Claims Automation

ClaimFlow

Faster Claims, Fairer Payouts

ClaimFlow digitizes claims intake for claims managers and independent adjusters at small-to-mid insurers and MGAs, extracting facts from photos and messages with an NLP engine, tagging loss details and routing tasks into configurable automated workflows to cut intake time 60%, eliminate manual entry, accelerate approvals, and reduce follow-ups.

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

ClaimFlow

Product Details

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

Vision & Mission

Vision
Empower small-to-mid insurers and adjusters to resolve claims faster, more fairly, and transparently through intelligent automated intake and triage.
Long Term Goal
Within 3 years, become the preferred claims intake platform for 500+ regional insurers and MGAs, cutting claims intake time by 50% and follow-ups by 40%
Impact
ClaimFlow reduces initial claims intake time by 60% and cuts manual data entry by 70% for claims managers and independent adjusters at small-to-mid insurers, trimming overall claim cycle time by 25%, lowering follow-ups and accelerating payout approvals.

Problem & Solution

Problem Statement
Claims managers and independent adjusters at small-to-mid insurers and MGAs waste hours on slow, error-prone manual intake—typing notes, organizing photos, and inconsistent triage—because legacy CRMs lack automated NLP parsing, configurable workflows, and affordable customization.
Solution Overview
ClaimFlow automates claims intake and routing by using an NLP damage-parsing engine to extract and tag loss details from photos and messages, then applying configurable triage rules to route tasks for faster, consistent, error-free approvals.

Details & Audience

Description
ClaimFlow digitizes insurance claims intake and routes tasks into automated workflows for faster, consistent processing. It serves claims managers and independent adjusters at small-to-mid insurers and MGAs. ClaimFlow eliminates slow, error-prone manual entry, accelerating approvals, cutting cycle time, and reducing follow-ups. Its NLP damage-parsing engine extracts facts from photos and messages automatically, tagging loss details for instant triage.
Target Audience
Claims managers and independent adjusters (30-55), small-to-mid insurers, battling slow manual intake, preferring mobile workflows.
Inspiration
On a Saturday ride-along with an independent adjuster, I watched them switch between frantic texts, smeared handwritten notes, and a flood of photos, then painstakingly type the same details into a clunky portal. One missed checkbox meant costly follow-ups. Seeing that human patience turned into data entry sparked the idea: software that reads photos and messages, extracts facts, and routes tasks automatically so adjusters can focus on decisions—not clerical work.

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.

Angle Assist

Live AR guides frame VIN plates, serial stickers, and damage zones with alignment borders and a quality meter for glare, blur, and shadows. Ensures first-shot captures that maximize OCR accuracy, reducing retakes and speeding the 2‑second extraction. Ideal for field adjusters and FNOL agents who need fast, reliable shots.

Requirements

Smart Alignment Overlay
"As a field adjuster, I want live alignment guides that adapt to VIN plates and damage zones so that I can frame shots correctly on the first try and avoid retakes."
Description

Live, on-screen AR borders and corner anchors that dynamically conform to VIN plates, serial stickers, and damage zones using edge detection and device pose data. Supports portrait/landscape, variable plate sizes, and custom templates defined in ClaimFlow admin. Provides real-time tilt/level guidance via gyroscope, high-contrast guides for outdoor glare, and haptic cues when alignment enters acceptable bounds. Designed to minimize framing errors and speed first-shot capture while integrating seamlessly with the Angle Assist camera view.

Acceptance Criteria
Dynamic AR Border Conformance to Plate Edges
Given the camera preview shows a VIN plate or serial sticker with detectable edges and sufficient lighting When edge detection confidence is >= 0.85 Then the AR borders and corner anchors align to detected edges within max(4 px, 1.5% of the shorter edge) mean error over 10 consecutive frames And overlay updates have a per-frame latency <= 33 ms (measured end-to-end from detection to render) And if tracking confidence drops < 0.6, a "tracking lost" indicator appears within 100 ms and snap cues are hidden And after brief occlusion or motion blur, tracking re-acquires and re-aligns within 200 ms at confidence >= 0.85
Gyro-Based Tilt and Level Guidance
Given the device gyroscope is available and calibrated When device roll or pitch deviates more than ±1° from level while an alignment target is active Then a visible tilt indicator appears and updates at least 30 fps with angular resolution ≤ 0.5° And when tilt is within ±2° and edge detection confidence is >= 0.85 for ≥ 500 ms Then the state changes to Aligned and a light haptic tick is triggered within 50 ms
Orientation and Reflow (Portrait/Landscape)
Given the user rotates the device between portrait and landscape during active alignment When the OS orientation change event is received Then the overlay, anchors, and quality meter reflow to the new orientation within 250 ms without visible flicker or layout jump > 8 px And the alignment ROI preserves its relative position and aspect to the detected plate within ±5% And the capture button and core controls remain unobstructed and tappable (>= 48x48 dp)
Variable Sizes and Admin Templates Application
Given ClaimFlow admin defines templates for VIN plates, serial stickers, and damage zones with aspect and padding metadata When a capture session starts with a selected or auto-detected target type Then the corresponding template is applied and the overlay conforms to the target with aspect variance ≤ ±5% and padding variance ≤ ±2% And if no matching template exists, a generic rectangular template is applied and the system logs a template_miss event And on capture, metadata includes template_id, template_version, applied_padding, and aspect_ratio
High-Contrast Guides Under Outdoor Glare
Given ambient lighting produces glare or high luminance backgrounds (quality meter glare flag = true) When the overlay is rendered over the target area Then guide colors and strokes auto-adjust to maintain a contrast ratio ≥ 4.5:1 against the median 10x10 px sampling window beneath each guide segment And stroke width scales between 2–4 dp based on estimated camera distance to maintain visibility And contrast adjustments occur within 100 ms of glare detection
Haptic Cues on Acceptable Alignment
Given device haptics are enabled at the OS level When alignment enters the acceptable window (tilt within ±2°, confidence >= 0.85) for ≥ 500 ms Then a single light haptic tick is emitted and debounced so that subsequent ticks occur no more than once every 1,000 ms And no haptic feedback is produced if OS haptics are disabled And the haptic call is non-blocking with execution time ≤ 5 ms on the UI thread
Performance and Integration with Angle Assist View
Given Angle Assist camera view is active with Smart Alignment Overlay enabled When operating on a supported mid-tier device Then camera preview maintains ≥ 30 fps at p50 and ≥ 25 fps at p90 with CPU utilization ≤ 60% and additional memory footprint ≤ 50 MB And overlay layers do not occlude the capture button or quality meter; z-order places guides below CTA and above preview And no network calls are required for alignment; feature operates fully offline And on capture, alignment metrics (tilt_deg, confidence, template_id, timestamp) are attached to the image payload
Real-time Quality Meter
"As an FNOL agent, I want a live quality score with clear guidance so that I can fix issues before I capture and reduce the need for retakes."
Description

Continuous on-device assessment of blur, glare, shadows, motion, and occlusions that renders a visible score and pass/fail indicator at 25–30 fps. Thresholds are configurable per template to optimize OCR accuracy. Provides corrective prompts (e.g., tilt device, move closer, reduce glare) and gates the shutter until minimum quality is reached. Uses lightweight ML/computer vision for low latency and includes a developer API to log quality metrics for tuning and A/B tests.

Acceptance Criteria
Real-time Frame Rate and Latency Compliance
Given the Angle Assist camera preview is active on a supported device and the Quality Meter is enabled When frames are evaluated continuously for 10 seconds under typical indoor lighting Then the quality score and pass/fail indicator update at an average of >= 25 fps (minimum instantaneous rate 20 fps), per-frame processing time is <= 30 ms at p95, and end-to-end preview-to-render latency is <= 120 ms at p95 And the Quality Meter executes fully on-device with no network calls on the frame-evaluation path
Multi-Dimension Quality Assessment Accuracy
Given a labeled validation set covering blur, glare, shadows, motion, and occlusions across VIN plate, serial sticker, and damage zone templates When the Quality Meter evaluates the dataset using the active template thresholds Then per-dimension classification achieves F1 >= 0.90 and AUC >= 0.95, and overall pass/fail decision accuracy >= 95% And score calibration error (ECE) <= 0.05 against the validation set
Per-Template Threshold Configuration and Application
Given template-specific threshold configuration is available locally or via remote config with versioning When an adjuster selects a template (e.g., VIN Plate) or a template is auto-detected Then the Quality Meter loads and applies the corresponding thresholds within 200 ms and uses them for scoring, gating, and prompts And if configuration is missing or invalid, the system falls back to default thresholds and logs a recoverable error with config_version="default" And changes to thresholds via remote config are applied without app restart within 60 seconds
Shutter Gating Behavior
Given a minimum quality threshold for the active template When the user attempts to capture while quality < threshold Then the shutter is disabled, capture is blocked, and the pass/fail indicator shows Fail And when quality >= threshold for at least 3 consecutive frames within the last 200 ms, the shutter becomes enabled, a haptic tick is emitted, and the indicator shows Pass And gating behavior is enforced in offline mode and during transient connectivity changes
Corrective Prompting Logic and Responsiveness
Given real-time per-dimension quality scores are computed When a dominant deficiency is detected (e.g., glare exceeds threshold by >10% while others are within threshold) Then a single highest-priority corrective prompt is displayed within 200 ms (e.g., Reduce glare, Hold steady, Move closer, Tilt device, Uncover target) And prompts auto-clear within 300 ms after the deficiency resolves, are fully localizable, and do not stack And no prompt is shown when pass state is maintained continuously for >= 1 second
Visible Score and Pass/Fail Indicator UX
Given the preview is visible and the Quality Meter is running When quality evaluations are produced each frame Then the UI displays a numeric score (0–100) updating each frame and a pass/fail indicator And the indicator meets accessibility: contrast ratio >= 4.5:1, screen-reader labels announce transitions ("Quality Pass"/"Quality Fail"), and a haptic feedback occurs on Fail->Pass And the meter UI does not occlude critical AR alignment borders (overlap area <= 5% of overlay bounds)
Developer Metrics API for A/B and Tuning
Given the developer metrics API is enabled When the Quality Meter evaluates frames during a capture session Then the API emits batched events at up to 2 Hz containing timestamp, device model, app version, template_id, config_version, overall score, per-dimension scores, pass/fail, prompt_shown, and shutter_enabled And events are queued offline and delivered within 10 minutes of connectivity, with at-most-once semantics and <1% drop rate over 1,000 test events And an optional A/B assignment key can be included and contains no PII; no image pixels are transmitted And metrics emission does not degrade frame rate below 25 fps average during the session
Auto-Capture Lock
"As a field adjuster, I want the camera to auto-capture when the shot is good so that I can work faster and ensure consistent, high-quality images."
Description

Automatic shutter trigger when framing and quality thresholds are met, with focus/exposure lock to prevent last-moment blur or exposure shifts. Provides haptic/audio confirmation, captures a short burst (e.g., 3 frames), and selects the best frame based on sharpness and glare metrics. Includes manual override, retry flow, and safeguards for low-light. Designed to hand off the selected frame to the 2‑second extraction pipeline immediately after capture.

Acceptance Criteria
Auto-trigger on alignment and quality readiness
Given the VIN/serial plate is framed within the AR alignment borders and the quality meter is in Ready (glare, blur, shadow thresholds met) for at least 250 ms while device motion is below the stability threshold When these conditions are sustained Then the shutter auto-triggers within 200 ms, AE/AF are locked at trigger time, and haptic plus audio confirmations are emitted immediately
Focus and exposure lock stability during auto-capture
Given auto-capture has been triggered When the burst begins Then AE/AF lock engages before the first frame and remains locked across the burst with exposure variance ≤ 5% and no refocus events until the burst completes
Burst capture and best-frame selection
Given auto-capture is triggered When a burst of 3 frames is captured within 500 ms Then a quality score is computed per frame using sharpness and glare metrics, the highest-scoring frame is selected; on ties select the frame with lowest motion blur, else the earliest; the selected frame’s quality score ≥ the auto-trigger threshold; the selected frame ID and quality metrics are stored with the capture
Haptic/audio confirmation with mute and visual fallback
Given a capture (auto or manual) occurs When feedback is emitted Then a 50–80 ms haptic is played on supported devices; an audio click is played unless the device is muted or in Do Not Disturb; a visual flash indicator appears in all cases; all feedback starts within 100 ms of the trigger
Manual override and cancel of auto-capture
Given the user is in Angle Assist preview When the user taps the shutter before auto-trigger Then a capture is taken immediately (≤ 100 ms) with AE/AF lock and auto-capture is suppressed for the next 3 seconds; and when the user taps Cancel while auto-trigger is pending, no capture occurs and auto-trigger is reset
Low-light safeguards and torch assist
Given estimated scene luminance is below the low-light threshold or device motion exceeds the blur-safe threshold When preview is active Then auto-capture is disabled and a Low light/motion warning with a torch toggle is shown; when the torch is enabled, thresholds are re-evaluated every 100 ms and auto-capture proceeds only when quality and stability thresholds are met; exposure time of captured frames must be ≤ the device’s blur-safe maximum
Immediate handoff to 2-second extraction pipeline
Given the best frame has been selected When the capture concludes Then the image is handed off to the extraction pipeline within 100 ms, UI shows Extracting, exactly one selected frame is sent, and 95th-percentile time from handoff to first OCR result is ≤ 2.0 s under normal connectivity; user cannot trigger another capture until handoff starts or they cancel
OCR-Ready Metadata Packaging
"As a claims manager, I want captured images sent with context and quality data so that OCR is more accurate and intake workflows can auto-route without manual review."
Description

On capture, packages the selected frame with structured metadata (bounding boxes, quality scores, angle, exposure, timestamps, device model) and securely posts to ClaimFlow’s OCR/extraction service. Associates capture with the active claim, entity type (VIN, serial, damage), and workflow step. Implements retry/backoff, response parsing, and error surfaces in the UI. Stores metadata for analytics while following data retention policies, enabling auto-tagging and task routing upon OCR completion.

Acceptance Criteria
Package Frame With OCR-Ready Metadata
Given an Angle Assist capture is finalized for an active claim When the app packages the selected frame Then the payload conforms to metadata schema v1 containing: imageId (UUID v4), claimId, entityType ∈ {VIN, SERIAL, DAMAGE}, workflowStep, boundingBoxes[] with {x, y, width, height} within image bounds, qualityScores {glare, blur, shadow, overall} in [0.0,1.0], angle {pitch, roll, yaw} in degrees within [-180,180], exposure {iso > 0, shutter > 0, ev within [-10,10]}, timestamp in UTC ISO-8601 with millisecond precision, device {model, osVersion}, appVersion And all required fields are non-null and pass client-side validation And only the selected frame is included with no additional frames or thumbnails
Secure Submission to OCR Service
Given the device has network connectivity When the app posts the payload to the OCR/extraction endpoint Then the request is sent over HTTPS with TLS 1.2+ and certificate pinning enabled And the request includes a valid OAuth2 Bearer token in the Authorization header And no secret or token is written to logs or persisted in plaintext And if TLS pin validation fails or the certificate is untrusted, the post is aborted and no retries are attempted And if the server returns 401/403, the token is refreshed once and the request retried a single time; thereafter the user is prompted to re-authenticate
Associate Capture With Claim and Workflow Context
Given a capture is initiated within a specific claim and Angle Assist mode (VIN/Serial/Damage) When the capture is posted Then the payload includes claimId, entityType, and workflowStep matching the app’s current context at shutter time And the server response echoes claimId and entityType, which are stored with the capture record And if the user navigates away or switches claims before delivery, the capture remains associated to the original claim and workflowStep
Reliable Delivery With Retry and Idempotency
Given a transient failure occurs (network timeout, DNS error, HTTP 5xx) When posting the capture Then the client retries with exponential backoff (initial 1s, factor 2.0, max interval 30s) with jitter, up to 5 attempts And an Idempotency-Key header equal to the imageId is included on every retry And duplicate acknowledgements from the server return the same result without creating duplicate records And while offline, the payload is queued locally (encrypted at rest) and automatically sent when connectivity resumes And if all retries exhaust, the capture is marked “Delivery failed” with a retry action available
Parse OCR Response and Trigger Auto-Routing
Given the OCR service responds with 200 and a JSON body containing extracted fields and tags When the app receives the response Then the response is validated against response schema v1 and parsed without error And the claim is auto-tagged with returned tags and the appropriate workflow task(s) are created within 2 seconds of receipt And the capture record is updated with ocrStatus=Complete and a reference to the OCR job/result ID And if the OCR service responds 202 with a jobId, the client subscribes/polls and processes the completion callback within the configured timeout; on completion, the same tagging and task routing occur And if the OCR service responds with a failure code and reason, the capture is marked ocrStatus=Failed and retake/retry guidance is presented
Surface Errors and Recovery Paths in UI
Given an error occurs during packaging, submission, or OCR processing When the error is classified (validation, auth, network, server, quality) Then the UI displays a user-friendly message with specific cause and a recommended action (Retake, Retry, Sign in) And technical details are captured in logs with correlationId and imageId but without PII or tokens And the user can retry failed submissions without losing the captured frame And error banners and controls are accessible (screen-reader labels present; contrast >= AA) And all error states are tracked in telemetry with error codes and latency
Analytics Storage and Retention Compliance
Given analytics storage is enabled with retentionTTL days configured When a capture is completed and posted Then metadata (quality scores, angle, exposure, device, timestamps, entityType, workflowStep, success/failure flags, durations) is stored in the analytics store without image bytes or OCR text content And records include a pseudonymized claim identifier suitable for aggregation And access to analytics data requires authenticated role-based access And a daily purge job removes analytics records older than retentionTTL days, verified by backdated test records And when a claim is deleted or a data subject erasure request is processed, associated analytics records are purged within 24 hours
Cross-Device Performance & Offline Mode
"As a field adjuster working in low-connectivity areas, I want Angle Assist to function smoothly offline so that I can capture high-quality images without waiting for network connectivity."
Description

Optimized performance across iOS 14+/Android 9+ with adaptive quality checks to maintain 25–30 fps on mid-tier devices. Runs models on-device to minimize latency and supports offline operation for up to 15 minutes, queueing captures and quality metrics and syncing automatically when online. Includes thermal/battery safeguards, graceful degradation of AR effects under load, and a QA matrix covering common devices and camera modules.

Acceptance Criteria
Maintain 25–30 FPS on mid-tier devices
Given Angle Assist camera preview is active on a QA Tier-2 device running iOS 14+ or Android 9+ And default capture settings and normal indoor lighting (300–500 lux) When the user continuously frames a target for 3 minutes Then median render FPS >= 27 and p90 FPS >= 25 And frame drop rate <= 5% And touch-to-frame interaction latency <= 80 ms p95 And no crash or OS kill occurs
Adaptive AR effect degradation under load
Given Angle Assist is running And the system detects either FPS < 25 for >= 2 continuous seconds or device thermal state >= Elevated/Throttling or battery <= 15% When the condition is detected Then the system degrades visual effects in this order: (1) disable shadow mask, (2) disable reflections, (3) reduce overlay refresh to 15 Hz, (4) reduce mesh complexity by 50% And the quality meter remains visible and updates at >= 10 Hz And upon 5 seconds of sustained recovery (FPS >= 27, normal thermal, battery > 15%), effects are restored stepwise in reverse order And a single, unobtrusive banner informs the user of performance mode (no more than once per session) And all state transitions are logged with timestamps
On-device model latency and autonomy
Given network connectivity is absent or < 100 kbps When initializing Angle Assist on-device models Then model cold-start completes in <= 1000 ms on QA Tier-2 devices And during active preview, per-frame inference time p95 <= 120 ms And no network calls are made during capture and quality assessment And after capture, OCR extraction for VIN/serial images completes in <= 2.0 seconds p95 on QA Tier-2 devices
Offline capture queuing for up to 15 minutes
Given the device goes offline during an Angle Assist session When the user captures images and associated quality metrics for up to 15 minutes Then all captures and metrics are queued locally with original order preserved And the queue supports at least 150 images and 500 metric records without loss And additional local storage consumption stays <= 50 MB And the session shows a visible "Queued" state within 1 second of each capture And upon reconnection, sync starts within 10 seconds and completes without user action
Sync resilience, persistence, and conflict handling
Given there is a non-empty offline queue And the app is force-quit or the OS restarts while still offline When the app relaunches Then queued items persist and resume syncing automatically when online And each item is submitted idempotently via content-hash deduplication to prevent server duplicates And transient sync failures are retried with exponential backoff up to 5 attempts And permanent failures surface as user-visible errors with a retry option, while successful items are not re-sent And if offline duration exceeds 15 minutes, capture is paused, queued data is retained, and the user is prompted to resume when online
Thermal and battery safeguards enforcement
Given Angle Assist is running When the device thermal state reaches Serious/Critical or battery <= 5% Then the camera preview pauses automatically, current capture is safely saved, and a blocking alert explains the condition and next steps And background processing is suspended during the pause to reduce load And capture cannot resume until thermal state returns to Nominal/Moderate and battery > 5% And no crash or app-not-responding occurs during transitions And all events are logged for diagnostics
QA matrix device and camera coverage
Given a release candidate build is ready When executing the QA device/camera matrix Then coverage includes >= 90% of the top 20 device models by active user share across target regions And tests span camera modules with and without OIS/EIS and multiple lenses where available And each run records FPS (median, p90), inference p95, thermal events, and battery delta per 3-minute session And release gates require 0 Critical, <= 2 High severity open defects, and overall pass rate >= 95% And the signed QA matrix report is attached to the release notes prior to launch
On-Device Privacy, Consent & Audit
"As a compliance officer, I want on-device processing with audit trails so that sensitive data is protected and our organization meets regulatory and client requirements."
Description

Performs quality analysis on-device, with ephemeral image buffers and no persistent storage unless policy requires it. Encrypts data in transit, supports configurable consent prompts, and masks sensitive regions (e.g., faces) when capturing broader damage zones. Generates an audit trail including model version, thresholds used, and operator identity, enabling compliance with SOC 2/ISO 27001 and insurer retention policies.

Acceptance Criteria
On-Device Quality Analysis and Ephemeral Buffers
Given a capture session starts, When quality analysis runs, Then all computations occur on-device with no network calls to analysis services. Given capture completes, When the session ends or the app backgrounds, Then all raw frames and intermediate buffers are purged from memory within 300 ms and never written to persistent storage unless enforce_retention=true. Given enforce_retention=false, Then no image files exist in the app sandbox after session end (verified via file system scan APIs). Given an unexpected crash, When the app next launches, Then a startup routine zeroizes any residual temp files and records audit event "buffer_purge_after_crash". Given enforce_retention=true, When storing is required by policy, Then only masked images are stored and are encrypted using hardware-backed keys; storage path and retention_expiry are recorded in the audit trail.
Consent Prompt and Capture Gate
Given consent_required=true and no prior consent for the current claim, When the user opens Angle Assist, Then display the localized consent prompt with configured text/version and require explicit accept to proceed. Given the user declines consent, Then block capture, do not process camera frames, and record audit event "consent_declined" with operator_id, timestamp, and jurisdiction_code. Given the user accepts consent, Then record audit event "consent_accepted" with operator_id, timestamp, jurisdiction_code, and prompt_version, and do not re-prompt within consent_ttl unless policy_version changes. Given jurisdiction_code maps to prompt_variant, When opening the prompt, Then the correct variant is shown based on configured mapping. Given consent_required=false, When opening Angle Assist, Then skip the prompt and record audit event "consent_not_required".
Sensitive Region Masking Enforcement
Given damage-zone capture mode, When faces or license plates are detected with confidence >= 0.60, Then apply real-time masks in the viewfinder and ensure only masked images are stored or transmitted. Given masking_enabled_policy=true, Then any UI control to disable masking is hidden/disabled; bypass attempts block capture and add audit event "masking_policy_enforced". Given manual masking is used by the operator, Then manual masks are composited with automatic masks and persist to any stored/transmitted images. Given previews/thumbnails are generated, Then only masked variants are cached and all are purged at session end. Quality target: On validation set, masks achieve IOU coverage >= 0.90 on detected regions; false-negative rate <= 5% at configured threshold.
Encrypted Data in Transit and Domain Allowlisting
Given any network transmission of images (masked) or extracted text, Then transport uses TLS v1.2+ with strong ciphers and certificate pinning to the configured allowlist of backend domains; requests to non-allowlisted domains are blocked. Given pin verification fails or TLS version < 1.2, Then the upload is aborted, the user sees "secure transport required", and audit event "tx_blocked_insecure_channel" is recorded. Given a MITM proxy intercept attempt, Then the client rejects the connection due to pin mismatch and no data leaves the device. Given background uploads, Then the same TLS and pinning policies apply; OS photo library is never used as a transport path.
Comprehensive Audit Trail and Tamper Evidence
Given any capture session lifecycle event, Then create an append-only audit record with fields: audit_id, claim_id, session_id, timestamp(UTC), operator_id, consent_status, model_version, quality_thresholds, policy_rule_ids, masking_status, network_security_status, storage_decision, and outcome. Given audit records are stored locally pending sync, Then each record is HMAC-SHA256 signed with a rotating key; tampered records are rejected on server verification and flagged. Given an authorized export request, Then audit records for a claim export as JSON within <= 2 seconds per 1,000 records and include signatures for integrity verification. Given offline mode, Then audit records queue locally and sync in original order when online with zero loss across app restarts.
Retention and Erasure Compliance
Given retention_policy = none, Then no images (masked or unmasked) persist beyond the session; only audit records and extracted structured data are retained per policy. Given retention_policy duration D > 0, Then only masked images persist and are auto-deleted at or before retention_expiry (drift <= 5 minutes); deletion events are logged in the audit trail. Given a data subject erasure request for claim_id, Then all retained images and derivatives are deleted within 24 hours and audit event "erasure_completed" is recorded; audit records persist but must exclude pixel data and direct PII beyond operator_id (per policy). Given an authorized operator triggers manual deletion, Then deletion occurs immediately, respects retention constraints, and is reflected in the audit trail.

Burst Boost

When confidence is low, PhotoFact Flash auto-captures a rapid burst of frames and fuses them to enhance clarity, then re-runs extraction in-line. Suggests alternate targets (door jamb VIN, dashboard plate, license plate lookup) to recover essentials fast. Delivers higher data confidence with less manual effort and fewer corrections.

Requirements

Confidence-Triggered Burst Capture
"As a field adjuster, I want the app to auto-capture a burst when the first photo is unclear so that I can quickly obtain a readable image without manually retaking multiple photos."
Description

Automatically initiates a rapid burst capture when PhotoFact extraction confidence for key fields (e.g., VIN, license plate, policy ID) falls below a configurable threshold. Captures 8–12 frames with exposure/focus bracketing and motion stabilization using native iOS/Android camera APIs and WebRTC where applicable. Provides real-time on-screen framing guidance, minimal-latency capture, and offline-safe operation with temporary, encrypted local storage that is purged post-fusion. Integrates with ClaimFlow’s workflow engine to pause the intake step, record trigger conditions, and resume once results are available. Includes guardrails for device thermals/battery, concurrency limits, and secure handling of transient media to meet privacy and data residency requirements.

Acceptance Criteria
Low-Confidence Auto-Trigger and Burst Parameters
Given ClaimFlow PhotoFact extraction is configured with key fields VIN, License Plate, and Policy ID and a per-field confidence threshold of 0.90 And burst parameters are configured to N=10 frames with exposure bracketing {-1EV, 0EV, +1EV}, focus bracketing {near, far}, and stabilization enabled when supported When a capture attempt yields a VIN confidence of 0.62 (< 0.90 threshold) Then Burst Boost auto-initiates within 300 ms of the low-confidence signal And captures exactly 10 frames within 1.5 seconds And the captured frames include at least 3 distinct exposure values and at least 2 distinct focus distances And camera stabilization is reported as enabled in capture metadata on devices that support it; otherwise a software stabilization path is used and reported And fusion completes and re-extraction is executed immediately on the captured burst And all trigger details (field=VIN, prior_confidence=0.62, threshold=0.90, device_model, os_version, timestamp) are recorded in the audit log for the claim
Real-Time Framing Guidance and Minimal Latency
Given burst capture is about to start due to a low-confidence signal When the burst trigger fires Then a framing guidance overlay with bounding guides and a steadiness indicator appears within 150 ms And the preview frame rate remains at least 24 fps during capture on devices capable of 30 fps in normal mode And the shutter begins capturing within 250 ms and completes the burst within 1.5 seconds And the user can cancel the burst within the first 500 ms via a visible cancel control, which immediately stops capture and logs the cancellation event
Offline-Safe, Encrypted Storage, and Purge
Given the device is offline (airplane mode) and local secure storage is available When a burst is captured and fusion/re-extraction runs Then all burst frames and intermediate fused artifacts are stored only in an encrypted app sandbox using platform keystore-backed encryption And no media bytes are transmitted off-device; only final extracted field values and confidences are queued for later sync And all transient media are purged within 30 seconds of fusion completion or immediately after successful extraction, whichever is sooner And after app restart, no burst media persists on disk and a secure deletion record is present in the audit log
Workflow Pause-Resume and Audit Trail
Given a claim intake step is active in ClaimFlow and burst capture is triggered for a key field When the burst begins Then the intake step status transitions to Paused with reason=burst_capture and a visible indicator is shown in the UI And trigger conditions (field, prior_confidence, threshold, device_state, thermal_state, battery_level) are recorded to the workflow event stream And upon fusion and re-extraction completion, the step automatically resumes within 500 ms and the updated field values and confidences replace prior values And events burst_started and burst_completed with a shared correlation_id are emitted to the workflow engine and stored for traceability
Thermal and Battery Guardrails
Given device thermal state is Severe or battery level is below 10% When a low-confidence condition occurs Then the system does not initiate a full burst; it reduces frames to at most 4 or defers with a user prompt indicating the constraint And no more than 1 burst attempt is allowed within any 60-second window under constrained conditions And a guardrail event with reason (thermal or battery) is logged and surfaced to telemetry And when conditions return to Normal and battery is at least 15%, full burst behavior is restored automatically
Concurrency Limits and Claim Context Integrity
Given a burst capture is already in progress for a claim session When a second low-confidence signal arrives for the same or another field before the first burst completes Then the system does not start a second burst concurrently; it queues a single follow-up burst request or collapses duplicates, ensuring max concurrent bursts per device equals 1 And camera access remains owned by the active burst without error or crash And all results are associated with the correct claim and step via a correlation_id; no cross-claim contamination occurs
Cross-Platform Capture Path and Fallbacks
Given the app runs on iOS 16+, Android 10+, and modern browsers supporting WebRTC When burst capture is triggered Then native AVFoundation (iOS) or CameraX/Camera2 (Android) APIs are used respectively, and WebRTC getUserMedia is used on web And if camera permission is denied or unsupported, the system does not trigger a burst; it logs the denial, shows non-blocking guidance to grant permission, and allows manual capture fallback And feature parity is maintained across platforms for frame count, bracketing behavior, stabilization flag reporting, and purge behavior
Multi-frame Fusion Engine
"As a claims manager, I want the system to automatically enhance low-quality captures so that extraction succeeds even in low light or when there is motion blur."
Description

Fuses captured burst frames into a single, higher-clarity image using deblurring, denoising, super-resolution, and HDR techniques to improve legibility of small text and embossed characters on VIN plates, stickers, and documents. Runs on-device with hardware acceleration (Neural Engine/NNAPI) when supported, with seamless fallback to secure cloud processing if device capabilities are insufficient. Exposes a deterministic API that returns the fused image, a quality score, and processing metadata within target latency budgets. Integrates with ClaimFlow’s media pipeline, supports model/version management, and enforces resource caps to protect app responsiveness.

Acceptance Criteria
On-Device Acceleration with Seamless Cloud Fallback
Given a device with supported Neural Engine/NNAPI and a 5–10 frame burst, When fusion is requested, Then processing_path="on_device", accelerator ∈ {"NeuralEngine","NNAPI"}, and runtime_ms is populated. Given a device without required acceleration or when resource caps are active, When fusion is requested, Then processing_path="cloud", all uploads occur over TLS 1.2+ with certificate pinning, request_id is present, and local raw frames are purged within 60 seconds after successful upload. Given identical inputs processed on-device and in-cloud with the same model_version, When comparing quality_score, Then absolute difference ≤ 0.02 and metadata.model_version matches. Given no network connectivity during required cloud fallback, When fusion is requested, Then a non-blocking error is returned (HTTP 503 with problem+json), UI remains responsive, and a retry token with exponential backoff policy is provided in metadata.
Fused Image Quality and Legibility for VIN/Text
Given the standard VIN/document low-light/blur dataset, When fusion completes, Then P90 quality_score ≥ 0.85 for VIN targets and ≥ 0.80 for document targets, and no fused image has SSIM < 0.90 versus the best input frame. Given baseline OCR on the best single frame, When OCR is run on the fused image, Then mean character accuracy improves by ≥ 15 percentage points and VIN checksum validity rate improves by ≥ 20 percentage points. Given a fused result with quality_score below threshold (VIN: 0.85, Document: 0.80), When metadata is generated, Then low_confidence=true and alternate_targets ∈ {"door_jamb_vin","dashboard_plate","license_plate_lookup"} are suggested.
Deterministic API Contract and Metadata
Given the same ordered burst, identical parameters, and the same model_version, When fusion runs twice, Then the SHA-256 of the fused image, the quality_score (±1e-6), and processing_metadata are identical. Given a successful fusion, When the API returns, Then the payload includes fused_image_uri, quality_score ∈ [0,1], and processing_metadata {model_version, processing_path, accelerator?, runtime_ms, frames_used, denoise_used, deblur_used, super_resolution_used, hdr_used, resource_caps_applied, request_id} with required fields non-null. Given invalid input (fewer than 2 frames, corrupt frame, or mixed resolutions), When the API is called, Then it returns HTTP 400 with problem+json including code, title, and detail, and it does not write any partial media artifacts.
Latency Budgets (On-Device and Cloud)
Given a 6×12MP burst on A14/SD778G-class devices, When processed on-device, Then P50 runtime_ms ≤ 700 ms and P95 ≤ 1200 ms recorded in metadata. Given a 6×12MP burst with required cloud fallback on a 20 Mbps uplink and 40 ms RTT, When processed, Then end-to-end P50 latency ≤ 1500 ms and P95 ≤ 2500 ms including upload, processing, and download. Given any processing path, When runtime_ms exceeds the P95 budget, Then metadata flags sla_breach=true and a telemetry event is emitted with request_id and model_version.
Resource Caps and App Responsiveness
Given on-device fusion running in the foreground, When monitored, Then app main-thread 99th percentile frame time ≤ 32 ms and dropped frames ≤ 1% during the operation. Given on-device fusion, When measured, Then peak additional memory usage ≤ 300 MB and average CPU/NN utilization ≤ 70% during the processing window. Given the thermal state approaches throttling, When detected, Then the engine throttles workload or switches to processing_path="cloud", sets resource_caps_applied=true, and completes without app termination.
Media Pipeline Integration and Re-Extraction
Given a successful fusion, When storing output, Then the fused image is written to the ClaimFlow media pipeline with a content-addressable ID, parent_burst_id linkage, and checksum verification passes. Given a new fused image, When the extraction service is invoked, Then extraction re-runs automatically and produces confidence ≥ the prior attempt OR the case is flagged for review with reason="no_improvement". Given media and metadata persistence, When retrieved later, Then the fused image and processing_metadata are accessible via canonical URIs and included in audit logs.
Model/Version Management and Rollback
Given multiple available model versions, When policy selects a version, Then metadata.model_version reflects the selected version and can be pinned via configuration for a tenant/device cohort. Given a model rollout, When failure rate or sla_breach exceeds 2× baseline over 100 consecutive runs, Then automatic rollback to the last stable model_version occurs within 10 minutes and is recorded in audit logs. Given a model update, When processed with older clients, Then the API contract remains backward compatible and A/B assignment is visible via metadata.ab_bucket.
Inline Re-extraction Pipeline
"As an adjuster, I want the system to retry extraction right after enhancement so that I don’t have to restart the intake step or correct fields manually."
Description

Re-runs OCR/VIN/plate extraction automatically on the fused image within the same intake step, merging results with prior attempts and updating field-level confidence scores. Publishes deltas to the UI and to ClaimFlow’s workflow/router so downstream tasks can auto-unblock without user intervention. Ensures idempotency, caching, and cost controls for repeated extraction attempts, and records provenance linking each extracted fact to its source image and processing path for auditability.

Acceptance Criteria
Inline fused-image re-extraction triggers on low confidence
Given an intake step where at least one required field has confidence < 0.85 on the initial extraction And a burst capture has completed and a fused image is available When the inline re-extraction pipeline is invoked Then OCR, VIN, and license plate extractors are re-run on the fused image within the same intake step without user action And the re-extraction completes with P95 latency <= 5s and a hard timeout of 10s And the pipeline records attempt_id and idempotency_key for this re-extraction
Confidence-aware field merge and non-regression
Given prior extraction results with field-level values and confidences And re-extraction results are available When merging results Then for each field, select the value with the highest confidence; if equal, prefer the most recent value And do not replace an existing value with a lower-confidence value And mark a field as updated only if the value changes or the confidence changes by >= 0.01 And unchanged fields retain their previous timestamps and provenance And merged results are stored atomically for the attempt
Delta publication to UI and workflow router
Given merged results with one or more updated fields When deltas are computed Then the system publishes one delta event per changed field containing claim_id, field_name, old_value, old_confidence, new_value, new_confidence, attempt_id, provenance_id, occurred_at And the UI receives the delta and updates the displayed field within 300ms of event receipt, visually indicating the change And the workflow/router consumes the delta within 500ms of publish and evaluates unblock rules And if a downstream task's rule is satisfied (confidence >= 0.85 and value present), the task transitions from Blocked to Ready automatically And no delta is published for fields that did not change by the defined threshold
Idempotent eventing and writes on retries
Given a re-extraction retry occurs with the same idempotency_key within a 10-minute window When the pipeline processes the retry Then no duplicate records are written for merged results, provenance, or audit logs And no duplicate delta events are emitted And the API response includes the same attempt_id as the original processing
Caching and cost controls for repeated extraction
Given a fused image with hash H and extractor config version M previously processed within the last 24 hours When a re-extraction is requested with the same H and M Then cached extractor outputs are reused and zero new external API calls are made And per-claim per-intake-step re-extractions are limited to a maximum of 3 attempts; subsequent requests are rejected with HTTP 429 and no processing occurs And at most 2 extractor types run concurrently per attempt; additional extractors queue And exponential backoff is applied between attempts with intervals of 2s and 4s
Provenance and audit trail completeness
Given any field value produced by the re-extraction When querying the provenance endpoint for that field Then the response includes value, confidence, source_image_ids, fused_image_id, extractor_type, model_version, extractor_config, attempt_id, idempotency_key, processing_node, started_at, finished_at And each provenance record includes a verifiable checksum of the fused image hash H And provenance records are immutable and retained for at least 7 years
Failure handling and safe fallback within intake step
Given re-extraction fails due to error or exceeds the 10s timeout When the failure occurs Then the UI continues to display prior extraction results without regressions And an error banner indicates the failure and any scheduled retry And the workflow/router receives no unblock events for fields affected by the failed attempt And automatic retries are attempted with exponential backoff starting at 2s, up to 2 retries total And errors are logged with a correlation_id and surfaced to monitoring within 60s
Alternate Target Guidance
"As an adjuster, I want clear prompts for alternative places to capture required identifiers so that I can proceed quickly when the initial target fails."
Description

Provides contextual guidance when primary targets remain unreadable, suggesting next-best capture targets such as door jamb VIN stickers, dashboard plates, license plates, or insurance cards. Ranks suggestions by vehicle type, region, and claim context, and presents overlay guides, microcopy, and haptic/audio cues to reduce capture friction. Supports quick target switching, offline heuristics, and streamlined manual entry with field validation as a last resort. Logs which suggestions succeed to improve future recommendations.

Acceptance Criteria
Trigger And Ranked Suggestions After Low-Confidence Primary Target
Given the user is capturing a primary target and extraction confidence remains below 0.75 for 2 consecutive evaluations after burst fusion When the system detects the low-confidence condition or unreadable primary target Then it displays an alternate-target panel within 500 ms containing at least 3 suggestions ranked by vehicle type, region, and claim context And the top-ranked suggestion matches the configured rules for the detected vehicle type and region in at least 95% of test cases And the panel can be dismissed or a suggestion accepted with a single tap
Overlay Guides And Multimodal Cues For Suggested Alternate Target
Given the user accepts a suggested alternate target When the overlay is presented Then the camera view shows target-specific framing guides aligned to expected geometry within ±5% and a one-sentence microcopy instruction localized to the app language And a short haptic pulse is emitted on target lock-on and a 250 ms confirmation tone plays only if system sound is enabled And all cues respect device mute, accessibility, and reduced motion settings And overlay elements meet minimum 12 pt text size and 4.5:1 contrast ratio for legibility
Quick Switch Between Capture Targets
Given alternate-target suggestions are visible When the user taps a suggestion chip or performs a single left/right swipe Then the capture mode switches to the selected target within 300 ms while maintaining a live preview And no more than one frame is dropped during the transition And the user can return to the previous target in two taps or fewer And the selected target is visually indicated and announced via screen reader
Offline Suggestion Heuristics Without Network
Given the device has no network connectivity When a low-confidence primary target is detected Then on-device heuristics generate a ranked list of alternate targets within 400 ms with no network calls attempted And an "Offline" badge is displayed in the suggestion panel And in offline mode the top-2 containment rate of suggestions is within 10% of the online baseline on the curated test set
Manual Entry Fallback With Field Validation
Given the user selects Manual Entry as a fallback When entering a VIN Then the form enforces 17-character ISO 3779 format, uppercases input, rejects I/O/Q, and validates the check digit before enabling submission And when entering a license plate, the form validates against the selected region's format and character set and auto-formats spacing where applicable And when entering a policy number, the form validates against the carrier profile's regex rules And invalid input produces an inline error message within 100 ms and blocks submission until corrected And all required fields must pass validation before the user can continue
Outcome Logging For Suggestions And Target Success
Given an alternate-target panel is shown or acted upon When capture completes (success) or is canceled (failure) Then the app logs timestamp, pseudonymous device/session IDs, claim context, suggestions shown and order, selection made, time-to-capture, and extraction confidences, plus success/failure outcome And analytics payloads exclude raw images and full-text PII; only hashed or redacted identifiers are included per policy And if offline, events are queued durably and transmitted within 5 minutes of connectivity with at least 99% delivery success And each log record includes the app version and model/ruleset identifiers for attribution
Suggestion Efficacy And Continuous Improvement
Given logging is enabled and data collection thresholds are met When evaluating a rolling 4-week window of auto claims Then the top-1 suggestion success rate is at least 60% and top-3 success rate is at least 85% on the validation cohort And if either metric falls below target for two consecutive weeks, a ruleset or model update is scheduled and deployed to adjust rankings within 24 hours of approval And post-deployment monitoring confirms metrics recover to target within 7 days
Plate-to-VIN Lookup Integration
"As a claims manager, I want the system to look up a VIN from a captured license plate when needed so that I can complete intake without returning to the vehicle."
Description

Performs VIN resolution from a high-confidence license plate capture via configurable third-party services. Implements secure API clients with authentication, rate limiting, retries, and circuit breakers, and enforces permitted-use, consent, and regional compliance rules. Masks sensitive data in transit and at rest, caches results per policy, and exposes feature flags per carrier/workflow. Provides graceful degradation and user messaging when services are unavailable.

Acceptance Criteria
VIN Resolution from High-Confidence Plate via Configurable Provider
Given a license plate extraction with confidence >= 0.90 and a recognized region/state When Plate-to-VIN lookup is triggered Then the system selects the highest-priority enabled provider for the carrier and region and invokes it with plate and region metadata Given the provider returns a VIN When the response is parsed Then the VIN is validated as 17 characters and checksum-valid, and the result is attached to the claim intake with a data-confidence score and provider provenance Given multiple providers are configured When the first provider returns a non-2xx status, empty result, or invalid VIN Then the system fails over to the next provider in the configured order within the same transaction Given lookup completes successfully Then the end-to-end call (including any failover) completes within 3 seconds p95 under nominal conditions and records correlation IDs and latency metrics
Resilient Secure API Client (Auth, Timeouts, Retries, Circuit Breaker, Rate Limits)
Given a provider requires API key or OAuth2 authentication When a lookup call is initiated Then credentials are loaded from a secret manager, injected only in memory, and never logged or persisted in plaintext Given outbound calls to providers Then HTTPS TLS 1.2+ is enforced with certificate validation; plaintext HTTP is rejected Given network variability and transient errors When calling a provider Then timeouts are set to connect <= 2s and read <= 5s; retry up to 2 times with exponential backoff (base 200ms, cap 1s) on 429, 5xx, and timeouts; respect Retry-After when present Given repeated provider failures When failure thresholds are met Then the circuit breaker opens after 5 consecutive failures or >=50% failure rate over 60s with a minimum of 20 requests; half-open after 30s; close on first successful probe Given provider-specific throughput constraints When issuing calls Then a client-side rate limiter enforces the configured QPS per provider; locally throttled 429s are not retried and are observed via metrics Given heterogeneous provider error models When errors occur Then errors are mapped to standardized error codes and messages for the workflow
Permitted Use, Consent, and Regional Compliance Enforcement
Given a carrier workflow with configured permitted-use basis and regional rules When a Plate-to-VIN lookup is requested Then the system verifies a valid permitted-use basis exists for VIN resolution for the subject region before sending any data Given the region requires explicit user consent When consent has not been captured Then the lookup is blocked, no data is sent to any provider, the UI displays a consent-required message, and an audit event is recorded Given the region is disallowed by policy When a lookup is attempted Then the request is blocked with a policy-violated error and the decision is audit logged with policy version and actor Given the lookup proceeds Then requests include required compliance parameters (e.g., purpose-of-use) if supported by the provider, and routing respects regional provider restrictions Given any allow/deny decision Then an immutable audit record is stored with timestamp, actor, carrier, workflow, policy version, and region
Sensitive Data Protection In Transit and At Rest
Given provider communications Then all requests use HTTPS TLS 1.2+ with strong ciphers; certificate pinning or trust store validation is enforced; plaintext endpoints are rejected Given logging and observability When recording requests and responses Then sensitive fields (license plate, customer identifiers, auth tokens) are redacted; only the last 3 characters of the plate are visible; VIN is logged only after checksum validation Given data persistence When storing provider responses and cache entries Then data at rest is encrypted using platform-standard encryption (e.g., AES-256) with managed keys; auth secrets reside only in a secret manager Given temporary payloads When processing lookups Then transient request/response bodies are retained no longer than 24 hours (configurable per carrier policy) and are automatically purged; purges are auditable Given access control When users or services request decrypted fields Then access is limited to authorized roles; unauthorized access attempts are denied and audited
Result Caching and Policy-Based Invalidation
Given a plate+region query matches a cache entry within the configured TTL (default 24h; per-carrier override) When a lookup is requested Then the cached VIN is returned without calling any provider, and the response indicates cache_hit=true with age seconds Given a cache miss or expired entry When a lookup succeeds Then the response is cached with key {plate, region, provider} and the policy-defined TTL; cache_write=true is recorded Given a carrier enables cache bypass for investigative workflows When bypass is true for a request Then no cache read/write occurs and the decision is audit logged Given a claim is withdrawn or a policy requires immediate invalidation When an invalidation event is received Then matching cache entries are purged within 60 seconds and the purge is reflected in metrics Given normal operations Then cache metrics (hit rate, evictions, stale fetches) are emitted and visible on dashboards
Feature Flags per Carrier and Workflow
Given Plate-to-VIN is feature-flagged per carrier and workflow When the flag is Off Then no provider calls are made and the UI indicates the feature is disabled for that workflow Given the flag is toggled On without redeploy When a new lookup is triggered Then the change takes effect within 60 seconds via remote configuration refresh Given a staged rollout is configured (e.g., 25%) When lookups occur Then only the configured percentage of eligible requests invoke provider calls and the remainder behave as flag Off; assignment is stable per claim ID within the rollout window Given governance needs When a flag is changed Then actor, timestamp, environment, rationale, and previous value are captured in an immutable audit log
Graceful Degradation and User Messaging on Provider Unavailability
Given the active provider returns 5xx, times out, or the circuit breaker is open When a lookup is requested Then the system returns a non-fatal failure to the workflow, does not block other intake steps, and displays a user-facing message indicating temporary unavailability and next steps Given multiple providers are configured When the primary is unavailable Then a fallback provider is attempted once according to the configured order before surfacing the degraded outcome Given all providers are unavailable When the lookup cannot be completed Then the UI offers configured alternatives (e.g., manual VIN entry) and logs a standardized error with correlation IDs for tracing Given repeated provider outages When incidents occur Then alerts are throttled to at most one per provider per 15 minutes to prevent alert storms; incident metrics are published
Configurable Thresholds and Policies
"As a product admin, I want to adjust thresholds and fallback order per workflow so that accuracy, cost, and user effort are balanced for each carrier."
Description

Offers admin settings to tune confidence thresholds, burst length, fusion parameters, retry limits, alternate target ordering, and on-device vs. cloud processing policies. Supports per-carrier and per-workflow overrides, environment-specific configurations, versioned rollouts, and instant rollback. Includes validation and guardrails to prevent overly aggressive capture loops and ensures all changes are recorded with user, timestamp, and reason in the configuration audit log.

Acceptance Criteria
Carrier-Level Confidence Threshold Override
Given a global confidence_threshold=0.85 and a carrier "ABC" override confidence_threshold=0.92 are configured and active When an image from carrier "ABC" is processed Then 0.92 is used to decide PhotoFact Flash triggering and entity acceptance And the applied threshold value (0.92) is recorded in the processing metadata And when an image from a non-ABC carrier is processed in the same environment, 0.85 is used
Workflow-Level Override Precedence
Given global confidence_threshold=0.85, carrier "ABC" confidence_threshold=0.90, and workflow "Auto-Physical-Damage" confidence_threshold=0.95 are configured When an ABC claim enters the "Auto-Physical-Damage" workflow Then the workflow-level threshold 0.95 is applied And when the claim moves to a workflow without an override, the carrier-level 0.90 is applied And processing metadata and the audit trail reflect precedence order: workflow > carrier > global
Burst Length and Fusion Guardrails
Given guardrails max_burst_length=12, max_fusion_strength=2.0, and processing_time_cap_ms=3000 are configured When an admin attempts to set burst_length=50 and fusion_strength=5.0 Then the change is blocked with validation errors indicating allowed ranges (burst_length <= 12, fusion_strength <= 2.0) And when the admin sets burst_length=8 and fusion_strength=1.5 Then PhotoFact Flash captures exactly 8 frames and applies fusion_strength=1.5 And the measured processing time per burst is <= 3000 ms and is logged in run metadata
Retry Limits and Alternate Target Ordering
Given alternate_target_order=[VIN_DoorJamb, VIN_Dashboard, LicensePlate_Lookup], retry_limit_per_target=2, and total_retry_limit=5 are configured When extraction fails for the current target Then the next target is attempted in the configured order And no target is attempted more than 2 times And the total number of retries across all targets does not exceed 5 And if retries are exhausted without success, the user is prompted for manual entry via a single clear CTA And the final data source and retry counts are recorded in metadata
On-Device vs Cloud Processing Policy
Given environment policies are configured: Field=OnDevice, Office=Cloud, with fallback=Allowed When the app runs in Field environment with network available Then burst fusion and extraction execute on-device and images are not uploaded And when the app runs in Office environment Then images are uploaded securely and processed in cloud And if the configured mode is unavailable (e.g., no secure enclave for on-device), the system falls back to the other mode, logs the fallback with reason, and continues processing
Versioned Rollout and Instant Rollback
Given configuration version v2 is created from v1 and a rollout target of 10% of Production users is defined When the rollout is started Then only the targeted 10% receive v2 within 60 seconds and all others remain on v1 And when a rollback to v1 is triggered Then 100% of users are reverted to v1 within 60 seconds and v2 is marked inactive And all rollout and rollback events include version_id, scope, actor, timestamp, and reason in the audit log
Configuration Audit Log Completeness and Integrity
Given an admin creates, updates, and rolls back settings across global, carrier "ABC", and workflow "Auto-Physical-Damage" scopes When the audit log is queried for a date/time range Then each entry contains user_id, timestamp (UTC), action (CREATE/UPDATE/ROLLBACK), scope, key, old_value, new_value, version_id, and reason And entries are returned in chronological order and are append-only (no edits or deletes allowed via UI or API) And any attempt to modify or delete an existing audit entry is rejected with HTTP 403 and no changes occur
Outcome Analytics and Audit Trail
"As an operations lead, I want visibility into Burst Boost outcomes and a complete audit trail so that I can demonstrate compliance and optimize performance over time."
Description

Captures granular metrics for Burst Boost including pre/post confidence, burst count, fusion success rate, re-extraction deltas, time-to-first-success, and manual corrections avoided. Writes an immutable, chronologically linked audit trail to each claim with source images, processing versions, and decisions. Streams summarized events to analytics dashboards and alerting to monitor impact, detect regressions, and drive continuous model and UX improvements while adhering to privacy and retention policies.

Acceptance Criteria
Burst Boost Metric Capture Completeness
Given a Burst Boost session is invoked for a claim When extraction runs pre-burst and post-fusion re-extraction completes Then the system records for the session: pre-extraction confidence per field, burst frame count, fusion success flag and score, post-extraction confidence per field, delta per field (post minus pre), time-to-first-success in milliseconds, and manual corrections avoided count And each metric is timestamped, associated to the claim ID, session ID, and processing version (model, fusion, ruleset) And metrics persistence succeeds with 99.5% completeness across sessions in a rolling 7-day window (no required field missing) And a failure to capture any required metric is logged with error code and retried up to 3 times with exponential backoff And an authenticated GET /claims/{claimId}/burst-boost/{sessionId}/metrics returns the full metric set in a documented schema with units and types And P95 metric write latency is <200 ms per session
Immutable, Chronological Audit Trail
Given any Burst Boost processing event (attempt, fusion, re-extraction, decision) occurs on a claim When the event is finalized Then an append-only audit entry is written with monotonic timestamp, actor (system/user), action, input references (content hashes of images), processing versions, outputs, and decision rationale, all linked to a claim and session correlation ID And each audit entry includes a cryptographic hash and previous-entry hash to form a verifiable chain; any mutation attempt is rejected and logged And source images are stored content-addressably; only their hashes and storage references appear in the audit entry And an authenticated GET /claims/{claimId}/audit supports chronological retrieval and export; exported chains validate hash continuity end-to-end And audit write availability is ≥99.99% monthly; P95 write latency <250 ms; retries with idempotency keys prevent duplicates
Real-time Analytics Event Streaming
Given a Burst Boost session completes (success or failure) When the summarization pipeline runs Then a summarized analytics event (schema v1) is published to the analytics bus with claimId, sessionId, timestamps, burstCount, fusionSuccess, confidenceLift, timeToFirstSuccessMs, manualCorrectionsAvoided, and errorCodes (if any) And events are redacted of PII and include only references (hashes/IDs) per policy And events are delivered to downstream consumers with at-least-once semantics and idempotent de-duplication via eventId for 24 hours And P95 producer-to-dashboard latency is ≤10 seconds; consumer lag P95 ≤10 seconds; end-to-end delivery success ≥99.9% daily And backfill can replay the last 30 days without schema drift; dashboards reflect replayed data without double counting
Regression Detection and Alerting
Given baselines for key KPIs (confidenceLift, fusionSuccessRate, timeToFirstSuccessMs) computed over the prior 7 days When the current rolling 60-minute window deviates beyond thresholds (confidenceLift drop >15% absolute, fusionSuccessRate drop >10% absolute, timeToFirstSuccessMs increase >30%) for any product segment (line of business, device type, geography) Then an alert is generated within 5 minutes containing metric, segment, baseline, current value, links to dashboards, and runbook And alerts are routed to Slack, Email, and PagerDuty with deduplication across channels and auto-resolve after 2 consecutive hours back within thresholds And synthetic regression tests can be triggered to verify alert creation and routing without impacting production metrics
Privacy, Access Control, and Retention Compliance
Given storage of metrics, events, and audit entries for Burst Boost When data is persisted and accessed Then all sensitive data is encrypted in transit (TLS 1.2+) and at rest (AES-256); access is restricted by role with least privilege and is fully audited And PII is minimized; images are referenced by content hash; dashboards show only aggregated, de-identified metrics And retention is enforced: raw images retained 180 days, derived metrics retained 3 years, audit trail retained 7 years, with configurable legal-hold exceptions And purge jobs run daily, produce tamper-evident reports, and remove personal data while retaining non-identifying aggregates; right-to-be-forgotten requests complete within 30 days And quarterly compliance tests pass with zero critical findings; access reviews show no violations
Manual Corrections Avoided Measurement
Given a defined baseline of manual correction rates without Burst Boost When Burst Boost runs for a claim Then the system computes manualCorrectionsAvoided by comparing accepted post-extraction values without user edits to the established baseline for the same field and context And the metric is stored per claim and aggregated per product segment; methodology and baseline version are recorded And an A/B toggle exists to validate attribution; analysis runs with minimum 500 sessions per variant and reports statistical significance (p<0.05) And dashboards display avoided corrections per 100 claims and cumulative hours saved, updated daily

Severity Map

Computer vision outlines damaged areas, classifies damage type (dent, crack, hail, rust), and estimates severity and affected parts. Auto-tags loss details and pre-fills structured fields, surfacing checklist tasks if critical views are missing. Accelerates triage, standardizes scoring, and reduces rework.

Requirements

Damage Segmentation & Type Classification
"As a claims adjuster, I want the system to automatically outline and label damage areas in photos so that I can quickly understand the type and extent without manual inspection."
Description

Implement a computer vision service that detects and outlines damaged regions in uploaded images, segments them with polygons, and classifies each region by damage type (e.g., dent, crack, hail, rust, scratch, corrosion). Support multiple regions per image, per-region confidence scores, and normalization of labels to ClaimFlow’s damage ontology. Accept common image formats (JPEG/PNG), handle varied lighting and angles, and process images individually or in batch. Produce overlay assets for the UI and a structured JSON payload for downstream systems via the platform’s event bus. Include model versioning, health checks, and graceful degradation paths when confidence is below configurable thresholds.

Acceptance Criteria
Single Image: Multi-Region Damage Detection & Segmentation
- Given a curated validation set of 500 images with annotated damaged regions, when the service processes each image at a max side of 1024 px, then: - Per-image damaged-region recall >= 0.85 and precision >= 0.85 at IoU >= 0.50. - Each returned region is a closed, non-self-intersecting polygon in pixel coordinates within [0,width) x [0,height). - Supports up to 100 regions per image without truncation. - Each region includes a unique regionId and a segmentationConfidence in [0.0,1.0].
Per-Region Damage Type Classification & Ontology Normalization
- Given the same validation set with ground-truth damage types {dent, crack, hail, rust, scratch, corrosion}, when the service classifies each detected region, then: - Macro-averaged F1 >= 0.75 across the six classes. - Each region includes a typePrediction {originalLabel, normalizedCode, confidence in [0,1]}. - normalizedCode maps to ClaimFlow ontology codes and never returns a value outside the allowed set; unknowns map to CF.DAMAGE.OTHER with reason "low-confidence" or "no-match". - If top-1 confidence < 0.65, include top-3 labels with confidences in descending order.
Confidence Thresholds & Graceful Degradation Behavior
- Given configurable thresholds T_seg (default 0.50) and T_cls (default 0.60), when results fall below thresholds, then: - Regions with segmentationConfidence < T_seg are excluded from auto-tagging and marked lowConfidence=true in the payload; overlays render them as dashed outlines. - Regions with type confidence < T_cls keep normalizedCode=CF.DAMAGE.OTHER and emit flag requiresHumanReview=true. - An event bus message with reason "LOW_CONFIDENCE" is published for the image; no blocking errors are thrown. - Thresholds are adjustable via settings and take effect without service restart within 60 seconds.
Single and Batch Processing Performance & Resilience
- Given a request with 1 image, then the response is returned within P95 <= 2.0s on the reference GPU profile and includes exactly one result object correlated by imageId. - Given a batch request with up to 100 images (mix of JPEG and PNG), then: - The service processes all images; one failure does not prevent others from returning results. - The order of results matches the input order; each result includes the original clientRequestId. - Overall throughput is >= 30 images/minute P95 on the reference GPU profile. - Per-image errors include machine-readable codes and messages; successful images are not omitted.
Overlay Asset Generation and Event Bus JSON Output
- Given any processed image, then: - A PNG overlay asset with alpha channel is generated with polygons color-coded by normalizedCode; filename pattern {imageId}_{modelVersion}_overlay.png. - The overlay and a thumbnail (max-side 512 px) are persisted to the configured object store with read URL and 24h TTL metadata. - A JSON payload is produced matching schema claimflow.cv.damage.v1 and includes imageId, modelVersion, processedAt (ISO-8601 UTC), regions[{regionId, polygon, bbox, areaPx, normalizedCode, originalLabel, confidences}], aggregate metrics, and lowConfidence flags. - The JSON is published to the platform event bus topic claimflow.cv.damage.v1 within 1s of processing completion and is acknowledged in the happy path.
Image Formats, Orientation Handling, and Robustness to Conditions
- Given JPEG or PNG inputs between 640 and 6000 px on the longest side, with or without EXIF orientation, when processed, then: - EXIF orientation is respected; output polygons align with visually upright image. - Non-supported formats (e.g., HEIC, GIF) return HTTP 415 with error code UNSUPPORTED_MEDIA_TYPE. - Images with low light, glare, or oblique angles still meet detection/classification metrics within 10% absolute of baseline metrics measured on the standard validation set. - If critical views are missing per platform rules, the payload includes missingCriticalViewsHint=true to trigger a checklist task downstream.
Model Versioning, Health Checks, and Observability
- Given the service is running, then: - GET /health returns 200 with {status:"up"} and includes {modelVersion, modelChecksum, uptimeSeconds}. - GET /ready returns 200 only after the model is loaded and warm; returns 503 otherwise. - Every response (API, payload, overlay metadata) includes modelVersion; version changes only via controlled deployment. - If the model fails to load, requests return 503 with error code MODEL_UNAVAILABLE and an event with reason "MODEL_UNAVAILABLE" is emitted; no partial results are produced. - Prometheus metrics expose per-image latency, batch size, and confidence distributions; logs include correlationId for all requests.
Severity Scoring & Thresholding
"As a triage manager, I want consistent severity scores with confidence so that I can route claims automatically and reduce subjective variance."
Description

Calculate a standardized severity score (0–100) for each detected region and roll up to image- and claim-level aggregates. Incorporate region size, density, and contextual cues to derive severity, and provide confidence intervals. Expose configurable thresholds per line of business to categorize Low/Medium/High severity and emit structured fields for triage and routing. Flag low-confidence or ambiguous results for review, persist scores with model version metadata, and ensure consistent outputs across retriggers and reprocessing.

Acceptance Criteria
Region-Level Severity Score 0–100 with Confidence Interval
Given a photo with at least one detected damage region and a fixed model version V and configuration C When severity scoring runs Then each region returns severity_score as an integer within [0,100] And each region returns ci_lower and ci_upper within [0,100] with ci_lower <= severity_score <= ci_upper And each region returns confidence within [0.0,1.0] And for a controlled test where region B has strictly greater area and damage density than region A in the same image, severity_score(B) > severity_score(A) And runtime completes within the SLO (p95 <= 500ms per image for scoring, excluding detection)
Image- and Claim-Level Severity Aggregation
Given an image with N >= 2 scored regions and their pixel areas When image-level aggregates are computed Then the image exposes aggregates: regions_count, severity_max, severity_mean, severity_area_weighted_mean And severity_mean = average of region severity_score rounded to 2 decimal places And severity_area_weighted_mean = sum(severity_score_i * area_i) / sum(area_i) rounded to 2 decimal places And the claim-level aggregates apply the same metrics across all images in the claim And all aggregate values are within [0,100] and are reproducible for identical inputs, model version, and configuration
LOB-Configurable Threshold Categorization (Low/Medium/High)
Given a Line of Business (LOB) L with thresholds defined in configuration C as ordered, non-overlapping ranges covering [0,100] When categorization runs for regions, images, and claims under L Then each entity receives a severity_category in {Low, Medium, High} based on its severity score and C And changing thresholds in C (without changing inputs or model version) changes categories accordingly on the next run And categorization decisions are logged with thresholds_set_id and effective range used
Structured Field Emission for Triage and Routing
Given scoring and categorization have completed for a claim When structured outputs are emitted via API and event stream Then per-region fields include: region_id, severity_score, ci_lower, ci_upper, confidence, severity_category, lob, thresholds_set_id And per-image fields include: image_id, regions_count, severity_max, severity_mean, severity_area_weighted_mean, severity_category, lob, thresholds_set_id And per-claim fields include: claim_id, images_count, severity_max, severity_mean, severity_area_weighted_mean, severity_category, lob, thresholds_set_id And all numeric fields have defined types and units, and enums use the canonical values {Low, Medium, High} And downstream routing rules can filter on severity_category and thresholds_set_id without additional transformation
Low-Confidence or Ambiguous Results Flagging for Review
Given configuration C defines min_confidence and max_ci_span and boundary_margin points around thresholds When a region's confidence < min_confidence OR (ci_upper - ci_lower) > max_ci_span Then region.review_required = true with reason code {LOW_CONFIDENCE or WIDE_CI} And when a region's severity_score lies within boundary_margin of any threshold, region.review_required = true with reason code AMBIGUOUS_BOUNDARY And if any region in an image is review_required, image.review_required = true; if any image is review_required, claim.review_required = true And all review flags and reason codes are present in emitted structured fields
Deterministic Outputs on Retriggers and Reprocessing
Given identical inputs (images and metadata), the same model version V, and the same configuration C When scoring is re-run (manual retrigger or automated reprocessing) Then all region scores, confidence intervals, aggregates, categories, and review flags are byte-for-byte identical to the prior run And the run records share the same determinism hash derived from inputs+V+C And if V or C changes, outputs may change but are associated to the new V or C and do not overwrite prior run outputs
Persistence with Model Version Metadata and Auditability
Given a claim has been scored When results are persisted Then each stored record (region, image, claim) includes: model_version, model_hash, config_version, thresholds_set_id, lob, run_id, scored_at (ISO 8601), and checksum And records are immutable; updates create a new run_id with a link to the prior run_id And retrieving by claim_id returns the latest run by default and supports filtering by run_id, model_version, and config_version And deletion policies (if any) do not allow partial removal that would break the audit trail
Parts Mapping & Affected Components Identification
"As a claims manager, I want the system to identify which parts are affected so that coverage and repair estimates can be initiated accurately."
Description

Map detected damage regions to affected parts using a maintained parts taxonomy and view/orientation classification. Support vehicle and property contexts, leveraging make/model metadata when available and falling back to generic component sets otherwise. Return a structured list of affected components with repairability indicators and coverage-relevant attributes to inform downstream estimating and policy checks.

Acceptance Criteria
Vehicle VIN-Based Mapping to Parts Taxonomy
Given a vehicle claim with VIN decoded to a supported make/model/year and photos showing a left-front bumper dent and a left headlamp crack When Severity Map processes the photos and orientation classification runs Then the response contains exactly 2 affected components mapped to the make/model-specific taxonomy with: - component 1 taxonomy_id for "Front bumper cover (left)" and orientation=front-left - component 2 taxonomy_id for "Headlamp assembly (left)" and orientation=front-left And for each component the fields are present: [taxonomy_id, component_name, orientation, parent_component_id, damage_types, severity_score (0–1), confidence (0–1), location_polygon, source_image_ids] And confidence >= 0.85 for each component And parent_component_id correctly links to the assembly parent And parts-mapping latency <= 2000 ms
Generic Fallback Without Make/Model Metadata
Given a vehicle claim where VIN is unavailable and make/model cannot be resolved, and photos show a right rear door dent When Severity Map processes the photos Then the response contains 1 affected component mapped to the generic taxonomy with: - taxonomy_source="generic" and taxonomy_version present - component_name="Rear door (right)" and orientation=rear-right - required fields present: [taxonomy_id, component_name, orientation, damage_types, severity_score, confidence, location_polygon, source_image_ids] And confidence >= 0.75 And the operation completes without error
Property Roof Hail Mapping and Quantification
Given a property claim with roof photos showing hail impacts on multiple slopes When Severity Map processes the photos and classifies roof orientations Then the response includes affected components for each slope with: - component_name="Roof covering" and orientation in {north, south, east, west} per slope detected - metrics present: area_in_sq_m, impact_density_per_sq_m, severity_score, confidence, location_polygon - repairability provided for each slope component And confidence >= 0.80 for each slope component And quantifications (area, density) are within ±5% of ground-truth for the test set
Repairability Indicator Rules Application
Given detected damages with computed measurements (dent_diameter_mm, crack_length_mm, hail_density_per_panel) and severity_score When the repairability engine evaluates each affected component Then the following rules are applied deterministically: - If dent_diameter_mm <= 30 and severity_score <= 0.50 then repairability="repair" - If crack_length_mm > 20 on headlamp or windshield then repairability="replace" - If hail_density_per_panel > 8 then repairability="replace" - Else if confidence < 0.60 then repairability="unknown" And each component includes repairability_reason_code from the defined enum And all components include the repairability field with one of {repair, replace, unknown}
Coverage-Relevant Attribute Tagging
Given components mapped for a claim including: a windshield crack near an ADAS camera, a front bumper crack impacting a radar bracket, and a cosmetic door dent When coverage-relevant attribute tagging runs Then attributes are set as follows: - Windshield component includes coverage_relevant_attributes containing ["glass", "ADAS", "safety-system-involved"] - Front bumper component includes coverage_relevant_attributes containing ["safety-system-involved", "sensor-mount"] - Door cosmetic dent includes coverage_relevant_attributes containing ["cosmetic-only", "exterior-body"] And each component in the response has at least 1 coverage_relevant_attribute from the controlled list
Uncertainty and Missing Views Task Surfacing
Given a claim lacking required critical views (e.g., no front-left quarter image) for a suspected left headlamp damage When parts mapping confidence for that component would be < 0.70 or orientation cannot be resolved Then the component entry includes needs_additional_view=true and missing_views containing ["Front-left quarter"] And the response includes checklist_tasks with an item titled "Request front-left quarter view" and priority="high" And no component with confidence < 0.70 is marked final=true
Aggregation and De-duplication Across Images
Given the same component damage is detected in multiple photos (overlapping location polygons and identical taxonomy_id) When aggregation runs Then the response contains a single component entry for that taxonomy_id with: - source_image_ids listing all contributing image IDs - damage_types de-duplicated (no repeated labels) - severity_score equal to the fused score and >= the maximum individual detection score And there are 0 duplicate component entries where location_overlap > 0.50 for the same taxonomy_id
Auto-Tagging & Structured Prefill
"As an intake specialist, I want fields to be pre-filled from photo analysis so that I spend less time on data entry and avoid errors."
Description

Automatically tag loss details and pre-fill structured claim intake fields (damage types, affected parts, severity categories, occurrence indicators) using outputs from the vision and scoring modules. Apply validation rules, support human-in-the-loop confirmations, and track changes with versioned write-backs to the ClaimFlow data model. Ensure idempotent updates, partial-field handling when some views are missing, and emit events/webhooks to trigger downstream workflows and checklists.

Acceptance Criteria
Map Vision Outputs to Structured Prefill
Given a claim with photos processed by the vision and scoring modules When auto-tagging executes Then damage_types, affected_parts, severity_category, and occurrence_indicator are prefilled per mapping rules from model outputs And each prefilled field stores source (cv|scoring), confidence (0.00–1.00), and timestamp And fields with confidence >= 0.85 are flagged review_required=false; fields with confidence < 0.85 are flagged review_required=true And only values from the controlled vocabulary are written to the data model
Validation Rules and Cross-Module Consistency
Given prefilled values are produced When validation runs Then values not in the controlled vocabulary are rejected with reason_code='invalid_code' and are not written And if severity from cv and scoring differ by more than 1 level, set status='conflict', suppress final write, and require review And if damage_types exist but affected_parts is empty, create warning reason_code='missing_affected_parts' and do not set severity_category And all validation outcomes are logged with correlation_id and rule_ids triggered
Human-in-the-Loop Confirmation and Edits
Given prefilled fields with review_required=true or status='conflict' When an adjuster confirms or edits values Then the system updates the fields, sets confirmed=true for each confirmed field, and clears review_required And the previous_value, new_value, user_id, and timestamp are recorded for each field And the system emits a 'prefill.updated' event including changed_fields and version
Versioned Write-Backs and Audit Trail
Given any automated prefill or human edit When data is written to the ClaimFlow model Then a new immutable version is created with sequential version_number and correlation_id And version metadata records actor (system|user), source (cv|scoring|human), and change_set And historical versions are retrievable and diffable by API for the claim
Idempotent Reprocessing Behavior
Given the same inputs (image set, model versions, mapping version) are processed again When auto-tagging is re-run Then no new version is created and no duplicate tags are written And values remain unchanged and a 'prefill.noop' event is emitted with idempotency_key And the operation completes within 2 seconds at P95 for idempotent runs
Partial-Field Handling and Missing Views Checklist
Given required photo views are configured (e.g., front, rear, roof) When one or more required views are missing Then only fields supported by available evidence are prefilled; unavailable fields remain null with reason='insufficient_evidence' And severity_category defaults to 'Unknown' until evidence is captured And a checklist task 'Capture Missing Views' is created and assigned to the claim
Webhook Emission for Downstream Triggers
Given a successful write-back or update occurs When the transaction commits Then a webhook is emitted within 5 seconds with event_type ('prefill.completed'|'prefill.updated'|'prefill.noop'), claim_id, version_number, changed_fields, and correlation_id And non-2xx responses are retried up to 3 times with exponential backoff (1s, 3s, 9s) And failed deliveries are recorded with last_attempt_at and next_attempt_at
Missing Views Detection & Capture Checklist
"As an adjuster, I want the system to tell me which required photos are missing or unusable so that I can request them early and prevent rework."
Description

Detect the presence and quality of critical photographic views (e.g., front, rear, left, right, interior, VIN) using a view/quality classifier. When required views are missing, low quality, or occluded, surface a dynamic capture checklist within ClaimFlow and initiate automated requests for additional images via existing communication channels. Apply configurable business rules to block or defer auto-triage until mandatory views are provided, and update status in real time as new photos arrive.

Acceptance Criteria
Real-time Required View Detection on Photo Upload
Given an auto claim with 1–30 uploaded photos, When processing completes, Then each photo is classified into {front, rear, left, right, interior, VIN, unknown} with a confidence score 0–1 and ≥90% top-1 precision on the validation set. Given required views are configured as {front, rear, left, right, interior, VIN}, When classification completes, Then a checklist marks each required view Complete if any photo for that view has confidence ≥0.80; otherwise Missing. Given a detected view has occlusion score ≥0.60 or coverage <70% of the target area, When assessed, Then the view state is Low Quality (not Complete). Given processing starts, When photos are uploaded, Then the initial checklist is generated within 3 seconds at the 95th percentile. Given additional photos are uploaded in the same claim, When they arrive, Then re-evaluation runs automatically without user action.
Image Quality Classification and Reason Codes
Given any uploaded photo, When evaluated, Then the system computes blur, glare, exposure, framing, and occlusion metrics (0–1) and an overall quality score (0–1). Given overall quality <0.75 or any metric threshold is breached (blur>0.60 OR glare>0.60 OR exposure∉[0.30,0.70] OR framing<0.70), When mapped to a required view, Then the view is labeled Low Quality and reason codes for each failing metric are attached. Given multiple photos map to the same view, When at least one photo meets all thresholds, Then the view is marked Complete and low-quality photos do not block triage. Given a Low Quality label is shown, When rendered in the checklist, Then user-visible reason codes and a short guidance string (≤120 chars) are displayed for that view.
Dynamic Capture Checklist UI Updates
Given the capture checklist is visible in ClaimFlow, When any new photo for the claim is uploaded by claimant or internal user, Then the checklist updates in real time within 5 seconds and each item transitions among {Missing, Low Quality, Complete} as appropriate. Given all mandatory checklist items are Complete, When the last item transitions to Complete, Then a status banner indicates All required views received within 2 seconds. Given optional views are configured, When they are Missing, Then they are listed under Optional and do not prevent auto-triage. Given any checklist state change, When it occurs, Then an event is logged with {claimId, viewType, priorState, newState, timestamp, actor} for auditability.
Automated Additional Image Requests via Existing Channels
Given one or more mandatory views are Missing or Low Quality, When the checklist state is evaluated, Then an outbound request is sent via the claimant’s preferred available channel (in-app chat if active; else SMS; else email) within 60 seconds. Given the outbound request is sent, When delivered, Then it enumerates missing/low-quality views, includes per-view capture guidance links, and provides a secure upload link bound to the claim with a token expiring in 7 days. Given a request was sent in the last 12 hours and no new missing items were added, When re-evaluated, Then no duplicate request is sent (de-duplication enforced). Given photos are submitted via the secure link, When received, Then they are auto-associated with the claim and trigger immediate re-evaluation without manual routing. Given any outbound request, When logged, Then an audit record is created with {channel, templateId, recipient, sendTimestamp, deliveryStatus, claimId}.
Business Rule Gate for Auto-Triage Based on Mandatory Views
Given business rules require mandatory views to be Complete, When any mandatory view is Missing or Low Quality, Then auto-triage is set to Deferred with reason Missing mandatory views and triage tasks do not advance. Given LOB/claim-type-specific required views are configured by an admin, When configuration changes are published, Then new claims use the updated set while existing claims retain a snapshot unless a supervisor manually refreshes configuration. Given all mandatory views become Complete, When re-evaluated, Then auto-triage automatically resumes within 5 seconds and downstream tasks are enqueued. Given a supervisor with Override permission, When an override is applied with reason code and comment, Then triage may proceed despite missing items and the override is recorded in the audit log with userId and timestamp.
VIN View Handling and Alternative Paths
Given auto physical damage claims where VIN is mandatory, When evaluating the checklist, Then VIN can be satisfied by a VIN photo or by manual VIN entry plus supporting photo if rules allow. Given a VIN photo is provided, When OCR quality ≥0.85 and check-digit validation passes, Then VIN is marked Complete and the VIN field is auto-filled; otherwise the view is Low Quality with reason OCR_LOW_CONFIDENCE or CHECKDIGIT_FAIL. Given manual VIN entry is permitted, When the user enters a VIN, Then a supporting photo is required and VIN is marked Complete only if the photo OCR ≥0.80 or a supervisor approves an override with a reason code. Given multiple VIN photos exist, When any meets thresholds, Then accept the best and suppress further VIN requests for this claim.
Reviewer Annotations, Overrides & Audit Trail
"As a senior adjuster, I want to correct the system’s annotations and document why so that final assessments are accurate and auditable."
Description

Provide an interactive UI overlay that displays model-drawn polygons, labels, affected parts, and severity scores. Enable reviewers to edit polygons, relabel damage types, and override severity with reason codes. Persist all edits with user identity, timestamps, and before/after diffs, and automatically reapply prefill and workflow triggers after changes. Store model-versus-human outcomes for QA, reporting, and future model retraining.

Acceptance Criteria
Polygon Editing and Geometry Controls
- Given an image with model-drawn damage polygons visible, when a reviewer selects a polygon, then its vertices become draggable and the shape can be adjusted with a snap tolerance of <=5px and a minimum vertex spacing of >=3px. - Given an active polygon, when the reviewer drags a vertex or edge and releases, then the new geometry renders within 100ms and remains within image bounds. - Given the need to add a new polygon, when the reviewer completes drawing, then the polygon auto-closes, validates as non-self-intersecting, and displays pixel-area and perimeter. - Given a polygon, when the reviewer deletes it, then a confirmation modal appears, and on confirm the polygon is removed and an audit entry is recorded with the original geometry. - Given ongoing edits, when no further changes occur for 2s, then the system autosaves the current state and persists it across page reload; an undo/redo history of at least 20 steps is available per image.
Damage Type Relabel With Reason Codes
- Given a selected polygon, when a reviewer changes the damage type, then they must choose a reason code from a controlled list [Misclassification, Ambiguous, Edge Case, Customer Info, Other] and may enter optional notes up to 300 characters. - Given a successful relabel, then the polygon's label and color update immediately, the item is marked "Reviewer-updated", and the change is saved within 2s. - Given the relabel action, then the audit trail captures {oldType, newType, reasonCode, notes, userId, timestamp} and the UI shows a toast confirming save. - Given an invalid type, when the reviewer attempts to submit a label outside the allowed set [dent, crack, hail, rust, other], then validation prevents save and displays an inline error.
Severity Override and Validation
- Given a polygon with a model severity score, when a reviewer overrides the score, then the input accepts integers 0–100 inclusive, requires a reason code, and optionally allows notes up to 300 characters. - Given a valid override submission, then the displayed severity updates, dependent UI (badges, heatmap) refreshes within 200ms, and the change is autosaved within 2s. - Given an override, then the system records {oldScore, newScore, reasonCode, notes, userId, timestamp} in the audit trail. - Given an invalid value (e.g., blank, >100, <0, non-integer), when submitted, then the system blocks save and displays a descriptive validation message.
Immutable Audit Trail With Before/After Diffs
- Given any change to polygons, labels, affected parts, or severity, when the change is saved, then the system writes an immutable audit entry containing before/after values, userId, userRole, sessionId, ipAddress, and ISO-8601 UTC timestamp. - Given a geometry change, then the audit entry stores vertex arrays for old and new polygons and a computed delta (added/removed/moved vertices count). - Given the audit log view, when a reviewer opens it, then entries display in reverse-chronological order with filters by user, field, action type, date range, and can be exported as CSV and JSON. - Given access control policies, when a user without Audit permissions attempts to view logs, then access is denied with a 403 message and no data is returned.
Reapply Prefill and Workflow Triggers After Edits
- Given a saved reviewer change, when the change is persisted, then the system recalculates prefilled structured fields and re-runs workflow rules within 3s, updating tasks accordingly. - Given existing tasks affected by changes, when rules are re-evaluated, then obsolete tasks are canceled, new required tasks are created, and updated tasks retain their IDs; no duplicate tasks are created. - Given rule reapplication, then a banner "Prefill and workflows updated" appears within 5s and the audit trail records a "Rules re-evaluated" entry with outcome summary. - Given errors during rule reapplication, then the UI shows a non-blocking error message, retries up to 3 times with exponential backoff, and preserves the user's edits.
Store Model vs Human Outcomes for QA and Retraining
- Given an image processed by the model, when a reviewer finalizes edits, then the system stores paired records of model predictions and final human-adjusted outcomes with modelVersion, dataVersion, and claimId. - Given stored outcomes, when a QA export is requested for a date range, then the system produces a file within 60s containing per-polygon fields {part, type, severity_model, severity_final, iou_geom, accepted:boolean} and aggregate metrics. - Given a retraining flag enabled, when outcomes are stored, then they are partitioned into a retraining dataset bucket with PII-free media references and checksum validation. - Given no reviewer changes, then the system still records an explicit "accepted as-is" outcome for each polygon.
Concurrent Edit Handling and Versioning
- Given two reviewers editing the same image, when non-conflicting fields are changed concurrently (e.g., different polygons), then changes merge automatically and both users see updates within 2s. - Given conflicting edits to the same polygon, when a save occurs, then the second saver is presented a conflict dialog showing a diff (before, theirs, others) and must choose to overwrite, merge, or cancel. - Given any conflict resolution, then no data is lost, an audit entry records both attempted changes and the chosen resolution, and a new versionId is assigned. - Given optimistic concurrency control, when a stale version is submitted without resolution, then the system rejects with 409 and provides an option to reload latest.

Proof Seal

Each capture is sealed with a cryptographic timestamp, GPS/geofence validation, and a tamper-evident hash embedded in EXIF and the claim record. Provides chain-of-custody transparency for auditors and SIU while respecting privacy controls. Delivers instant audit readiness and stronger fraud defense.

Requirements

Cryptographic Timestamp Seal
"As an SIU analyst, I want machine-verifiable capture timestamps so that I can prove exactly when evidence was created during investigations and audits."
Description

At the moment of media capture or message ingestion, generate a cryptographic timestamp using a trusted time source (e.g., RFC 3161 TSA or cloud KMS-signed time). Bind the timestamp to the media’s content hash and a client nonce, embed the timestamp token in EXIF/XMP and store it within the claim record. Support clock-skew attestation, replay protection, and server-side fallback sealing when offline (with explicit disclosure). Expose verification results in the UI, rules engine, and export packages so SIU and auditors can machine-verify when evidence was created.

Acceptance Criteria
Real-time TSA Timestamp at Capture
Given a connected device or ingestion service with network access When media is captured or a message is ingested Then the system requests a timestamp from a configured trusted time source (RFC 3161 TSA or cloud KMS-signed time) And returns a signed timestamp token within 3 seconds at P95 (10 seconds absolute timeout) And persists the token ID, source, and signing cert chain reference with the claim asset And logs failures with error codes and retries up to 2 times before surfacing a user-visible error
Binding Timestamp to Content Hash and Client Nonce
Given an immutable byte stream of the captured media or message content When sealing is initiated Then the system computes a SHA-256 content hash over the exact bytes stored And generates a 128-bit cryptographically secure random client nonce unique per asset And includes both the content hash and nonce in the data that is signed by the TSA/KMS And verification fails if any bit of content or the nonce changes (hash or nonce mismatch) And the claim record stores {hash_algorithm:"SHA-256", content_hash, client_nonce, time_source, signing_key_id}
Embedding Timestamp Token in EXIF/XMP and Claim Record
Given a successfully sealed image/video format supporting EXIF/XMP When the seal is produced Then the system embeds the timestamp token and related fields into metadata (EXIF/XMP) without altering pixel/audio data And the same token bytes are stored in the claim record And for formats without EXIF/XMP support, a sidecar XMP/JSON is created and linked in the claim record And a subsequent metadata read yields an identical token to the claim record value And any write attempt that would change pixels/audio after sealing results in a new hash and requires a new seal
Offline Capture with Server-side Fallback Sealing and Disclosure
Given a device is offline at the moment of capture When media is captured Then the client computes and stores SHA-256(content) and a 128-bit nonce locally with monotonic capture time And upon reconnect within 24 hours the server obtains a trusted timestamp and seals using the stored hash and nonce And the UI clearly discloses "Sealed after upload (offline)" on the asset And the claim record sets offline_seal=true and records offline_duration And rules and exports expose offline_seal so auditors can detect fallback cases
Clock-Skew Attestation and Drift Thresholds
Given device-reported capture time and a trusted time at sealing When the seal is produced Then the system computes clock_skew_seconds = trusted_time - device_time And marks status "Clock OK" if |skew| <= 120 seconds, else "Clock Skew" with the absolute skew value And persists clock_skew_seconds and status in the claim record and export payloads And the UI displays a visible badge reflecting the status And the rules engine can evaluate clock_skew_seconds and status for decisions
Replay Protection for Nonce and Token Reuse
Given a 128-bit client nonce must be unique per asset When an incoming seal request reuses an existing nonce within 30 days or a timestamp token appears in multiple claims/assets Then the system flags a replay event, prevents silent reuse, and records an audit entry with severity=high And the rules engine exposes a replay_detected=true signal And the UI displays a warning on affected assets And exports include a replay_detected flag
Verification Exposure in UI, Rules Engine, and Exports
Given a sealed asset in a claim When verification is executed on-demand or during nightly jobs Then cryptographic verification validates the TSA/KMS signature, cert chain, token integrity, and hash binding And the UI shows a tri-state status (Verified/Warning/Failed) with reason codes And the rules engine exposes fields: timestamp_verified, verification_reason_code, time_source, signing_key_id, clock_skew_seconds, offline_seal, replay_detected, content_hash And export packages include the raw token, verification report JSON, and the intermediate certs required for offline verification
Location Integrity & Geofence Validation
"As a claims manager, I want captures validated against the loss-site geofence so that I can trust the evidence was collected at the correct location."
Description

Capture high-fidelity location evidence (GNSS fix, accuracy radius, altitude, speed, satellite count, and provider) at the instant of capture. Validate position against claim-configured geofences (e.g., loss address radius) with configurable tolerances and time windows. Detect and flag spoofing signals (mock location, emulator, rooted/jailbroken devices, VPN anomalies) and record the validation verdict with reasons. Embed signed location payload in EXIF/XMP and the claim record. Provide privacy-safe modes (e.g., share externally with coarse location or detached proof) while maintaining verifiability.

Acceptance Criteria
Capture GNSS Metadata at Moment of Capture
Given a device with location permissions granted and GNSS available When a photo is captured in ClaimFlow Then the location fix is taken at most 300 ms from the shutter event And the payload includes latitude, longitude, horizontalAccuracy(m), altitude(m), speed(m/s), satelliteCount, provider, and captureTimestamp(UTC) And satelliteCount >= 4 and provider = "GNSS" for a GNSS-classified fix And if horizontalAccuracy > configured.maxAccuracyMeters, the record is saved and flagged with reason "LowAccuracy" And if provider != "GNSS", the record is saved and flagged with reason "NonGNSSProvider" And if no fix is available, the payload records provider = "Unavailable" and reason "NoFix"
Geofence Validation Against Loss Location
Given a claim geofence configured with center(lat,lon), radius R meters, tolerance T meters, and a time window W When a capture occurs with location fix L at timestamp t Then the system computes distance d from L to center And if t ∈ W and d <= R, verdict = "InsideGeofence" And if t ∈ W and R < d <= R + T, verdict = "BorderlineOutOfGeofence" And if t ∈ W and d > R + T, verdict = "OutsideGeofence" And if t ∉ W, verdict = "OutsideTimeWindow" And the computed d, R, T, W, and t are persisted with the verdict
Spoofing and Device Integrity Detection
Given device integrity and network anomaly checks are enabled When a capture occurs Then the system detects and flags any of: MockLocation, EmulatorSimulator, RootJailbreak, VPNCountryMismatch, OSAttestationFail And if any indicator is present, verdictSpoofing = "Suspected" and reasonCodes include the detected indicators And if no indicators are present, verdictSpoofing = "Clear" And spoofing verdict and reasonCodes are persisted in the claim record
Signed Location Payload Embedded in EXIF/XMP and Claim Record
Given a successful capture and validation When the photo file is written Then EXIF/XMP contains a signed location payload with fields: lat, lon, accuracy, altitude, speed, satelliteCount, provider, captureTimestamp, geofenceVerdict, spoofingVerdict, reasonCodes, payloadHash And the payload is signed (JWS/COSE) using the platform private key and includes the signing certificate chain identifier And verification with the corresponding public key succeeds and matches the payload stored in the claim record And any byte-level modification of EXIF/XMP causes signature verification to fail And the claim record stores payloadHash equal to the hash embedded in EXIF/XMP
Coarse Location Share Mode (Privacy-Safe)
Given an external share is initiated with Privacy Mode = "Coarse Location" and gridSize S meters (default 1000) When the share package is generated Then the shared coordinates are rounded to the nearest grid cell of size S and precise lat/lon are not exposed And the package includes a verifiable proof that the original precise location was within the configured geofence at capture time And external verification of the proof succeeds without access to the precise coordinates And the claim record logs that Privacy Mode = "Coarse Location" was applied with S
Detached Proof of Location Without Disclosing Coordinates
Given an external share is initiated with Privacy Mode = "Detached Proof" When the share package is generated Then the exported media contains no EXIF/XMP location coordinates And a separate proof object contains a signature over the canonical payload hash and geofence parameters And external verification confirms the geofence verdict and timestamp while revealing no precise coordinates And any tampering with either media or proof invalidates verification And the claim record associates the proof object ID with the capture
Content Hash & EXIF Embed
"As an auditor, I want a tamper-evident hash embedded in each file so that I can independently confirm the media has not been altered."
Description

Compute a SHA-256 content hash of each media asset at capture (and a frame chain for bursts/videos), then sign and embed the proof into EXIF/XMP while storing a canonical copy in the claim record. Reject or flag uploads whose recomputed hash does not match the sealed value. Present a tamper status indicator in ClaimFlow (Verified/Warning/Failed) and expose verification via API for downstream systems. Ensure transformations (thumbnails, transcodes) are recorded as derived artifacts with their own hashes linked to the original.

Acceptance Criteria
On-Capture SHA-256 Hashing and Signed EXIF/XMP Embed
Given a media asset is captured via the ClaimFlow capture SDK on a supported device When the asset is finalized prior to any transformation or metadata write Then the system computes a SHA-256 content hash over the original media bytes And generates an RFC 3339 UTC capture timestamp And signs the tuple {assetId, contentHash, timestamp, deviceId, appVersion} with the platform signing key (Ed25519) And embeds contentHash, signature, timestamp, and algorithm identifiers into EXIF/XMP fields And persists the same tuple in the claim record as the asset’s canonical proof And the operation succeeds only if both embed and claim record writes succeed atomically
Upload Verification and Tamper Status Indicator
Given an asset file is uploaded or re-ingested into ClaimFlow When the system recomputes the content hash using the same algorithm used at capture Then if the recomputed hash equals the sealed contentHash and the signature verifies, the asset status is set to Verified and stored And if the sealed proof is absent but a canonical proof exists in the claim record and the recomputed hash matches it, the status is set to Warning And if the recomputed hash does not match the sealed value or the signature verification fails, the status is set to Failed and the upload is rejected with HTTP 422 and a user-visible error And the UI tamper indicator displays Verified (green), Warning (amber), or Failed (red) consistently with the stored status
Derived Artifact Hashing and Provenance Linkage
Given the system generates a thumbnail or transcode from an original asset When the derived artifact is produced Then the system computes a SHA-256 hash for the derived artifact And records a derived artifact entry with {derivedId, originalAssetId, type, parameters, hash, createdAt} And links the derived artifact to the original asset in the claim record And the derived artifact’s creation does not alter the original asset’s tamper status And verification of a derived artifact returns its own status while referencing originalAssetId
Verification API for Downstream Systems
Given a downstream system calls the verification API When GET /api/v1/proof/verify?assetId={id} is invoked by an authorized client Then the API responds 200 within 300 ms p95 with JSON {assetId, status, contentHash, signatureValid, timestamp, hashAlgorithm, signatureAlgorithm, derivedOf} And when POST /api/v1/proof/verify with a media file is invoked, the API responds with the same schema and does not persist the file And unauthorized requests receive 401, unknown assets 404, and invalid payloads 400 And the API signatureValid field equals true only if the embedded signature verifies against the platform public key
Burst/Video Frame-Chain Hashing and Validation
Given a burst photo sequence or video is captured When frame hashing is performed Then the system computes per-frame hashes and a forward chain where Hn = SHA-256(Hn-1 || frameHash_n) with H0 initialized to all zeros And embeds chainHead and chainTail identifiers in XMP along with chainAlgorithm And persists the frame count and chainTail in the claim record And verification detects any dropped, inserted, or reordered frames by chain breakage and sets status to Failed
Canonical Proof Storage and Idempotency
Given an asset with an existing canonical proof is re-uploaded or referenced When the recomputed content hash matches the stored canonical hash Then the system does not create a new canonical proof record (idempotent) And returns HTTP 200 with the existing assetId and status Verified And any attempt to mutate canonical proof fields is rejected with HTTP 409 and no change persisted
Tamper Events, Rejection Policy, and Audit Logging
Given an upload results in status Failed or Warning When the result is stored Then an immutable audit event is written with {assetId, status, reason, detectedAt, actorId, sourceIp} And notifications are emitted to the claim’s activity feed and SIU webhook if status is Failed And the UI must surface a View Proof panel showing contentHash, timestamp, signatureValid, and any mismatch reasons
Immutable Chain-of-Custody Ledger
"As a compliance officer, I want an immutable, exportable chain of custody so that our organization can demonstrate end-to-end evidence integrity to regulators and auditors."
Description

Maintain an append-only, signed ledger of all custody events for sealed evidence (capture, upload, validations, transformations, views, shares, exports, and deletions with legal holds). Store event digests in write-once storage (e.g., S3 Object Lock/WORM) with periodic checkpointing. Link ledger entries to the claim, task, and user identity. Provide filtered audit views, exportable reports, and API access for SIU and compliance, ensuring traceability across automated workflows and external sharing.

Acceptance Criteria
Append-Only Ledger with WORM Enforcement
Given a sealed evidence item and custody event types {capture, upload, validation.gps_geofence, validation.timestamp, transformation, view, share.created, share.accessed, export.created, legal_hold.applied, legal_hold.released, deletion.requested, deletion.executed} When any custody event occurs Then the system appends a new ledger entry with fields {sequence_index, event_type, timestamp, actor_id, actor_type, claim_id, task_id (nullable), evidence_id, payload_digest, prev_entry_hash, entry_hash} And the entry is persisted to write-once storage with Object Lock retention equal to the configured retention policy And attempts to modify or delete any existing ledger entry are rejected with 409/Forbidden and a write.rejected audit event is recorded And retrieval of the entry returns the same entry_hash as persisted
Cryptographic Signing, Trusted Timestamps, and Identity Linkage
Given a ledger entry is created Then the entry is signed with Ed25519 using a managed platform key and includes signer_key_id And the RFC3339 timestamp is sourced from a trusted time authority with drift <= 2 seconds from system time And signature verification using the published public key succeeds for 100% of entries And actor_identity is resolved via IdP, recording {actor_type in [user, service], subject_id, tenant_id, mfa=true/false, client_id (if service)} And within a single claim, timestamps are non-decreasing and sequence_index increments by 1 And for capture/upload events, payload_digest equals the tamper-evident hash embedded in the sealed file’s EXIF; for transformations, parent_digest and child_digest are recorded And when an event occurs within a workflow task, task_id and workflow identifiers are populated
Periodic Checkpointing and End-to-End Chain Verification
Given ongoing ledger activity When either 100 entries have been appended since the last checkpoint or 15 minutes have elapsed (whichever comes first) Then a checkpoint is created with a Merkle root over entries since the previous checkpoint, signed, and stored in WORM with Object Lock And GET /ledger/checkpoints returns the latest checkpoint with {root, span_start, span_end, created_at, signature} And POST /ledger/verify over the full chain up to the latest checkpoint returns status=valid And verification of a chain of 10,000 entries completes in <= 3 seconds on the reference dataset
Audit Views: Filtering, Pagination, and Export
Given a user with role Audit.View When they filter by {claim_id, evidence_id, event_type, actor_id, date_range} Then results are correctly filtered and returned with cursor-based pagination and total_count And the first page returns in <= 2 seconds for up to 50,000 matching events And exporting the filtered result yields CSV and JSON within 60 seconds including all entries, a verification manifest (Merkle root and entry hashes), and a detached signature And PII fields are masked per tenant privacy policy unless the user has scope Audit.PII And all view and export actions are themselves recorded as ledger events
Ledger API: Endpoints, Access Control, and Performance
Given authenticated API clients with scopes {Ledger.Read, Ledger.Verify} When they call GET /claims/{id}/ledger, GET /evidence/{id}/ledger, GET /ledger?filters=..., GET /ledger/checkpoints, and POST /ledger/verify with supported filters and pagination Then responses conform to the OpenAPI schema and include ETag headers and Next-Cursor tokens where applicable And requests beyond 1,000/minute per token receive 429 with Retry-After And p95 latency <= 300 ms and p99 latency <= 800 ms at 1M total entries under nominal load And unauthorized or insufficient-scope access attempts return 401/403 and are recorded as ledger events
External Sharing Traceability
Given an evidence item is shared externally via link or integration When the share is created, accessed, revoked, or expires Then ledger events {share.created, share.accessed, share.revoked, share.expired} are recorded with fields {share_id, recipient_hint, token_fingerprint, ip, user_agent, timestamp, actor_id (if authenticated)} And access denials due to expiry or revocation record share.access_denied with reason And exports of the evidence include the complete external share event trail
Legal Hold and Deletion Semantics
Given an evidence item under legal hold When a deletion is requested Then the deletion is blocked, API returns 423 Locked, and legal_hold.blocked_deletion is recorded And when legal hold is released and retention policy permits, deletion.executed is recorded, the content is purged, and the ledger retains payload_digest and a deletion receipt And no ledger entries are removed; attempts to remove entries are rejected with 409/Forbidden and audited
Privacy Controls & Redacted Sharing
"As a privacy officer, I want to control what metadata is shared while keeping the proof intact so that we comply with privacy regulations without weakening fraud defenses."
Description

Offer tenant-level policies to minimize exposed metadata while preserving verifiability. Support configurable EXIF fields, detached signatures/sidecar proofs for external recipients, and automatic stripping of non-proof metadata on share. Provide redaction workflows (manual or automated) for PII-sensitive regions while keeping the original sealed copy under restricted access. Enforce retention schedules, consent flags, and access scopes; log all disclosures in the custody ledger.

Acceptance Criteria
Tenant Policy: Configurable EXIF Whitelist
Given a tenant admin configures an EXIF whitelist at the tenant level, When a new capture is sealed, Then only whitelisted EXIF fields are embedded alongside the tamper-evident proof and all non-whitelisted fields are excluded. Given a tenant admin updates the whitelist policy, When the policy is saved, Then subsequent captures conform to the new whitelist without altering any existing sealed originals. Given application defaults conflict with tenant policy, When both are present, Then the tenant policy overrides the defaults. Given invalid EXIF keys are submitted, When the admin attempts to save the whitelist, Then the system rejects the save and displays validation errors identifying unknown or unsupported keys.
External Share: Detached Sidecar Proof
Given a user initiates an external share, When share mode "Proof-only sidecar" is selected, Then the exported media has non-proof metadata stripped and a detached sidecar contains the cryptographic timestamp, GPS/geofence validation result, content hash, and signature. Given an external recipient downloads the files, When the sidecar is verified using the tenant public key, Then verification succeeds and matches the original seal recorded in the claim. Given separate shares to different recipients, When links are generated, Then recipient-specific access tokens do not change the media content hash or the sidecar signature. Given the share completes, When the files are delivered, Then the custody ledger records recipient identity (or alias), timestamp, scope, and sidecar checksum.
Auto-Strip Non-Proof Metadata on Share
Given a share to an external domain, When the file is prepared, Then all non-proof EXIF/IPTC/XMP fields are removed per tenant policy while preserving pixels and proof-required fields. Given an internal share within the same tenant, When policy allows full metadata internally, Then no stripping occurs and this decision is logged. Given a field is marked retain-for-legal in tenant policy, When exporting externally, Then that field is preserved and its retention basis is noted in the ledger. Given a file is exported and re-imported, When inspected, Then ClaimFlow has not added any new non-proof metadata fields.
Redaction Workflow: PII Regions with Sealed Original Retention
Given a reviewer enters redaction mode, When PII regions are auto-detected or manually selected, Then a redacted derivative is created and the sealed original remains unchanged under restricted access. Given the redacted derivative is saved, When persisted, Then the system stores a derivative hash and a link to the original seal/hash for provenance. Given a user without "View Original" permission requests the asset, When access is evaluated, Then only the redacted derivative is delivered and the access attempt to the original is logged. Given an SIU role requests temporary original access, When dual authorization is completed, Then time-bound access is granted and auto-revoked per policy.
Consent Flags and Access Scope Enforcement
Given a capture is flagged "consent required" and consent is pending, When an external share is attempted, Then the share is blocked with a reason code until consent is recorded or an approved override occurs. Given consent documentation is uploaded and verified, When the flag is updated, Then allowed share channels per consent scope are enabled and recorded. Given access scopes are defined on the claim, When a user outside scope attempts view or share, Then the action is denied with a 403 (API) or UI error and the attempt is logged with user, scope, and resource. Given an API token lacks required scopes, When protected endpoints are called, Then no data is returned and the response is 403 with a correlation ID.
Retention Schedule Enforcement and Purge
Given a tenant retention schedule exists, When a sealed capture exceeds its retention period and no legal hold applies, Then derivatives and share artifacts are purged, the original sealed proof is destroyed per policy, and a minimal tombstone remains. Given a legal hold is active on a claim, When the retention period elapses, Then no purge occurs and the hold is visible in admin reports with reason and requester. Given a scheduled purge job runs, When deletion completes, Then the custody ledger records purge events including asset identifiers, checksums, and timestamps. Given a retention policy is shortened, When saved, Then the change applies prospectively and items nearing purge are flagged in a dashboard with expected purge dates.
Custody Ledger: Comprehensive Disclosure Logging
Given any disclosure event (view, download, share, API retrieval) occurs, When it is processed, Then the ledger records actor, timestamp, action, recipient (or alias), claim ID, access scope, consent status, and checksums for media and sidecars. Given a ledger integrity check is run, When the hash chain is verified, Then no tampering is detected and any gaps or anomalies are reported with affected ranges. Given an auditor queries by claim and time range, When results are requested, Then the system returns complete results within 3 seconds for up to 10k events and supports CSV export. Given privacy export settings are enabled, When logs are exported, Then PII fields are minimized or tokenized per policy while preserving auditability of events.
Self-Serve Proof Verification
"As an external auditor or opposing counsel, I want to independently verify the authenticity of evidence so that I do not need privileged access to ClaimFlow to trust the proof."
Description

Provide a read-only verification portal and API where recipients can upload a file or enter a claim link to validate timestamps, hashes, signatures, and geofence results without accessing internal systems. Generate a human-readable verification report and a downloadable verification bundle (media, sidecar JSON, signatures, proofs). Embed a QR code or link in shared artifacts that resolves to the verification page. Expose SDKs for partners to integrate verification into their systems.

Acceptance Criteria
Public Verification Portal: File Upload Validation
Given an unauthenticated visitor on the public verification portal When they upload a sealed media file Then the system validates the cryptographic timestamp, tamper-evident hash, embedded signature, and geofence constraints And the portal displays per-check results as Pass or Fail with machine-readable error codes for any failures And no login or access to internal ClaimFlow systems is required to view results And no internal claim data beyond artifact-level verification metadata is exposed And the operation performs read-only processing with no mutation of internal records And p95 response time for files up to 50 MB is ≤ 5 seconds; for files > 50 MB and ≤ 200 MB is ≤ 30 seconds
Claim Link and QR Code Resolution
Given a recipient scans an embedded QR code or opens a verification link from a shared artifact When the token in the link is valid and not expired or revoked Then the verification page loads over HTTPS and displays the artifact’s verification results without requiring authentication And the page shows the artifact identifier, verification timestamp, and per-check outcomes And invalid, expired, or revoked tokens return a 410 Gone response with no artifact data And HSTS is enabled and all HTTP requests are redirected to HTTPS
Human-Readable Verification Report Generation
Given verification results exist for an artifact When the user requests a verification report Then a human-readable report is generated in HTML and PDF including: artifact identifier, verification transaction ID, ISO 8601 UTC verification timestamp, hash algorithm and digest, timestamp proof reference, signature verification outcome, and geofence evaluation outcome And the report contains a QR code/link back to the verification page and a SHA-256 checksum of the report file And the report download begins within 3 seconds at p95 for artifacts up to 50 MB
Verification Bundle Packaging and Integrity
Given verification results exist for an artifact When the user downloads the verification bundle Then the bundle contains: original media bytes, a sidecar JSON with normalized metadata and per-check outcomes, proof/signature files, and a manifest listing filenames with SHA-256 checksums And the bundle is signed or accompanied by a detached signature with a public key reference And the download URL is pre-signed, single-use, and expires within 24 hours And all files in the bundle match the manifest checksums upon re-verification
Verification API and Partner SDKs
Given a partner possesses a valid API key and submits an HMAC-signed request When they call the verification API with a file upload or artifact ID Then the API returns 202 Accepted with a job ID for asynchronous processing or 200 OK with results for synchronous validation, and appropriate 4xx/5xx with machine-readable error codes on failure And the JSON schema includes per-check status (Pass/Fail), failure reasons, algorithms used, and reproducible digests And idempotency is honored using an Idempotency-Key header with identical results for retries within 24 hours And official SDKs for JavaScript, Python, and Java expose methods to submit files, poll results, and download bundles with typed responses and working examples
Privacy, Read-Only Access, and Auditability
Given any portal or API verification action When verification is executed Then only verification metadata and outcomes are returned; no PII or internal claim notes are exposed And the verification workflow is strictly read-only with no changes to internal claim records And an audit log entry is recorded including timestamp, artifact identifier, requester IP, user agent, result summary, and correlation ID And rate limiting of 60 requests per minute per IP is enforced with 429 responses and a Retry-After header when exceeded
Tenant-Scoped Key Management
"As a security administrator, I want isolated, rotating signing keys per tenant so that compromise is contained and long-term validation remains possible."
Description

Use per-tenant keys for signing and sealing operations managed by cloud KMS/HSM with least-privilege access. Support key rotation, revocation, and BYOK, with auditable logs and alerting on key events. Enforce modern algorithms (e.g., ECDSA P-256/Ed25519) and store key identifiers with each proof to enable long-term validation and crypto agility. Provide break-glass procedures and migration tooling for re-sealing if keys are compromised.

Acceptance Criteria
Per-Tenant Signing Key Isolation
Given tenants A and B exist and both have active signing keys When Tenant A submits a sealing request Then the KMS operation uses a key scoped to Tenant A (key_id prefix/ARN contains Tenant A identifier) And any attempt by Tenant A to use Tenant B’s key returns 403/AccessDenied and is logged And across a batch of 1,000 parallel sign operations over 10 tenants, zero operations use a cross-tenant key And median signing latency <= 150 ms and p95 <= 400 ms per request
Key Rotation Without Service Interruption
Given Tenant A schedules a rotation from k_old to k_new When rotation is activated Then new seals begin using k_new within 60 seconds of activation And seals created before activation verify with k_old; seals after activation verify with k_new, based on embedded key_id And audit events KEY_ROTATION_INITIATED and KEY_ROTATION_COMPLETED are written with tenant_id, old_key_id, new_key_id, actor, timestamps And during the rotation window, sign failure rate <= 0.1% with up to 3 automatic retries per failure
Key Revocation and Seal Verification Behavior
Given a tenant key is revoked/disabled When a sealing request references the revoked key Then the operation is blocked, no seal is produced, and error code KEY_REVOKED is returned And existing seals created prior to revocation continue to verify successfully; verification returns status signature_valid=true and key_status=revoked And an audit event KEY_REVOKED is emitted with tenant_id, key_id, reason, actor, timestamp And an alert is sent to the tenant’s configured channel within 60 seconds of revocation
Bring-Your-Own-Key (BYOK) Onboarding and Control
Given a tenant initiates BYOK setup When a CSR/import is provided to the cloud KMS Then the system validates the algorithm is ECDSA P-256 or Ed25519 and rejects others with validation error And the key is created/imported as non-exportable in KMS/HSM; only the ClaimFlow service principal has Sign permission; tenant admins can revoke this permission And proof-of-possession is verified via challenge signature prior to activation And activation requires approval by two tenant admins (two-person control) And a test seal is generated and verified successfully; an AUDIT event BYOK_ACTIVATED is recorded with tenant_id and key_id
Algorithm Enforcement and Key Identifier Storage
Given a seal is produced When the seal is written to EXIF and claim record Then fields proof.alg and proof.key_id are populated and immutable thereafter And allowed algorithms are exactly [ECDSA_P256_SHA256, ED25519]; any other selection returns a 400 validation error And verification tooling uses embedded alg and key_id to fetch the correct public key and validate the signature both online and with the offline verifier And changing the tenant’s default algorithm only affects new seals; historical records remain unchanged and verifiable
Audit Logging and Alerting for Key Events
Given any key event occurs (create, rotate, revoke, permission change, failed sign) When the event is processed Then an immutable audit log entry is persisted within 2 seconds including timestamp (UTC ISO8601), tenant_id, key_id, event_type, actor, request_id, and outcome And logs are queryable by tenant_id and time range with RBAC-scoped access and retained for >= 7 years And alerts are generated for rotation, revocation, permission changes, and failed sign rate > 1% over 5 minutes; alerts are delivered to configured channels with MTTA < 5 minutes
Compromise Response: Break-Glass and Re-sealing Migration
Given suspected key compromise for a tenant When break-glass is initiated Then a time-bound (<= 2 hours) least-privilege role is granted only after two-person approval; all actions are audited And a new key is provisioned and activated; signing with the old key is immediately disabled; service p95 signing latency remains <= 500 ms during incident And the migration tool enumerates seals by old key_id and re-seals assets with the new key, preserving original timestamps and adding migration metadata (migrated=true, original_key_id, migration_time) And migrated items verify successfully with the new key and include a chain-of-custody link to the original seal And a migration report is produced with totals, success rate >= 99.5%, failures listed with reasons, and stored in audit

QuickQueue Offline

Performs lightweight on-device extraction for VINs, serials, and timestamps when connectivity is poor, queueing full-resolution processing for later. Shows a readiness badge and syncs automatically so adjusters can move on without waiting. Keeps the 2‑second experience consistent in the field.

Requirements

On-device Lite Extraction Engine
"As a field adjuster, I want captured photos to instantly yield VIN/serial/timestamp tags on my device so that I can move on within two seconds even when I have no signal."
Description

Provide a lightweight on-device computer vision/NLP module that detects and extracts Vehicle Identification Numbers (VINs), equipment serial numbers, and capture timestamps from photos and typed messages within ~2 seconds, even without connectivity. The module must validate VIN formats (including checksums for 17-character VINs), normalize serial patterns per OEM if known, and time-stamp assets using the device clock with timezone. It should operate within mobile CPU/GPU constraints, support offline language packs for alphanumeric recognition, and return structured tags (field, value, confidence, source) to the ClaimFlow intake flow. The engine must degrade gracefully when confidence is below threshold by flagging fields as 'needs review' without blocking user progress. Integration points include the media capture screen and the draft claim object, with an interface to pass results to the downstream server for reconciliation once full-resolution processing completes.

Acceptance Criteria
VIN Extraction and Validation (Offline, Media Capture)
Given the device has no connectivity and the adjuster captures a photo of a VIN plate on the media capture screen When the on-device lite extraction engine runs Then a 17-character VIN, if present, is detected and normalized to uppercase within 2 seconds (p95) from shutter tap And the VIN is validated against checksum rules; if validation fails, the VIN field is flagged Needs Review without blocking progress And a structured tag is emitted to the draft claim with field="VIN", value="<VIN>", confidence in [0,1], source="photo" And the user can proceed to the next step without waiting for server processing
Serial Number Extraction and OEM Normalization (Offline Photos and Messages)
Given the device is offline and an equipment serial number is present in either a captured photo or a typed message When the on-device lite extraction engine runs Then a serial number candidate is detected within 2 seconds (p95) from user action And known OEM normalization rules are applied; if the OEM is unknown, the original serial format is preserved And a structured tag is emitted to the draft claim with field="SerialNumber", value="<normalized or raw>", confidence in [0,1], source in {"photo","message"} And if confidence is below the configured threshold, the SerialNumber field is flagged Needs Review without blocking user progress
Capture Timestamp Tagging with Device Timezone
Given the user captures a photo or composes a typed message When the on-device lite extraction engine records capture time Then the timestamp is taken from the device clock at capture moment including timezone offset and formatted ISO 8601 (e.g., 2025-09-30T14:22:05-07:00) And a structured tag is emitted with field="CaptureTimestamp", value="<ISO8601 with timezone>", confidence=1.0, source in {"photo","message"} And if the device clock or timezone changes after capture, the stored tag remains the original capture time
Readiness Badge and Non-Blocking UX in Poor Connectivity
Given connectivity is poor or unavailable during capture When the on-device lite extraction completes Then a readiness badge is displayed on the media item within 2 seconds indicating local extraction is complete And the user can navigate forward without waiting for server-side processing And if any extracted field has low confidence, only a non-blocking Needs Review indicator is shown; no blocking error dialogs are presented
Queueing and Auto-Sync of Full-Resolution Processing
Given the device is offline at the time of capture and lite extraction has produced tags When connectivity is restored Then the app automatically uploads full-resolution media and sends lite results to the server with a correlation ID linking local and server processing And downstream reconciliation updates the draft claim by replacing or confirming fields without creating duplicates (idempotent updates) And the readiness badge transitions to a synced state upon server acknowledgment without user intervention
Structured Tag Schema and Intake Flow Interface
Given the lite extraction engine returns results When writing results to the draft claim object Then each tag includes exactly: field, value, confidence (0.0–1.0), source in {"photo","message"} And the tags are persisted and visible in the intake flow within 2 seconds of extraction completion And the intake flow exposes these tags to the downstream server for reconciliation via the defined interface
On-Device Performance and Offline Language Packs
Given the engine runs on a supported mid-range mobile device without connectivity When performing VIN and serial OCR/NLP Then processing completes entirely on-device with no network calls and within 2 seconds (p95) from user trigger And the English alphanumeric offline language pack is used; if an expected pack is unavailable, extraction still attempts and any affected fields are flagged Needs Review without blocking And the UI thread remains responsive during extraction (no ANR events and no visible freezes)
Offline Capture Queue & Auto Sync
"As a field adjuster, I want my captured evidence and tags to sync automatically when the connection returns so that I don’t have to wait around or re-upload anything."
Description

Implement a durable, encrypted local queue that stores original media, thumbnails, extracted metadata, and submission intents when the network is unavailable or slow. The queue must automatically attempt background synchronization when connectivity improves, using exponential backoff, jitter, and battery-aware constraints. Items should be FIFO by default with per-claim grouping to preserve ordering, support pause/resume, manual 'Sync now', and safe retry semantics (idempotent server APIs with client-generated UUIDs). The system must handle conflicts, duplicates, and partial uploads, resume from byte offsets for large videos/photos, and surface per-item sync status to the UI. A maximum queue size and eviction policy must be configurable, with user-safe prompts before any data is purged. Successful sync should transition items to server-side workflows without user intervention.

Acceptance Criteria
Durable Encrypted Offline Queue
Given network connectivity is unavailable or below the configured quality threshold When the user captures media and submits Then the app writes original media, thumbnails, extracted metadata, and submission intent into a local queue encrypted at rest And each queued item is assigned a client-generated UUID and timestamp And the queued data persists across app kill and device reboot without loss And attempting to read the queued payloads outside the app yields unreadable/encrypted content And if a queued payload is corrupt or missing on read, the item is marked Failed-Corrupt with a recoverable error and excluded from auto-sync until resolved
Auto Sync with Backoff, Jitter, and Battery-Aware Constraints
Given at least one item is Pending and the device transitions to an online or improved-connectivity state When the background sync runner starts Then retries use exponential backoff starting at the configured base interval and capped at the configured maximum, with ± configured jitter applied to each interval And sync attempts respect battery constraints (do not start when battery < configured threshold and not charging; do start when charging or above threshold) And sync proceeds while the app is in background, subject to OS background-execution limits And on successful sync of an item, the server transitions the item into the configured workflow and returns a server ID that the client records; the item is removed from the local queue
FIFO with Per-Claim Ordering Preservation
Given multiple queued items across multiple claims When auto-sync processes items Then items are dequeued FIFO by default across claims And items within the same claim are uploaded in the exact capture/queue order And a failure of an item in a claim blocks subsequent items of that claim until resolved, without blocking items from other claims
User Controls: Pause/Resume and Manual Sync Now with Status Visibility
Given the queue has active or pending items When the user taps Pause Then all in-flight uploads are gracefully paused within the configured timeout and all items show status Paused When the user taps Resume Then syncing resumes from the last known offsets and statuses update to Syncing with progress When the user taps Sync now on a specific item Then that item is attempted within 1 second, bypassing the current backoff window while honoring battery constraints And per-item status reflects Pending, Syncing (with progress %), Retrying in [ETA], Paused, Failed (with error code), or Synced, and updates in real time And after status Synced, no further user action is required and the item is removed from the queue list
Resumable Large Uploads and Partial Upload Recovery
Given a queued media file larger than the configured large-file threshold When the network drops mid-transfer Then upon reconnection the upload resumes from the last acknowledged byte offset without restarting And the final server-side object checksum matches the local checksum And multiple network flaps during a single upload still result in a single server object with no duplicates And partial server artifacts left by interrupted uploads are cleaned up or finalized automatically after success
Idempotent Retries, Duplicate Detection, and Conflict Handling
Given each queued item has a client-generated UUID When the same item is retried due to timeout or 5xx Then the server responds idempotently (returns the same resource or 409/200 with existing ID) and the client marks the item Synced once the server resource exists When the server reports a duplicate submission for the same UUID Then no additional server record is created and the client does not re-upload media bytes When the server returns a conflict (e.g., 409) due to updated server-side metadata Then the client fetches the server version, applies safe merge for non-conflicting fields, marks the item Needs Attention if manual resolution is required, and continues syncing other claims/items And the system never creates more than one server record per client UUID
Queue Size Limit, Configurable Eviction, and Safe Prompts
Given the queue approaches or exceeds the configured maximum (by count or storage size) When additional items are added Then the app displays a user-safe prompt describing the impact and options before any purge occurs When the user approves eviction Then the configured eviction policy is applied exactly (e.g., delete oldest derived artifacts first) and originals or unsynced items are not purged unless explicitly confirmed by the user When the user declines or cancels the prompt Then no data is purged and the queue contents remain unchanged And current queue usage (count and storage) is visible in the UI
Readiness Badge & Offline UX States
"As a field adjuster, I want a clear indicator that extraction succeeded and my items are queued so that I can confidently move to the next task without waiting."
Description

Add clear UI affordances that confirm when on-device extraction is complete and the user can proceed, including a 'Ready' badge on captured items, an offline banner when in QuickQueue mode, and concise toasts that confirm queued submission. The experience must remain tap-to-capture with no blocking spinners, provide accessible color/contrast and screen reader labels, support localizations, and expose per-item states: 'Extracting', 'Ready', 'Queued', 'Synced', 'Needs review'. Provide a one-tap 'Move on' CTA after readiness to preserve the two-second field experience. The design must be consistent across iOS and Android and resilient to app backgrounding and process death by restoring UI state from the queue on relaunch.

Acceptance Criteria
Per-Item Status Badges
Given the user captures an item under poor connectivity and QuickQueue is active When on-device extraction starts Then the item shows an 'Extracting' badge within 200 ms and the capture control remains enabled Given on-device extraction completes successfully When the extraction result is committed to the local queue Then the item shows a 'Ready' badge within 2 seconds of the original capture time and exposes the 'Move on' CTA Given the user submits while offline or degraded When the item is enqueued for server processing Then its badge changes to 'Queued' within 200 ms and displays a queued timestamp Given the device reconnects and the server confirms receipt When the app syncs the item Then its badge updates to 'Synced' within 1 second of confirmation Given extraction confidence is below the configured threshold or a parse error occurs When local processing completes Then the item badge shows 'Needs review' and exposes an info affordance Rule: Exactly one state badge is visible per item at any time; state is persisted to local storage and survives app restart; behavior is identical on iOS and Android.
Offline QuickQueue Banner
Given the user is on the capture screen When network is unavailable or round-trip latency exceeds 1500 ms for 3 consecutive checks Then a non-blocking banner labeled 'Offline — QuickQueue active' appears within 500 ms Given connectivity is restored and all queued items are synced When the next health check passes Then the banner auto-hides within 1 second Rule: The banner does not block capture interactions, meets a minimum 4.5:1 text contrast ratio, is announced by screen readers as a status update, and behaves identically on iOS and Android.
Queued Submission Toast
Given an item transitions to 'Queued' When the queue write succeeds Then a toast appears within 300 ms with concise localized copy and auto-dismisses after 2–3 seconds Rule: Exactly one toast is shown per item enqueue event; the toast does not block input; it is announced by screen readers (polite), and behavior is identical on iOS and Android.
Move On CTA and Two-Second Flow
Given an item's state becomes 'Ready' When the readiness is displayed Then a 'Move on' CTA is shown within 100 ms and is accessible to screen readers without stealing camera focus Given the user taps 'Move on' When the action is processed Then the app returns focus to the capture surface and the user can initiate the next capture within 2 seconds of the original capture, with no blocking spinners or overlays Rule: Capture controls remain enabled during extraction; additional captures can proceed in parallel; behavior is identical on iOS and Android.
Accessibility Compliance for States and Controls
Rule: All badge text meets WCAG 2.1 AA contrast (>= 4.5:1); badge icons meet >= 3:1 contrast; all controls and labels support Dynamic Type without truncation; VoiceOver/TalkBack labels for badges announce 'Status: <state>'; 'Move on' reads as 'Move on, advances to next capture'; state changes trigger polite live announcements; focus order is readiness -> action -> next capture; behavior is identical on iOS and Android.
Localization and Internationalization
Rule: All user-visible strings (badges, banner, toasts, CTA) are externalized and localized for at least English, Spanish, and French with verified translations; unsupported locales fall back to English; pseudo-localization with +30% text expansion shows no truncation or overlap; RTL locales mirror layouts appropriately while preserving badge semantics; date/time and numeral formats follow device locale; behavior is identical on iOS and Android.
State Persistence and Recovery
Given the app is backgrounded or terminated by the OS during 'Extracting', 'Queued', or 'Synced' When the user relaunches the app Then the capture screen reconstructs per-item states from the local queue within 1 second, without duplicate items or regressions Given the device reconnects after being offline When sync resumes Then items in 'Queued' transition to 'Synced' and the UI updates within 1 second per item Rule: Recovery errors surface 'Needs review' with a retry action; a telemetry event is logged for each restore and sync outcome; behavior is identical on iOS and Android.
Server Reconciliation & Conflict Merge
"As a claims manager, I want server-quality results to automatically reconcile with the quick offline tags so that accuracy improves without creating duplicate work."
Description

Create a reconciliation service that merges server-side full-resolution extraction results with previously stored on-device tags. The service must compare fields by type and value, apply confidence-based precedence rules, surface discrepancies for human review when thresholds are crossed, and maintain an audit trail of changes with timestamps and origins (device vs server). Merging must be idempotent, preserve user edits, and trigger workflow rules (e.g., routing, validations) only after reconciliation is finalized. Provide a diff view API for the client to display any adjusted fields and a notification hook to update the claim record without duplicating tasks.

Acceptance Criteria
Type- and Confidence-Aware Merge Precedence
Given a claim has on-device tags and server full-resolution results for the same field types (VIN, serial, timestamp) with confidence scores When reconciliation executes Then values are normalized type-safely (VIN uppercased 17 chars; serial trimmed; timestamps converted to UTC ISO-8601) And the server value replaces the device value only if (server_confidence - device_confidence) >= configured_delta and server_confidence >= min_confidence And if normalized values are equal, a single value is kept with provenance {device, server} and confidence = max(device_confidence, server_confidence) And if the above replacement condition is not met, the device value is retained
Idempotent Merge on Repeat Inputs
Given a claim at reconciled version V and the identical server payload is received again When reconciliation runs Then the persisted claim data remains unchanged And no new audit entries are created And no additional notifications or workflow triggers occur
User Edits Take Precedence Over Automated Values
Given a user has edited a field after initial capture (edit_timestamp > extraction_timestamps) and marked as user-edited When reconciliation proposes a different server value Then the user-edited value is retained And a discrepancy record is created with the proposed server value and confidence And the field is excluded from auto-overwrite until a human explicitly accepts a change
Discrepancy Threshold Creates Human Review Task and Holds Finalization
Given a field has conflicting normalized values between device and server and the confidence gap is below configured_delta or both confidences are below min_confidence When reconciliation completes evaluation Then a single human-review task is created containing field_name, values, confidences, origins, and reason And reconciliation status is set to Pending Review And no routing/validation workflow rules are triggered until the task is resolved
Comprehensive Audit Trail for Reconciliation Changes
Given reconciliation applies any field change When the change is committed Then an immutable audit entry is recorded with field_name, previous_value, new_value, previous_origin, new_origin, previous_confidence, new_confidence, changed_at (UTC), and reconciler_id And the audit log is retrievable via API by claim_id and time range And entries are ordered chronologically with a monotonically increasing version number
Diff View API Returns Adjusted Fields Only
Given a client requests the diff view for claim_id with an optional since_version When the API is called Then the response includes only fields adjusted by reconciliation since since_version (or since last finalized version) And each item includes old_value, new_value, origin_before, origin_after, confidence_before, confidence_after, changed_at, and version And results are deterministically ordered by changed_at then field_name And the API returns 200 with an ETag and supports If-None-Match to return 304 when unchanged
Finalization Notification Hook Is Exactly Once and De-duplicated
Given reconciliation transitions a claim from In Progress or Pending Review to Finalized When emitting the notification Then exactly one notification is published per finalized version with a unique deduplication_id And downstream systems update the claim record once with no duplicate task creations And retries using the same deduplication_id do not create additional updates
Network Health Detection & Mode Switching
"As a field adjuster, I want the app to automatically switch to offline mode when the signal is weak so that my capture flow stays fast and predictable."
Description

Implement a network health monitor that evaluates connectivity quality (latency, bandwidth, packet loss) and determines when to enter or exit QuickQueue Offline mode. Define thresholds and hysteresis to prevent flapping, detect captive portals and airplane mode, and expose a lightweight 'preflight' check before attempting real-time extraction. When poor conditions are detected, the client should immediately route captures to the offline queue and enable the offline banner; when conditions improve, the client should resume live flows and trigger background sync.

Acceptance Criteria
Auto-enter Offline Mode under Poor Network Conditions
Given the app is in online mode and network health is probed every 2 seconds And median RTT over the last 5 probes > 800 ms OR effective downstream bandwidth < 128 kbps OR packet loss ≥ 20% across the last 10 probes When these poor conditions persist for 2 consecutive probe cycles (≥ 4 seconds) Then the client switches to QuickQueue Offline mode within 1 second And subsequent captures are routed to the offline queue immediately And the offline banner becomes visible within 500 ms And no live extraction requests are initiated while in offline mode
Auto-exit Offline Mode and Resume Live Flows on Recovery
Given the app is in QuickQueue Offline mode And good network conditions are detected: median RTT < 400 ms, bandwidth ≥ 512 kbps, packet loss < 5% for 10 consecutive seconds When the recovery threshold is met Then the client exits offline mode and resumes live flows within 2 seconds And queued items begin background sync within 2 seconds of exit And the offline banner is dismissed and the readiness badge reflects syncing within 1 second And at least one queued item is uploaded successfully when the server is reachable
Captive Portal Detection and Handling
Given the device is connected to Wi‑Fi without internet access behind a captive portal And the connectivity check GET to the configured endpoint responds with HTTP status ≠ 204 or contains a login HTML page When the check result is received Then the client classifies the state as "Captive Portal" And enters QuickQueue Offline mode within 1 second And displays an offline banner indicating sign‑in required And suppresses live extraction attempts until a successful 204 check is observed for 10 seconds
Airplane Mode Detection and Handling
Given the OS reports airplane mode enabled or no network interfaces available When the app evaluates network health Then the client enters QuickQueue Offline mode immediately (< 200 ms) And network probe routines are suspended And captures are routed to the offline queue And preflight returns "offline" without performing network I/O in < 50 ms
Preflight Network Check Before Real-time Extraction
Given a user initiates real‑time extraction When the preflight network check runs Then it completes within 300 ms And returns a decision of "online" only if median RTT < 400 ms, bandwidth ≥ 512 kbps, packet loss < 5%, and last successful connectivity probe was within 2 seconds And if the decision is "offline" no network extraction request is sent and the capture is queued And the decision and metrics are recorded with a timestamp
Immediate Offline Queue Routing and UI Indicators
Given poor network conditions have triggered offline mode When the user captures a photo or scans a VIN/serial Then the asset is written to the offline queue in < 100 ms And the UI shows a readiness badge within 500 ms And the total capture-to-ready time is ≤ 2.0 seconds at the 95th percentile measured over 100 events And no blocking spinner appears longer than 300 ms
Hysteresis to Prevent Mode Flapping
Given network conditions oscillate around the defined thresholds When poor–good–poor transitions occur within short intervals Then the client requires at least 5 seconds of confirmed poor conditions (≥ 2 consecutive probes) before entering offline after being online And requires at least 10 seconds of confirmed good conditions before exiting offline And the mode does not toggle more than once within any 15‑second window during a 3‑minute oscillation test
Admin Controls & Remote Model Updates
"As a product admin, I want to configure offline extraction behavior and safely roll out model updates so that each carrier’s needs and device constraints are respected."
Description

Provide an admin console and remote config to enable or disable QuickQueue Offline per carrier, line of business, or environment; configure which fields are extracted on-device; and set queue size, sync policies, and confidence thresholds. Support over-the-air updates of the lightweight extraction model and language packs with version pinning, phased rollouts, and rollback capability. Device capability checks must prevent incompatible downloads, and all changes must be auditable with who/when metadata.

Acceptance Criteria
Tenant-Level Toggle by Carrier/LOB/Environment
- Given an admin with Config:QuickQueue permission and a device enrolled to Carrier A, LOB=Auto, Env=Prod, When the admin disables QuickQueue Offline at scope Carrier A/Auto/Prod, Then the device hides the Offline extraction UI and blocks on-device extraction within 5 minutes of connectivity or on next app launch. - Given conflicting policies across scopes, When policies are evaluated, Then the most specific scope (environment > LOB > carrier) takes precedence and is applied consistently on API responses and on-device behavior. - Given the feature is disabled for a device scope, When the adjuster captures while offline, Then a non-blocking notice "Offline extraction disabled by admin" is shown and no on-device extraction artifacts are queued.
On-Device Field Configuration Enforcement
- Given admin enables on-device fields {VIN, SerialNumber, Timestamp} and disables others, When the device performs QuickQueue extraction, Then only the enabled fields are emitted, stored, and displayed; disabled fields are omitted and not persisted. - Given a new field configuration is published, When the device fetches config vN+1, Then captures taken after fetch honor vN+1 and captures taken under vN remain unchanged; diagnostics show config version applied. - Given a capture, When on-device extraction runs, Then the end-to-end on-device step completes within 2 seconds at p95 for enabled fields on supported devices.
Queue Size and Sync Policy Configuration
- Given queue size is set to 50 with policy "reject-new", When the 51st extraction is attempted offline, Then the capture succeeds but the extraction is skipped with a user notice and the queue remains ≤ 50. - Given queue size is set to 50 with policy "drop-oldest", When the 51st extraction is added, Then the oldest queued item is evicted, the new item is queued, and an eviction event is logged locally. - Given sync policy is "Wi‑Fi only" and "battery ≥ 20%", When the device is on Wi‑Fi with battery at 30%, Then queued items begin syncing automatically within 60 seconds; When on cellular or battery 15%, Then no sync occurs and items remain queued. - Given intermittent connectivity during sync, Then retries use exponential backoff capped at 15 minutes and items are uploaded in capture-timestamp order without duplication.
Confidence Thresholds and Readiness Badge Behavior
- Given per-field thresholds (e.g., VIN ≥ 0.92, SerialNumber ≥ 0.85), When an extraction meets or exceeds its threshold, Then the readiness badge shows "Ready" within 2 seconds and the value is included in the queued payload; otherwise the badge shows "Needs review" and the field is excluded from auto-population. - Given thresholds are updated by admin, When the device fetches the new config, Then new captures use updated thresholds; previously queued items retain their original local decision but may be re-evaluated during server processing after sync. - Given an extraction without a computable confidence, Then the badge shows "Pending" and the item is queued for full-resolution server processing.
OTA Update, Version Pinning, and Compatibility Gating
- Given admin pins the lightweight model to v1.3.2 for Carrier A/Prod, When model v1.4.0 is published, Then devices in that scope continue using v1.3.2 and do not download v1.4.0. - Given admin targets model v1.4.0, When the device passes capability checks (OS ≥ required, CPU supports required instruction set, free storage ≥ 150 MB), Then the package downloads, signature and checksum validate, and the model swaps atomically without user action; on any failed check, the download is skipped and the current model remains active. - Given a download or activation failure, Then the device reverts to the last working model, records failure telemetry with error code, and retries with exponential backoff.
Phased Rollout and Rollback Controls
- Given a phased rollout plan (10% → 50% → 100%) with a pause function, When the rollout starts, Then only the targeted cohorts receive the update in the defined window and telemetry shows version adoption by scope with ≤ 15-minute granularity. - Given admin triggers a rollback, When devices in the affected scope are online, Then each reverts to the previous working version within 2 hours and blocks further downloads of the rolled-back version. - Given a device has not checked in for > 7 days, When it next connects, Then it evaluates current rollout state and installs the latest allowed version for its cohort.
Comprehensive Audit Trail for Admin Changes
- Given any admin change (enable/disable, field list, thresholds, queue/sync policies, model publish/pin/unpin, rollout/rollback), Then an immutable audit entry is created with user ID, UTC timestamp, scope (carrier/LOB/env), change set (before→after), request ID, and outcome (success/failure). - Given audit logs, When queried by date range, scope, or user, Then up to 10,000 matching records return within 3 seconds and can be exported to CSV. - Given access control, When a user lacks Audit:Read permission, Then audit log access is denied with HTTP 403 and no data is returned.
On-device Security, Privacy, and Retention
"As a compliance officer, I want offline data to be encrypted, controlled, and auditable so that we meet regulatory obligations even when devices are used without connectivity."
Description

Ensure all queued content and metadata are encrypted at rest using platform-secure storage (e.g., iOS Keychain-protected keys, Android Keystore), encrypted in transit upon sync, and inaccessible to other apps. Enforce configurable retention policies (e.g., TTL after successful sync or logout), immediate wipe on device deregistration, and redaction of PII from logs and notifications. Support MDM policies for corporate devices, including blocking screenshots on sensitive screens and remote wipe triggers. Provide audit logs for access and deletion events to meet SOC 2/GDPR obligations.

Acceptance Criteria
Encrypt Queued Content At Rest Using Platform Secure Storage
Given the app queues media and metadata offline When data is written to local storage Then each item is encrypted with AES-256-GCM using a per-installation key protected by iOS Keychain/Android Keystore (hardware-backed when available) And each ciphertext uses a unique nonce and authenticated tag; decryption fails on tamper And files reside only in app-private storage with no-backup flags (iOS excluded from backup + NSFileProtectionComplete; Android MODE_PRIVATE + noBackup) And no content is written to shared/external storage or exposed via content providers And encryption keys are rotated on reinstall and invalidated immediately on logout or deregistration
Encrypt In-Transit Sync with Certificate Pinning
Given the device initiates sync When establishing a connection to the API Then TLS 1.2+ is required with strong ciphers and certificate pinning to a known public key/leaf; connections fail closed on pin mismatch And all uploads use HTTPS; HTTP and redirect downgrades are blocked And authentication uses short-lived tokens; secrets are not sent in query parameters And a pin-mismatch test results in a logged security event and no data transmission
Configurable Retention and TTL After Sync or Logout
Given an admin-configured retention policy with TTLs for pending and synced items When an item is successfully acknowledged by the server Then the local full-resolution copy is deleted within 5 seconds unless policy explicitly retains it And pending items exceeding their TTL are purged automatically on app launch and at least every 15 minutes while running And on user logout, all queued content, derived metadata, caches, and encryption keys are wiped immediately And policy defaults and changes are versioned and auditable
Immediate Wipe on Device Deregistration and Remote Wipe
Given the device receives a verified deregistration or MDM remote wipe command When the command is processed Then the app halts operations, invalidates keystore keys, securely deletes queued content/caches/logs, and locks access until re-enrollment And online wipes complete within 10 seconds of receipt; if offline, the wipe executes on next app resume prior to any UI access And a wipe completion event is recorded and, if possible, confirmed to the server And reinstallation does not restore previous data (fresh keys and empty storage)
Redact PII from Logs and Notifications
Given the app emits logs or user/device notifications When content could include PII (e.g., VINs, serials, names, emails, phone numbers, addresses, GPS) Then PII is masked or tokenized before persistence or display And production notifications contain no media thumbnails or message snippets with PII; they use generic text And production logging excludes raw payloads by default; debug logging (when enabled) still applies redaction And automated scans of log outputs find no unredacted PII
MDM Policies: Block Screenshots on Sensitive Screens
Given an active MDM policy or app setting to block capture When a user views sensitive screens (offline queue, media viewer, extracted data) Then screen capture and recording are blocked using OS mechanisms (Android FLAG_SECURE; iOS screen capture detection and content obscuring) And if the OS cannot block capture, sensitive content is blurred/obscured And policy changes take effect without app restart And all block/attempt events are logged without PII
Audit Logging for Access and Deletion Events (SOC 2/GDPR)
Given any access or lifecycle operation on queued content or keys When an action occurs (view, decrypt, sync, purge, wipe) Then an immutable audit event is recorded with: user/device ID, anonymized object ID, action, timestamp (UTC), app version, device model, network IP, reason code, and outcome And audit entries are encrypted at rest locally and synced to the server within 60 seconds with retry and ordering guarantees And audit logs are retained per policy (minimum 1 year configurable) and are exportable for compliance And tamper signals (clock skew beyond threshold, storage corruption) are detected and flagged

Tap Verify

Overlays tappable boxes on extracted elements; tap to view the value and confidence, correct in-line, or trigger a guided recapture. Makes extraction transparent and editable at the source, speeding QA and training. Results in fewer errors and faster approvals.

Requirements

Interactive Tap Overlay
"As an adjuster, I want tappable boxes over extracted fields on a claim asset so that I can quickly locate the data the system found and act on it without hunting through the image."
Description

Render tappable bounding boxes over all extracted elements in photos, PDFs, and message attachments. Boxes must align with model-provided coordinates, handle multi-line/grouped fields, and avoid overlap using collision/priority rules. On tap/click, the element is visually highlighted and brought into focus, anchoring an action surface without shifting the underlying asset. The overlay must be responsive, support pinch-zoom and pan, and remain performant at scale (≤200ms overlay paint on assets up to 20MP, ≤60ms on subsequent pans/zooms). Accessibility includes full keyboard navigation, focus states, and screen reader labels describing field name, value, and confidence. Integrates with ClaimFlow’s Extraction Service (reads coordinates/labels) and Event Bus (emits tap, view, and action telemetry). Supports web and mobile SDKs with a unified component API.

Acceptance Criteria
High-resolution overlay alignment and initial paint budget
Given a 20MP image or PDF page and a valid extraction payload containing bounding boxes and labels When the overlay component is mounted Then 100% of boxes render aligned to model coordinates within the greater of ±2px or ±0.2% of the asset dimension And the initial overlay paint completes within ≤200ms from mount time And no visual layout shift of the underlying asset occurs during or after overlay paint
Responsive pan/zoom with performant subsequent paints
Given the overlay is rendered over an asset When the user pans or pinch-zooms between 25% and 400% Then boxes translate and scale in lockstep with the asset with no jitter or drift (≤1px at 1x equivalent) And each subsequent overlay repaint completes within ≤60ms And tappable hit areas maintain a minimum effective size of 44x44 CSS px at 100% zoom (scaling proportionally)
Collision handling and priority resolution for overlapping elements
Given two or more bounding boxes overlap by ≥10% area When the overlay computes layout Then the element with higher priority (from payload) is stacked above lower-priority elements And smart nudging/offsets are applied so that no interactive hit areas overlap by more than 2px in the hit-test layer And z-index ordering is deterministic (priority, then reading order) And each element remains individually tappable without ambiguity (distinct hit-test regions)
Tap/click focus, highlight, and anchored action surface without asset shift
Given a user taps or clicks a visible overlay element Then the tapped element receives a visible focus/highlight state and is brought into view if partially occluded And the action surface anchors adjacent to the element without shifting or reflowing the underlying asset or changing zoom level And only one element is in the active state at a time, and previous highlights are cleared And tap and view telemetry events are emitted with elementId, assetId, coordinates, and ISO-8601 timestamp
Multi-line and grouped field rendering and interaction
Given an extracted field composed of multiple line spans or grouped child elements in the payload When the overlay renders the field Then a single grouped tappable region represents the field with visual cues linking all constituent spans And tapping any span activates the group, highlighting all spans as one selection And hit-testing on any constituent span resolves to the groupId And the displayed value concatenates spans in reading order for accessibility and telemetry
Accessibility: keyboard navigation and screen reader labeling
Given keyboard-only navigation and a screen reader are enabled When navigating from the asset container into the overlay Then every tappable element is reachable via Tab/Shift+Tab (or Arrow keys when in spatial mode) in a deterministic order And focus states are visible with WCAG 2.2 non-text contrast ≥3:1 And each element exposes an accessible name including field name, value, and confidence (e.g., “Field Claim Number, value ABC123, confidence 96%”) And Enter/Space activates the element and emits the same telemetry as a tap And Escape returns focus to the asset container
Integration with Extraction Service, Event Bus, and unified SDK API
Given a valid Extraction Service response with coordinates (absolute px or normalized) and labels When the component initializes on web and mobile SDKs Then coordinates are correctly interpreted (including DPI/scale normalization) and boxes render in the correct positions And the component connects to the Event Bus and publishes tap and view events to the specified topics without runtime errors And the web and mobile SDKs expose a unified API (props: asset, extractionPayload, eventBus, config; callbacks: onTap, onView, onRender) with identical signatures And rendering parity across web and mobile yields ≤1% pixel-diff at 1x scale on reference assets
Confidence and Metadata Popover
"As a claims manager, I want to see the confidence and origin of an extracted value so that I can decide whether to accept it or take corrective action."
Description

Display an anchored popover on tap that shows the extracted value, confidence score (numeric and color-coded), extraction source (asset ID and region), model version, and timestamp. Provide configurable confidence thresholds to flag low-confidence values and surface warnings. Support deep link to the full asset preview at the exact region and to the claim record field. Popover content must be localized, accessible, and dismissible with ESC/tap-away. Integrate with Tenant Settings for threshold configuration and with the Audit Log to record views and actions taken from the popover.

Acceptance Criteria
Popover Anchoring and Content Display on Tap
Given a tappable Tap Verify element is visible When the user taps the element Then an anchored popover opens adjacent to the element within 300 ms and no other popovers remain open And the popover displays: extracted value (plain text), confidence score (two decimals), a color-coded indicator, extraction source assetId and region (x,y,width,height normalized 0–1), model version, and extraction timestamp in ISO 8601 adjusted to the user’s timezone And only one popover can be open at a time and a subsequent tap on another element closes the previous popover And the popover repositions to remain fully within the viewport if the anchor is near an edge
Confidence Score Rendering and Threshold Warnings
Given tenant confidence thresholds are low=0.70 and medium=0.90 When a confidence score of 0.65 is displayed Then the indicator shows "0.65" with red status and a low-confidence warning is shown When a confidence score of 0.85 is displayed Then the indicator shows amber status and no warning banner When a confidence score of 0.95 is displayed Then the indicator shows green status and no warnings Then boundary behavior is: score < low -> red; low ≤ score < medium -> amber; score ≥ medium -> green And color indicators and any text meet WCAG 2.1 AA contrast requirements
Tenant Settings: Configurable Thresholds
Given an admin updates Tenant Settings thresholds to low=0.60 and medium=0.80 and saves When a user opens any popover after save Then the new thresholds are applied within 60 seconds without redeploy When invalid thresholds are entered (low >= medium or values outside 0–1) Then the settings cannot be saved and validation errors are shown When no tenant-specific thresholds exist Then defaults of low=0.70 and medium=0.90 are used And thresholds persist across sessions and apply to all Tap Verify popovers for the tenant
Deep Links to Asset Region and Claim Field
Given a popover is open for a specific element with assetId and region When the user selects "Open asset" Then the asset preview opens centered on the exact region with a visible highlight within 1 second When the user selects "Go to field" Then the claim record opens with the corresponding field in view and focused within 1 second And deep links include claimId, assetId, elementId, and region parameters to maintain context When the asset or field cannot be resolved Then navigation is prevented and a descriptive error is shown
Localization, Accessibility, and Dismissal
Given the user locale is es-ES When a popover opens Then all labels, messages, dates, and numbers are localized to es-ES; missing translations fall back to en-US And the popover has role="dialog", aria-labelledby a visible title, is keyboard-focusable, and traps focus while open And the ESC key and tap-away dismiss the popover and focus returns to the invoking element And color indicators are accompanied by text/icons and meet WCAG 2.1 AA contrast And keyboard behavior supports Tab/Shift+Tab to navigate and Enter/Space to activate actions
Audit Logging of Popover Views and Actions
Given a popover is opened Then an Audit Log entry "popover.view" is recorded with tenantId, userId, claimId, assetId, elementId, timestamp, and confidence score When the user clicks "Open asset" or "Go to field" Then an Audit Log entry "popover.action" is recorded with action type and the same context metadata When a low-confidence warning is shown Then an Audit Log entry "popover.warningShown" is recorded with thresholds and score When the popover closes Then an Audit Log entry "popover.close" is recorded with reason (esc, tap-away, close-button, navigation) And all Audit Log entries are available via the Audit Log UI/API within 15 seconds and are immutable
Inline Edit with Validation and Write-back
"As an adjuster, I want to correct extracted values in-line so that the claim record is accurate without leaving my review flow."
Description

Enable in-place editing of extracted values directly within the popover, with field-type-specific inputs (date picker, currency, VIN mask, address autocomplete). Apply synchronous validation (format, range, cross-field rules) and asynchronous business-rule checks (policy coverage, deductible caps). On save, write back to the canonical claim record, mark the field as ‘verified,’ and propagate updates to downstream workflow steps and notifications. Maintain complete audit history (before/after, who, when, reason), support undo within session, and resolve concurrent edits via optimistic locking and merge prompts. Ensure PII protection, role checks, and autosave with failure recovery.

Acceptance Criteria
Role-Based Inline Edit Popover With Field-Type Inputs and PII Masking
Given a user with edit permission taps a tappable box When the popover opens Then render a field-type-specific input: Date uses a date picker, Currency enforces locale currency with 2 decimals, VIN enforces 17 uppercase alphanumerics excluding I/O/Q with checksum, Address uses autocomplete with at least 5 suggestions within 500ms Given a user without edit permission taps a tappable box When the popover opens Then show the value read-only and keep Save disabled Given a field is flagged as PII and the user lacks PII view permission When the popover opens Then mask the value and prevent unmask and edit; log the access attempt in audit Given a field is flagged as PII and the user has PII view permission When the user clicks Unmask Then reveal the value and auto-remask after 5 minutes of inactivity Given the popover is open When it renders Then display the current extracted value and confidence percentage
Synchronous Field Validation: Format, Range, and Cross-Field Rules
Given a field input is changed When the value fails format validation Then show an inline error within 300ms and disable Save Given Date of Loss is entered When the date is in the future relative to system UTC date Then show error "Date cannot be in the future" and block Save Given Claim Amount is entered When the value is < 0 or > 1000000 or has > 2 decimal places Then normalize decimals where possible or show error and block Save Given a VIN is entered When length != 17 or contains I/O/Q or checksum fails Then show error and block Save Given Coverage Limit and Claim Amount exist When Claim Amount > Coverage Limit Then show a cross-field error on both fields and block Save Given all synchronous validations pass When Save is clicked Then proceed to asynchronous business-rule checks
Asynchronous Business-Rule Checks and Result Handling
Given local validations pass When Save is clicked Then invoke asynchronous checks for policy coverage, deductible caps, and special handling flags Given asynchronous checks return within 5 seconds When results include a blocking failure (e.g., policy lapsed) Then prevent commit and display a blocking message with a View Details link Given asynchronous checks return warnings (e.g., near deductible cap) When user confirms override per role policy Then allow commit and record the override in audit Given asynchronous checks time out after 5 seconds or network error occurs When retry is offered Then display a retry option and keep Save disabled until checks complete or user cancels Given the app is offline When Save is clicked Then queue checks and mark the field status as "Pending verification" until connectivity is restored and checks pass
Save/Write-Back: Verification Flag, Propagation, Autosave, and Recovery
Given validations and required checks pass or an allowed override is confirmed When the user clicks Save Then write the updated value to the canonical claim record within 1 second and return a new version identifier Given write-back succeeds When the response is received Then mark the field as Verified with timestamp and editor user id and display a verified badge Given the field value changes When write-back completes Then emit a FieldUpdated event to the workflow engine; dependent tasks recalculate and notifications dispatch within 10 seconds Given the user edits a value without clicking Save When 10 seconds elapse or the input loses focus Then autosave a draft to the server if online or to local storage if offline; do not mark as Verified until explicit Save Given Save or autosave fails due to network error When 3 retries with exponential backoff (1s, 2s, 4s) fail Then persist the draft locally, show a recovery banner, and auto-retry on reconnect; no data loss occurs Given the app is reloaded after a failure When the user returns within 7 days Then restore the unsaved draft and prompt to resume or discard
Audit Trail: Before/After, Who/When/Reason, Exportability
Given a field value is changed and saved When write-back succeeds Then append an immutable audit record with claim id, field id, previous value, new value, editor user id, ISO 8601 UTC timestamp, source (inline edit/autosave), and client id Given Save is initiated When the user confirms Then require a reason (code or free text min 5 chars) and include it in the audit record; disable Save until provided Given an audit record exists When queried via the audit API Then return it within 1 second and allow export as CSV and JSON Given an undo or redo results in a saved change When recorded Then create a new audit entry linked to the prior change id
Undo/Redo Within Session
Given a user has made changes to a field in the current session When the user clicks Undo Then revert the field to the previous value without page reload and update the Verified badge accordingly Given up to the last 10 changes are stored per field in session When the user clicks Undo repeatedly Then step back through prior states; Redo moves forward until the latest state Given an undo reverts to the original extracted value When applied Then clear local validation errors and re-run asynchronous checks if required before allowing Save Given the session ends (logout, 30 minutes inactivity, or browser close) When the session is restored Then the undo/redo stack is cleared
Concurrent Edit Resolution via Optimistic Locking and Merge Prompt
Given another user saved a newer version of the same field When the current user attempts to Save Then detect a version conflict via ETag/version and block silent overwrite Given a version conflict is detected When the merge prompt is displayed Then show Mine vs Theirs values and diffs within 500ms and offer actions: Keep Mine, Keep Theirs, Merge Given the user selects Keep Mine When Save proceeds Then overwrite the canonical value, increment version, and create audit entries for the conflict and resolution Given the user selects Keep Theirs When applied Then discard the local change, refresh the value, and close the popover without write-back Given the user selects Merge When editing the combined value Then re-run validations and checks before saving the merged result Given the merge prompt remains unanswered for 2 minutes When timeout occurs Then cancel the Save and retain the draft locally
Guided Recapture Flow
"As a field adjuster, I want a guided recapture when a field is unclear so that I can quickly obtain a usable image and move the claim forward."
Description

Provide an action from the popover to initiate guided recapture when confidence is low or data is unreadable. On mobile, open an in-app camera with real-time guidance (edge detection, glare/perspective hints, stability gate) and automatic capture; on desktop, offer drag-and-drop/upload with quality checks. Link recaptured assets to the original claim and targeted field, re-run extraction on the new asset, and update overlays and values automatically. Handle failures with fallback to manual entry and clear error messaging. Preserve chain-of-custody metadata, support offline capture with queued sync, and respect storage/retention policies.

Acceptance Criteria
Mobile Guided Recapture Initiation from Low-Confidence Field
- Given a field extracted with confidence below the configured threshold (default 0.80) or marked unreadable, When the user taps "Recapture" in the Tap Verify popover on mobile, Then the in-app camera opens within 1 second and the targeted field name is displayed in the capture UI. - Given camera permissions are not yet granted, When the user taps "Recapture", Then the OS permission prompt is shown once, and if permanently denied, Then the app displays a non-blocking error and offers Manual Entry. - Given the camera opens, When the session starts, Then the app records claim ID, field ID, initiating user ID, and recapture session ID for audit. - Given a recapture is initiated, When the event occurs, Then an analytics event "recapture_initiated" with source=TapVerify and platform=mobile is emitted.
Desktop Recapture via Upload with Quality Checks
- Given a field with low confidence on desktop, When the user selects "Recapture" from the popover, Then a modal opens supporting drag-and-drop and file browse with allowed types: JPG, PNG, HEIC, PDF (single page). - Given a file is dropped/selected, When pre-checks run, Then files larger than 25 MB or with dimensions under 1000 px shortest edge are rejected with an actionable message. - Given a raster image, When quality checks run, Then the image passes if Laplacian variance >= 100, glare coverage <= 15%, and skew <= 5 degrees; otherwise, Then the user sees specific guidance and may retry. - Given an upload starts, When progress is available, Then a progress indicator is shown and the user can cancel before 100% without affecting existing claim data. - Given a successful upload, Then the asset is linked to the claim and targeted field and queued for extraction.
Real-time Mobile Guidance and Auto-Capture
- Given the in-app camera is open, When a document/area is in frame, Then edge detection outlines appear within 250 ms and guidance hints show for glare and perspective. - Given the device is moving, When stability is detected for >= 500 ms and quality checks pass (glare <= 15%, skew <= 5 degrees, focus metric >= threshold), Then the shutter auto-captures; otherwise, Then auto-capture is suppressed. - Given auto-capture is available, Then a manual capture button is also available and functions identically. - Given a capture occurs, Then the user can review, retake, or accept; accepting proceeds to extraction.
Re-extraction and Overlay Update after Recapture
- Given a new asset is captured/uploaded, When the extraction job starts, Then a loading state is shown and completes within 8 seconds p95. - Given extraction succeeds, Then the targeted field value is updated in the UI, Tap Verify overlays refresh to reflect the new bounding boxes, and the new confidence score is displayed in the popover. - Given the value changes, Then the prior value, new value, user, timestamp, and asset ID are recorded in the audit log and accessible from the field history. - Given other fields are affected by the new asset, Then their overlays and values are updated consistently and flagged as "updated via recapture" in the audit trail.
Failure Handling and Manual Entry Fallback
- Given extraction fails due to timeout, parsing error, or repeated quality failure (>= 2 attempts), When the user completes the recapture attempt, Then the app displays a clear error message with next steps and opens Manual Entry for the targeted field. - Given the user switches to Manual Entry, When a value is submitted, Then validation rules are applied and the value is saved with a "manual" source tag linked to the failed recapture session. - Given a failure occurs, Then the recaptured asset is still attached to the claim and field for reference, and the user may retry later. - Given the user cancels the flow, Then no existing claim values are overwritten.
Chain-of-Custody Metadata Preservation
- Given any recapture (mobile or desktop), When an asset is created/attached, Then the system records immutable metadata: claim ID, field ID, user ID, session ID, capture/upload timestamp (UTC), device or browser info, app version, IP (desktop), GPS (if permission granted), file name, file size, mime type, and SHA-256 hash. - Given the asset is processed, Then a provenance link is maintained from the field value to the specific asset and extraction model version used. - Given a value is updated, Then an audit entry with before/after values, reason=recapture, and reference to the metadata is created and cannot be edited by end users. - Given an admin views the claim audit, Then chain-of-custody details are viewable and exportable as JSON.
Offline Capture with Queued Sync and Retention Compliance
- Given the mobile device is offline, When the user initiates recapture, Then capture is allowed, the asset and metadata are stored locally encrypted, and the field is marked "Pending Sync" without overwriting the current value. - Given connectivity is restored, When sync runs, Then pending assets upload automatically with exponential backoff (up to 5 retries), and on success the extraction flow runs as if captured online. - Given a conflict where the targeted field was updated on the server after the offline capture, Then the system does not auto-overwrite; it presents a resolution prompt to the user and flags the conflict in the audit log. - Given local temporary assets, When upload succeeds, Then local copies are deleted within 1 hour; if still offline, Then local copies are purged after 24 hours unless retention policy requires longer. - Given organizational storage/retention policies are configured, When an asset is stored server-side, Then the correct retention tag is applied and the asset is subject to scheduled deletion per policy, with deletion events logged.
Training Feedback Capture for Model Improvement
"As a product owner, I want verified corrections to feed our training pipeline so that extraction accuracy improves over time with real-world data."
Description

Capture user confirmations and corrections as labeled feedback tied to asset regions, field types, and final accepted values. De-duplicate identical corrections, anonymize/scrub PII per tenant policy, and batch to a secure ML feedback store. Provide configuration to opt-in per tenant, with controls for sampling rate and data retention. Expose metrics (accept rate, correction rate by field, confidence vs. accuracy) to inform model retraining and threshold tuning. Integrate with the ML pipeline via export jobs and with Feature Flags to enable/disable per environment.

Acceptance Criteria
Inline Tap Verify Feedback Capture
- Given Tap Verify overlays extracted fields for a claims document and a user confirms or corrects a field value - When the user saves the change or navigates away from the field - Then a feedback record is created with tenantId, documentId, fieldType, assetRegion {x,y,width,height}, extractedValue, finalAcceptedValue, modelConfidence, actionType (confirm|correct), timestamp, sessionId, and actorId hashed per tenant policy - And the feedback record is persisted within 500 ms and assigned a globally unique id - And the document state reflects the finalAcceptedValue immediately and on reload
Feedback De-duplication and Idempotency
- Given multiple identical corrections to the same documentId+fieldType+assetRegion within the same session or within a 30-minute window - When batching to the ML feedback store - Then only one canonical correction is stored and an occurrences count is incremented accordingly - And writes use an idempotency key derived from tenantId+documentId+fieldType+assetRegion+finalAcceptedValue to prevent duplicates on retries - And non-identical subsequent changes are stored as new versions with an incremented version number
Tenant Opt-In, Sampling, and Retention Controls
- Given a tenant with feedbackCapture disabled - When users perform confirmations or corrections - Then no feedback records are stored or exported and metrics exclude this tenant - Given feedbackCapture is enabled with samplingRate=20% (random) - When 10,000 eligible events occur - Then between 18% and 22% are captured and the remainder are dropped by design - And setting retentionDays=90 results in automatic purge of feedback older than 90 days via a daily job - And configuration changes via Admin API take effect within 5 minutes and are audit logged with actor, before/after, and timestamp
PII Scrubbing per Tenant Policy
- Given tenant policy marks specific fields or patterns as PII - When feedback is stored, exported, or logged - Then PII values are tokenized or masked according to policy and raw PII is not present in payloads, logs, or metrics - And assetRegion geometry and non-PII metadata remain intact for model training utility - And outbound exports pass an automated PII scan with 0 critical findings
Secure Batching to ML Feedback Store
- Given feedback events are queued for batching - When batch size reaches 500 records or 60 seconds elapse, whichever comes first - Then the batch is written to the ML feedback store with encryption in transit (TLS 1.2+) and at rest (AES-256) - And access to the store is restricted by service identity with least privilege and audited - And transient failures are retried with exponential backoff up to 5 attempts; on persistent failure, alerts are emitted and the queue persists up to 50,000 events with oldest-first drop when full
Metrics Exposure and Accuracy vs Confidence
- Given captured feedback for a tenant over a selected date range - When querying the Metrics API or viewing the dashboard - Then accept rate and correction rate are reported overall and by fieldType, with filters for environment and date - And calibration curves (confidence vs accuracy) are available by fieldType and exportable as CSV - And metrics are updated at least every 60 minutes and reconcile to within 1% of raw feedback counts
Export Jobs and Feature Flags by Environment
- Given Feature Flags are set per environment (dev, staging, prod) - When the export flag is disabled in an environment - Then no export jobs run and no feedback leaves that environment - Given the export flag is enabled - When the scheduled daily export runs - Then a per-tenant export is produced in the agreed schema with a manifest, transferred to the ML pipeline destination, and success is audit logged - And failures trigger alerts and are retried on the next schedule without data loss
Role-Based Controls and QA Review Queue
"As a QA lead, I want a permissioned review queue for flagged fields so that my team can efficiently verify and correct data before approval."
Description

Enforce role-based permissions for view, edit, and recapture actions. Provide a QA mode that aggregates low-confidence or changed fields into a review queue with assignment, due dates/SLAs, and bulk accept/correct actions. Surface status badges (Unverified, Corrected, Verified) on overlays and in the claim record. Record reviewer decisions in the audit log and emit metrics for throughput and aging. Integrate with ClaimFlow’s task engine for routing and notifications, and expose APIs to fetch and update review items programmatically.

Acceptance Criteria
RBAC: Overlay View/Edit/Recapture Permissions
Given a user with role Adjuster lacking Edit permission, when opening Tap Verify overlay, then value and confidence are visible but inline edit controls are disabled and recapture is hidden Given a user with role QA Reviewer with Edit permission, when tapping a field, then inline edit and guided recapture controls are enabled Given a user without Recapture permission, when attempting to invoke recapture via API, then the API returns 403 RBAC_DENIED and no recapture session is created Given role permissions are updated by Admin, when a user next loads the overlay or calls the API, then the new permissions are enforced within 60 seconds Given an unauthorized attempt to edit or recapture, when the attempt occurs, then an audit log entry is created with actor, action, fieldId, and RBAC_DENIED outcome
QA Mode: Queue Population for Low-Confidence and Changed Fields
Given QA mode is enabled with threshold 0.80, when a claim has extracted fields, then all fields with confidence < 0.80 are added to the QA review queue exactly once Given a user edits any extracted field value, when QA mode is active or later activated, then that field is added to the QA review queue marked as Changed Given additional edits occur to a queued field, when viewing the queue, then the item remains a single entry with latest proposed value and retains change history link Given new extraction results arrive (reprocess) during QA mode, when confidence rises above threshold and no user change exists, then the item is removed from the queue; otherwise it remains Given the queue is loaded, when viewing an item, then metadata includes fieldId, label, source (photo/message), current value, previous value, confidence, and reason (LowConfidence or Changed)
QA Review: Assignment, Due Dates, SLA Alerts, and Notifications
Given a new QA queue item is created, when routing rules assign it to a team or user, then the item shows Assignee and DueDate computed from SLA policy Given an assignee change occurs, when the assignment is saved, then a task is created/updated in the task engine and a notification is sent to the new assignee within 60 seconds Given an item approaches SLA (<= 2 hours remaining), when viewed in the queue, then it displays a Yellow SLA badge; if overdue, a Red SLA badge and an OVERDUE event is emitted Given SLA policy is updated, when recalculation runs, then existing open items have DueDate recomputed and badges/alerts updated accordingly Given an item is unassigned, when viewed, then it is filterable as Unassigned and appears in the team work queue
QA Review: Bulk Accept and Bulk Correct Actions
Given multiple items are selected in the QA queue, when Bulk Accept is executed, then all selected items transition to Verified and their values remain unchanged Given one or more selected items fail validation during Bulk Accept, when the operation completes, then successful items are committed and failures are reported with item-level error codes Given multiple items of the same field type are selected, when Bulk Correct is executed with specified corrections per item, then each item is updated to its provided value and transitions to Corrected Given Bulk operations complete, when checking the audit log, then each item has a decision entry linked by a common bulkOperationId with actor and timestamp Given a bulk action is triggered, when processing, then user feedback shows progress and final success/failure counts within the session
Status Badges: Unverified, Corrected, Verified on Overlay and Claim Record
Given an extracted field is in the QA queue, when displayed on the overlay, then it shows an Unverified badge; once accepted without change, it shows Verified Given a field is changed and approved during QA, when displayed, then it shows Corrected with a tooltip indicating previous value and reviewer Given a field’s QA decision is reverted (re-opened), when displayed, then the badge returns to Unverified and the claim-level QA status updates counts accordingly Given field badges update, when viewing the claim record, then aggregate counts of Unverified, Corrected, Verified are displayed and match the overlay Given a status change occurs, when queried via API, then the field status reflects the latest value within 1 second and persists across sessions
Audit Logging and Metrics for Reviewer Decisions
Given a reviewer accepts or corrects a field, when the decision is saved, then an immutable audit entry records actor, timestamp, fieldId, oldValue, newValue, rationale (optional), and SLA state Given an item is reassigned or deferred, when the action is taken, then the audit log records the transition with from/to assignee and due date changes Given decisions are made, when metrics are computed hourly, then throughput (items/hour per reviewer), average cycle time, and aging buckets (0–4h, 4–24h, >24h) are emitted Given metrics are emitted, when querying the metrics endpoint, then values are available within 5 minutes and align with audit log counts (±1% tolerance) Given audit data is requested, when filtering by claimId, reviewer, date range, and outcome, then results return within 2 seconds for up to 10k entries
APIs and Task Engine Integration for Review Items
Given a client calls GET /review-items with filters (claimId, status, assignee, reason), when valid, then the API returns a paginated list with totalCount and ETag headers Given a client updates a decision via PATCH /review-items/{id} with If-Match ETag, when the tag matches, then the decision is applied and the item status updates; when it does not, API returns 409 CONFLICT Given a review item is created, assigned, decided, or overdue, when events occur, then webhooks ITEM.CREATED, ITEM.ASSIGNED, ITEM.DECIDED, ITEM.OVERDUE are emitted to subscribed endpoints Given the task engine integration is enabled, when an item is created or reassigned, then a corresponding task is created/updated with deep link to the Tap Verify view Given API usage exceeds 600 requests/min per tenant, when additional requests arrive, then the API responds with 429 TOO_MANY_REQUESTS and Retry-After header

Live Factline

Stream transcribe voice notes as they’re recorded, auto-extracting policy numbers, VINs, parties, locations, causes of loss, and timestamps in real time. Shows live checkmarks when required fields are captured and instantly creates structured fields and triage tasks. Cuts rework and speeds submission for adjusters while giving intake leads immediate, high‑quality data to route without waiting.

Requirements

Streaming Transcription Engine
"As an adjuster, I want my voice notes transcribed in real time so that I can see what the system heard and avoid re‑recording or manual typing."
Description

Provide low‑latency, streaming speech‑to‑text for voice notes inside ClaimFlow, transcribing as the adjuster speaks with insurance‑domain vocabulary support (policy numbers, VINs, loss terms), punctuation, and token timecodes. Must operate on web and mobile recorders, sustain <500 ms end‑to‑end latency, handle brief network interruptions with seamless resume, and support optional local buffering for poor connectivity. Audio is processed securely, with configurable retention (transient or retained per compliance policy). Exposes a stable streaming API that emits interim and finalized transcript segments for downstream extraction.

Acceptance Criteria
Real-time transcription latency on web and mobile
Given an adjuster uses the in-app recorder on supported web and mobile clients and speaks continuously for up to 15 minutes When audio frames are streamed to the transcription engine under normal network conditions Then interim transcript updates are emitted with end-to-end latency <= 500 ms at the 95th percentile measured from frame arrival to interim text emission And average latency <= 300 ms And finalization of a spoken phrase occurs within 800 ms after detecting 500 ms of silence And these latency thresholds are met on latest Chrome (desktop), Safari (iOS), and Chrome (Android)
Domain vocabulary recognition accuracy
Given voice notes include policy numbers, VINs, names of parties, locations, causes of loss, and common insurance terms When the notes are transcribed in real time Then exact-match accuracy for policy numbers >= 95% in clear speech and >= 90% with moderate noise (SNR >= 10 dB) And exact-match accuracy for VINs >= 95% in clear speech and >= 90% with moderate noise, and recognized VINs pass ISO 3779 character rules (no I, O, Q) and length = 17 And recognized policy numbers match configured carrier regex patterns with precision >= 95% and recall >= 95% in clear speech And recall and precision for predefined loss-domain terms each >= 92% in clear speech
Token timecodes and punctuation correctness
Given finalized transcript segments are produced When inspecting their token lists and punctuation Then each token contains start and end timestamps aligned to the audio timebase with median absolute error <= 50 ms and 95th percentile error <= 100 ms against ground truth And token timestamps are monotonically non-decreasing without overlaps and cover the tokenized text And sentence-ending punctuation (period, question mark) F1 >= 0.90 and comma F1 >= 0.85 in clear speech And finalized segments are immutable; once emitted, their text, punctuation, and token timecodes never change
Seamless resume after brief network interruptions with local buffering
Given an active transcription stream with local buffering enabled And the client experiences a network interruption of up to 5 seconds When connectivity is restored Then the stream resumes automatically within 1 second without user action And no transcript loss or duplication occurs; buffered audio is sent and processed in order And interim-to-final segment continuity is preserved (no gaps in segment IDs or time ranges) And with local buffering disabled, interruptions up to 2 seconds still resume without data loss And the client can buffer at least 60 seconds of audio locally and backfill upon reconnect
Streaming API emits interim and final segments with stable contract
Given a client connects and streams audio via the transcription streaming API When messages are received Then the API emits distinct interim and final transcript segment messages with a stable, versioned schema And each final segment message includes: segment identifier, text, isFinal=true, token list with per-token timecodes, and segment timing metadata And segment identifiers are monotonically increasing within a stream And interim segments may be superseded by a final segment covering the same range; once a final segment is sent, it is never retracted or modified And the API allows graceful stream closure and delivers a completion message
Secure processing and configurable retention
Given retention policy is set to transient for a tenant When a transcription stream completes Then no audio or transcript content is persisted server-side and none is retrievable after stream closure And data are encrypted in transit using TLS 1.2+ during processing Given retention policy is set to retained:30d for a tenant When a transcription stream completes Then audio and transcripts are stored encrypted at rest and automatically deleted after 30 days per policy And retention configuration is enforced per stream and recorded in audit metadata without storing raw content
Real‑time Fact Extraction
"As an intake lead, I want key claim facts identified as I speak or listen so that I can act on reliable, structured data without waiting for a finished recording."
Description

Continuously extract and normalize key facts from the live transcript—policy numbers, VINs, parties, locations, causes of loss, and timestamps—updating outputs as transcript hypotheses change. Apply domain validations (VIN length and check digit, policy number formats by carrier, date/time normalization to UTC, location geocoding) and map to ClaimFlow’s standard taxonomy. Emit incremental structured fact events with confidence scores for consumption by the UI, field population, and workflow engines.

Acceptance Criteria
Real-time policy number extraction with carrier validation
- Given a live transcript stream containing a policy number utterance and detected carrier context, When the engine identifies a policy number candidate, Then it validates against the active carrier’s pattern repository and emits a PolicyNumber.created event with normalized_value, carrier_code, confidence >= 0.85 within 500 ms of the final token. - Given a candidate fails validation, When no carrier-specific pattern matches, Then no PolicyNumber event is emitted and a Validation.rejected diagnostic is recorded without blocking other extractions. - Given a previously emitted policy number is impacted by an ASR hypothesis change, When the token sequence changes, Then a PolicyNumber.updated event with updated normalized_value and incremented version is emitted and the prior version is marked superseded.
VIN extraction with length and check digit validation
- Given the live transcript includes a 17-character VIN candidate, When the engine detects it, Then it validates length=17 and ISO 3779 check digit, uppercases, removes spaces, and emits a Vin.created event with normalized VIN and confidence >= 0.90 within 500 ms of the final token. - Given a VIN candidate fails check digit or contains invalid characters (I, O, Q), When detected, Then no Vin event is emitted and a Validation.rejected diagnostic is recorded. - Given a VIN was previously emitted, When an ASR hypothesis update changes any VIN character, Then a Vin.updated event is emitted with incremented version and the prior version is marked superseded.
Party entities identification and normalization
- Given the transcript mentions an individual and a role (e.g., insured, claimant, witness), When detected, Then a Party.created event is emitted with fields role (from ClaimFlow taxonomy), full_name, optional contact info, and confidence >= 0.75 within 700 ms of mention. - Given multiple mentions refer to the same person, When coreference resolution determines equivalence, Then subsequent events reuse the same party_id and a Party.merged event is emitted consolidating attributes. - Given a previously emitted party becomes unsupported due to hypothesis updates, When confidence remains < 0.50 for 2 consecutive seconds, Then a Party.retracted event is emitted and the UI checkmark for Parties is cleared via the event flag.
Location extraction with geocoding
- Given the transcript mentions an address or place name, When detected, Then a Location.created event is emitted with formatted_address, lat, lon, geocode_provider, and confidence >= 0.80 within 1 second of the mention. - Given multiple geocode candidates are viable, When ambiguity exists, Then the top candidate is emitted and an ambiguity flag is set with n_candidates and alternative candidates included for disambiguation. - Given an ASR update changes the address tokens, When the resolved coordinates shift by >200 meters, Then a Location.updated event is emitted with incremented version and the prior is marked superseded.
Cause of loss classification mapped to taxonomy
- Given the transcript contains a description of the loss, When a cause can be inferred, Then a CauseOfLoss.created event is emitted with ClaimFlow taxonomy code (e.g., FIRE, WATER, THEFT, WEATHER, COLLISION, LIABILITY, OTHER) and confidence >= 0.70 within 500 ms of detection. - Given the classification confidence is < 0.70, When ambiguity persists, Then a CauseOfLoss.candidate event is emitted (not created) with confidence for UI hinting until confidence threshold is met. - Given subsequent transcript clarifies the cause, When confidence >= 0.70, Then the candidate is promoted via CauseOfLoss.created with the same cause_id and updated fields.
Timestamp extraction and UTC normalization
- Given the transcript mentions a date/time (absolute or relative) and a local timezone context is known, When detected, Then a Timestamp.created event is emitted with normalized_value in ISO 8601 UTC (Z), original_time_zone, and confidence >= 0.80 within 500 ms of detection. - Given no explicit timezone is mentioned, When adjuster profile provides a default timezone, Then normalization uses the profile timezone and source=profile is recorded. - Given a hypothesis update changes the date/time interpretation, When the normalized value differs, Then a Timestamp.updated event is emitted with incremented version and prior version marked superseded.
Incremental fact events and hypothesis reconciliation
- Given streaming transcript partials and finals, When new facts are extracted or existing facts change, Then events are emitted incrementally with schema fields: event_type, fact_type, fact_id, version, normalized_value, raw_span[start_ms,end_ms], confidence, created_at, correlation_id. - Given multiple updates occur to the same fact, When versions increment, Then ordering is strictly increasing and reprocessing the same fact_id+version is idempotent. - Given tokens are retracted by ASR, When a prior fact is invalidated, Then a Fact.retracted event is emitted within 300 ms and subscribers (UI and workflow engine) receive the event within 200 ms and 500 ms respectively, reflected by cleared UI checkmarks where applicable.
Live Completion Checkmarks
"As an adjuster, I want live checkmarks for required fields so that I know exactly what’s already captured and what remains while I’m recording."
Description

Display a real‑time checklist that reflects required fields captured from the ongoing transcription, showing clear states (missing, partial, complete) and a progress indicator. Each checkmark links to the source transcript snippet and confidence, highlights conflicts, and surfaces what to say next to fulfill unmet requirements. Works within the claim intake UI with accessibility and keyboard/voice controls.

Acceptance Criteria
Real-time Checkmark State Updates
Given live transcription emits an entity for a required field, when the entity is recognized or updated, then the corresponding checkmark state updates within 300 ms. Rule: State definitions — Missing: no candidate value with confidence >= 0.50; Partial: candidate exists but fails validation OR confidence in [0.50, 0.89]; Complete: normalized value passes validation rules and confidence >= 0.90. Rule: State transitions are Missing -> Partial -> Complete; regression only occurs if a conflict is detected. Rule: Visual indicator for each state includes icon, label text, and color with contrast >= 4.5:1; information is not conveyed by color alone. Given network latency adds 200 ms and events arrive out of order, when processing completes, then the final state reflects the highest-confidence validated value.
Progress Indicator Accuracy
Given a configuration with M required fields, when C fields are in Complete state, then the progress displays "C of M Complete" and percent = round((C/M)*100) bounded [0,100]. Rule: Partial fields do not increment C. Rule: Progress updates within 300 ms of any field state change. Rule: aria-label or tooltip announces "C of M required fields complete" for assistive tech. Given M = 0, then the progress shows "0 of 0 Complete" and 100%.
Source Snippet and Confidence Linking
Given a user activates a checkmark item, when the source is opened, then the transcript scrolls to and highlights the exact tokens used, showing timestamp (mm:ss) and confidence as a numeric value with two decimals. Rule: If multiple snippets contributed, a list shows each snippet with timestamp and individual confidence; the highest-confidence snippet is preselected. Rule: Keyboard support — Enter/Space opens source, Tab navigates snippets, Esc closes and returns focus to the originating checkmark. Rule: Voice commands "Open source" and "Close source" perform the same actions. Performance: 95th percentile time to open source view <= 400 ms.
Conflict Detection and State Handling
Given two or more distinct candidate values for the same field with confidence difference <= 0.05 and both >= 0.70, when they are detected, then the field is marked Conflict and its state is Partial. Rule: A conflict badge and message list all candidates with timestamp and confidence, and guidance includes "Please confirm correct [field]". Rule: Conflicted fields are excluded from the Completed count until resolved. Rule: When a validated value with confidence >= 0.90 is extracted that matches one candidate or the user confirms a candidate, then the conflict clears and the state becomes Complete within 300 ms. Rule: Conflict events are logged with time, values, and confidences for audit.
Next-Utterance Guidance
Given at least one required field is Missing or Partial, when the checklist updates, then the "What to say next" panel displays up to three prompts referencing unmet fields by name. Rule: Prioritization — Missing over Partial; then by workflow dependency; tie-breaker by time since last attempt. Rule: Guidance updates within 500 ms of any state change. Rule: Each prompt is <= 120 characters, plain language, and supports localization. Rule: Voice command "Read next prompt" reads the top suggestion; keyboard shortcut Alt+N focuses it.
Accessibility and Controls Compliance
Rule: Component conforms to WCAG 2.2 AA; focus indicators contrast >= 3:1, logical tab order, ARIA roles (list, listitem, status), and aria-live announcements on state change. Rule: Screen reader announcement format on update — "[Field label], [state], confidence [0.00–1.00 with two decimals]". Rule: Keyboard navigation — Up/Down move between checkmarks; Enter/Space toggles details; Alt+N triggers guidance; no pointer required. Rule: Voice control recognizes "Next requirement", "Previous requirement", "Open source", "Close source", "Read next prompt" with >= 95% accuracy on the curated test set. Performance: aria-live announcements occur within 500 ms of state changes.
Auto‑Populate Structured Fields
"As a claims manager, I want extracted facts to fill the form automatically so that submissions are complete faster and require fewer manual corrections."
Description

Automatically populate claim intake fields with extracted facts in real time, preserving user editability and providing conflict resolution. If a user edits a field, auto‑updates pause for that field with the option to re‑enable. Maintain version history with timestamps, source (voice vs. manual), and confidence, with a one‑click revert to prior values. Synchronize changes across the claim record and downstream systems without duplicate updates.

Acceptance Criteria
Real-time Auto-Populate on Voice Extraction
Given a live voice note is being transcribed and the NLP extracts a Policy Number with confidence >= 0.85 When the extraction completes Then the Policy Number field is auto-populated within 500 ms with the extracted value, tagged with source=voice, confidence, and timestamp Given a field is empty and multiple values are extracted sequentially When a higher-confidence value (increase >= 0.05) arrives before the user edits the field Then the field updates to the new value and the version history logs both versions Given the NLP emits a value that fails the field’s validation rules (e.g., invalid VIN checksum, non-numeric policy) When validation fails Then the field is not populated and a non-blocking warning is logged to telemetry
Edit Pause on Manual Override
Given a field was auto-populated from voice When the user edits the field Then auto-updates for that field pause immediately, an “Auto-update paused” indicator appears, and subsequent voice extractions do not change the field Given auto-updates are paused for a field When the user clicks “Re-enable auto-updates” Then the pause state clears and the next incoming valid extraction for that field is applied only if its timestamp is newer than the current value Given auto-updates are paused When the voice stream ends without further extractions Then the paused state persists until the user re-enables or the claim is submitted
Conflict Resolution Between Voice and Manual Values
Given a field has a manual value and a new conflicting voice value arrives When the conflict is detected Then a conflict banner appears showing both values with sources, confidence scores, and timestamps, and no automatic replacement occurs Given a conflict banner is displayed When the user selects “Keep Manual” or “Replace with Voice” Then the chosen value is committed, the other is archived in history, and the conflict is cleared within 300 ms Given the user takes no action for 60 seconds after conflict and routing rules require a value When the system proceeds Then the currently committed value (manual) is used for routing and an unresolved-conflict event is logged without blocking
Version History and One-Click Revert
Given a field has received at least one voice and one manual update When the user opens Version History Then entries show value, timestamp (UTC ISO-8601), source (voice/manual), user id (if manual), and confidence (if voice) Given a prior version is selected When the user clicks “Revert” Then the field value changes to that version within 300 ms, an audit entry is created, and the auto-update pause state remains unchanged Given a revert occurs When downstream synchronization runs Then only a single consolidated update is emitted to subscribers with the reverted value
Idempotent Synchronization to Downstream Systems
Given a field value changes via auto-populate, manual edit, or revert When synchronization is triggered Then a message is sent with a stable correlation id for the change and a deduplication key so downstream systems can ignore duplicates Given the same value is set multiple times due to retries When downstream receives repeated messages with the same deduplication key Then only one update is applied and others are acknowledged without side effects Given a downstream system is temporarily unavailable When retries occur Then exponential backoff with jitter is used up to 6 attempts over 15 minutes, the UI shows “Sync pending,” and upon success the status flips to “Synced” without creating duplicate updates
Required Fields Checkmarks and Triage Triggering
Given required fields are configured for intake When all required fields reach a valid committed state (pass validation, no unresolved conflicts) Then a green checkmark appears for each and triage tasks are created within 1 second Given a required field later becomes invalid due to user edit or revert When validation fails or a conflict arises Then its checkmark is removed, dependent triage tasks are paused or rescinded per configuration, and the UI indicates which requirement is unmet Given a required field is valid but auto-updates are paused When a new higher-confidence voice value arrives Then the field does not change and no checkmark toggling occurs unless the user re-enables updates
Instant Triage Task Routing
"As an intake lead, I want tasks created and routed as soon as key facts are captured so that I can move claims forward immediately."
Description

Create and route triage tasks the moment the minimal data set is satisfied, using configurable workflow rules (LOB, severity, geography, availability). Ensure idempotency and de‑duplication when facts are updated, and update task metadata as higher‑confidence values arrive. Push tasks to the appropriate queues in real time and notify assignees, enabling routing without waiting for the recording to finish.

Acceptance Criteria
Minimal Data Set Trigger
Given a live transcription session is in progress and the minimal dataset is configured as Policy Number, Loss Location, Loss Timestamp, Cause of Loss, and LOB with minimum confidence 0.80 When the final required field is captured meeting the confidence threshold Then a triage task is created within 2 seconds And the task includes the captured fields and an initial Severity bucket per rules And no user action is required to create the task And the task status is set to "New" and the creation event is logged with timestamp and source "Live Factline"
Rule-Based Queue Routing
Given active workflow rules consider LOB, Severity, Geography, and Adjuster Availability with defined priority ordering When a triage task is created Then the task is routed to the queue defined by the highest-priority matching rule And if multiple rules match, the rule with the highest priority value is applied deterministically And if no adjuster is available in the target queue, the task is placed in the configured fallback queue and a routing alert is logged And the routing decision includes an attached rules evaluation trace on the task
Idempotent Task Creation
Given a triage task has already been created for the current intake session When additional or corrected facts arrive that do not invalidate the minimal dataset Then no additional triage task is created for the same session and claim context And the system maintains exactly one open triage task per deduplication key defined as Policy Number + Loss Timestamp (±15 minutes) + Loss Location And repeated detections within 5 minutes update the existing task only
Metadata Update on Confidence Upgrade
Given a triage task exists with preliminary extracted values When a higher-confidence value (> previous by at least 0.05) or a corrected normalized value for a field (e.g., VIN, address) arrives Then the task's corresponding fields are updated within 1 second and the previous value is retained in an immutable audit log And routing rules are re-evaluated; if the target queue changes, the task is moved and the previous assignee is unassigned And the current assignee (if any) receives a single consolidated update notification per 60-second window
Cross-Source De-duplication
Given facts may arrive concurrently from voice transcription and message input tied to the same intake ID When the minimal dataset is satisfied by any combination of sources Then exactly one triage task is created And subsequent minimal-dataset events referencing the same deduplication key are merged into the existing task without creating duplicates And merge actions are logged with source attribution
Real-Time Queue Push and Notification
Given a triage task is created or reassigned due to routing evaluation When routing completes Then the task appears in the destination queue within 2 seconds And the assigned user or queue subscribers receive an in-app notification within 2 seconds and an email within 30 seconds And notification delivery success or failure is logged with correlation to the routing event And failed notifications are retried up to 3 times with exponential backoff
Confidence & Clarification Prompts
"As an adjuster, I want the system to ask me to confirm uncertain details so that the data is accurate without slowing me down."
Description

Implement confidence thresholds and ambiguity handling that trigger inline prompts when values are uncertain or conflicting. Provide concise confirmation choices (e.g., policy number A or B), dictate‑back confirmation, and quick correction via voice or tap. Unresolved items are clearly flagged and excluded from auto‑routing rules until confirmed, with a seamless fallback to manual entry.

Acceptance Criteria
Low-Confidence Inline Prompt for Required Field
Given Live Factline is transcribing a voice note and a candidate value for a required field (e.g., policy number) is extracted with confidence below the configured prompt threshold When the extraction event is emitted Then an inline clarification prompt appears within 500 ms showing the top 2–3 candidates and a "Manual entry" option And when the user confirms a candidate by tap or voice Then the structured field is set, marked confirmed, and the field’s live checkmark turns green within 300 ms And the unresolved flag and prompt are cleared for that field And the action is audit-logged with before/after value and confidence score
Conflict Prompt for Multiple Sources
Given two different candidate values are extracted for the same field from different sources (e.g., audio vs. photo OCR) and both exceed the candidate floor When the conflict is detected Then a prompt lists both values with their sources and confidence percentages, plus "None of these" and "Manual entry" And when the user selects one or says "Use first/second" Then the selected value is set and marked confirmed, the alternative is archived as rejected, and a "conflict_resolved" event is logged And if "None of these" is chosen, the field remains unresolved and flagged
Dictate-Back Confirmation Mid-Confidence
Given a field is extracted with confidence between the prompt threshold and the auto-confirm threshold When dictate-back is triggered Then the system reads back or displays the value and asks for "Confirm" or "Correct to <value>" And on "Confirm" (voice or tap) the field is marked confirmed and checkmarked within 300 ms And on "Correct to <value>" the system updates the field to the spoken/typed value, marks it confirmed, and displays the updated checkmark within 500 ms And if speech is not recognized after 2 attempts or the user says "I'll type", focus moves to manual entry input for that field
Exclude Unconfirmed Fields from Auto-Routing
Given one or more required fields are unresolved When auto-routing rules evaluate the intake Then the case is excluded from auto-routing and labeled with a "Needs confirmation" badge And triage tasks dependent on unresolved fields are not created And when all required fields are confirmed Then routing proceeds on the next evaluation cycle (<= 1 second) without page refresh
Prompt Dismissal Behavior and Re-prompt Strategy
Given a clarification prompt is shown for a field When the user dismisses the prompt without confirming a value Then the field remains unresolved with a visible red flag and no checkmark And the unresolved count increases in the outstanding items panel And the same prompt will not reappear for at least 60 seconds unless a higher-confidence candidate or a new candidate is extracted
Clarification Audit Trail and Telemetry
Given any clarification interaction occurs (prompt shown, confirmation, correction, manual entry, timeout) When the event completes Then an audit record is saved with timestamp, user id, session id, field name, old value, new value, confidence scores, source(s), and end-to-end latency And 99% of audit records persist within 2 seconds, with a missing-log rate below 0.1% And PII fields are masked in logs according to policy
Per-Field Confidence Threshold Configuration
Given an admin has set per-field values for auto-confirm threshold and prompt threshold (0.0–1.0, with prompt threshold <= auto-confirm) When a field is extracted with confidence >= auto-confirm threshold Then it is auto-confirmed without any prompt And when confidence is between prompt threshold (inclusive) and auto-confirm threshold (exclusive) Then dictate-back confirmation is used And when confidence < prompt threshold Then a candidate selection prompt is shown And threshold changes take effect for new extractions within 10 seconds of saving
Admin Rules & Required Fields
"As an operations admin, I want to configure required fields and routing rules so that Live Factline adapts to our lines of business and compliance needs."
Description

Offer an admin console to configure required fields by line of business and jurisdiction, define extraction patterns and synonyms, set validation thresholds, and author routing rules. Support versioned rule sets with effective dates, test mode with sample audio/transcripts, and export/import for change control. Changes propagate instantly to Live Factline without redeploying code.

Acceptance Criteria
Configure Required Fields by Line of Business and Jurisdiction
- Given I am an Admin in the Rules console, When I select Line of Business "Auto" and Jurisdiction "CA", Then I can add, remove, and order required fields including Policy Number, VIN, Loss Location, Parties, and Cause of Loss. - Given a required field set is saved and published for "Auto-CA", When a new Live Factline session starts with LOB=Auto and jurisdiction=CA, Then the session reflects the configured required fields and shows live completion indicators for each. - Given the required set includes "VIN", When Live Factline cannot extract a VIN or the extracted VIN fails validation, Then the field is flagged as Required-Missing and routing rules that depend on it do not execute. - Given field dependencies are configured (e.g., "Injury Details" required if "Injury Indicated" = true), When the dependency condition evaluates to true, Then the dependent field becomes required; otherwise it remains optional. - Given conflicting required field definitions exist across scopes, When both a global and jurisdiction-specific rule apply, Then the most specific scope overrides the broader one and the system logs the resolution.
Define Extraction Patterns and Synonyms
- Given I author a Policy Number pattern "POL-[0-9]{8}" and synonyms ["policy #","policy no.","policy number"], When test mode runs on a transcript containing "policy # POL-12345678", Then the Policy Number field is extracted as "POL-12345678" with the synonym recognized. - Given patterns include capture groups and normalization, When extraction occurs, Then the stored value is normalized using configured rules (e.g., strip spaces, uppercase) and the raw match is retained in metadata. - Given multiple patterns could match the same field, When extraction runs, Then the highest-scoring match is selected and other candidates are stored as alternates with scores. - Given a synonym maps to multiple fields, When ambiguity occurs, Then the engine applies disambiguation priority as configured and logs the resolution; if unresolved, it flags for manual review in test mode.
Set Validation Confidence Thresholds
- Given I set Policy Number confidence threshold to 0.92 and VIN to 0.95, When extraction scores are below their thresholds, Then the fields remain Unverified and do not earn a required-field checkmark in Live Factline. - Given an extraction score meets or exceeds the threshold, When the field value is set, Then the field is marked Verified and the checkmark displays in Live Factline in under 1 second. - Given multiple candidates exceed threshold, When tie-breaking is needed, Then the engine selects the candidate with the highest score; on equal scores it applies recency in transcript as tie-breaker. - Given thresholds are updated and published, When a new session begins, Then the new thresholds are applied without requiring application redeploy.
Author Routing Rules by Conditions
- Given I create a routing rule "If LOB=Auto AND Jurisdiction=CA AND text contains 'injury' OR InjuryScore >= 0.7 Then create task 'Bodily Injury Triage' priority High and assign queue 'BI-CA'", When a transcript meets these conditions, Then the task is created with the configured attributes and appears in the target queue. - Given a routing rule references a required field that is missing or Unverified, When evaluation runs, Then the rule is skipped or delayed per configuration and an audit log entry explains the reason. - Given rule execution order is configured, When multiple rules could fire, Then they execute in the specified order and respect stop/continue behaviors. - Given I disable a rule and publish, When new sessions start, Then the rule no longer fires and the change is recorded in the audit log.
Versioned Rule Sets with Effective Dates and Preview
- Given rule set v1 is active and I create v2 with Effective From 2025-10-15T00:00:00Z, When I preview using a time-travel selector set to 2025-10-16, Then the engine evaluates test inputs against v2 and shows differences from v1. - Given v2 is published with a future effective date, When the current time is before the Effective From, Then v1 continues to serve production sessions and v2 remains scheduled. - Given the Effective From time is reached, When a new Live Factline session starts, Then v2 is applied within 5 seconds without code redeploy and an audit event records the activation. - Given a session started before activation, When it continues after activation, Then it remains pinned to its start-version to avoid mid-session rule changes.
Test Mode with Sample Audio/Transcripts
- Given I upload sample audio and/or paste a transcript in test mode, When I run the test against a selected rule set version, Then the system displays extracted fields, per-field scores vs thresholds, required-field status, and routing rule outcomes. - Given I run the same test against multiple versions (v1 vs v2), When I view results, Then the system highlights differences in extractions, verifications, and routing decisions. - Given test mode is used, When tests are executed, Then they do not impact production sessions, queues, or tasks, and results are retained in a test log with timestamps and the executing user. - Given a test case is saved, When another admin loads it, Then inputs and expected assertions can be re-run and pass/fail status is indicated.
Export/Import for Change Control
- Given I click Export for a rule set version, When the file is generated, Then it downloads as signed JSON including version metadata, effective dates, checksums, and a ruleset ID. - Given I import a ruleset file, When validation runs, Then the system verifies schema, signatures, and referential integrity; on success it creates a new draft version; on failure it blocks import and lists errors. - Given a draft created via import, When I preview and publish it, Then the audit log records who imported, who published, timestamps, and an optional change reason. - Given I need to roll back, When I select a prior version and publish it with immediate effect, Then it becomes active within 5 seconds and the change is logged.

Gap Coach

Guides adjusters mid‑note with subtle prompts when essential details are missing based on claim type, carrier rules, and SLA requirements. Offers one‑tap scripts (e.g., “Please confirm policy number and contact phone”) and logs completions automatically. Reduces follow‑ups, boosts first‑pass completeness, and standardizes notes across teams.

Requirements

Real-time Note Parsing & Gap Detection
"As a claims adjuster, I want real-time guidance while writing notes so that I capture all required details the first time and avoid follow-ups."
Description

Perform low-latency, on-the-fly NLP analysis of in-progress notes (typing or dictation) to detect missing required details based on claim type, carrier rules, jurisdiction, and SLA checklists, and surface context-aware inline prompts with confidence thresholds. Support multi-channel inputs (free-text notes, voice transcripts, photo captions, and message threads) and maintain sub-200 ms p95 prompt latency with graceful degradation offline by queuing checks. Integrate with ClaimFlow’s claim schema, existing rules engine, and event bus to synchronize detected gaps as structured fields and emit events for downstream automation.

Acceptance Criteria
Inline Prompting While Typing — p95 <200 ms
Given an adjuster is actively entering text in the claim note editor with network connectivity and a claim context (type, carrier, jurisdiction, SLA) loaded When the system detects a missing required detail Then an inline prompt is rendered within 200 ms at p95 and within 350 ms at p99, measured over a rolling window of at least 1,000 prompt events per environment And the prompt references the specific missing field (by schema field label) and offers a one-tap script when available for that field And new prompts are rate-limited to a maximum of one new prompt every 2 seconds per user to avoid flicker
Confidence-Thresholded Prompting
Given a detection score is below the configured rule threshold When evaluating whether to show a prompt Then the prompt is suppressed and a suppression audit record is written with rule_id, score, threshold, and timestamp Given a detection score is equal to or above the configured rule threshold When evaluating whether to show a prompt Then the prompt is displayed and includes the reason (rule label) and a confidence category derived from score bands And when content changes cause the score to cross the threshold Then the prompt is shown or withdrawn within 100 ms of the score change And the system does not show duplicate prompts for the same field and rule within a session unless the prior prompt was resolved or dismissed
Multi-Channel Input Aggregation and Gap Detection
Given the claim has inputs from free-text notes, streaming voice transcripts, photo captions, and message threads within the current session When new content arrives on any channel Then it is processed and added to the analysis context within 300 ms at p95 And if the required detail is present in any channel Then no prompt for that field is displayed And streaming voice partial hypotheses do not trigger prompt resolution; only finalized transcript segments can resolve or dismiss a gap And detected gaps consider all channels in aggregate so that providing a detail in any channel suppresses the corresponding prompt within 200 ms at p95
Offline Degradation with Queued Checks and Retry
Given the device loses connectivity or the NLP/rules services are unavailable When the user continues typing Then checks are enqueued locally and a non-blocking offline indicator is shown within 100 ms And the queue persists across app restarts and preserves FIFO order for at least 500 pending items When connectivity is restored Then queued checks are replayed and corresponding prompts are delivered within 2 seconds at p95, and the offline indicator is cleared And if a queued check becomes obsolete due to subsequent content changes Then it is dropped with an audit record noting the drop reason and superseding content hash
Rules-Driven Detection Mapped to Claim Schema
Given a claim context with type, carrier, jurisdiction, and SLA checklist available When a gap is detected Then the applied rule_id and rule_version are recorded and the gap maps to a ClaimFlow schema field_id and path And 100% of emitted gaps include field_id, rule_id, confidence_score, and source_channel in structured storage And when the mapped field becomes populated by user input or integration Then the corresponding gap state transitions to resolved automatically within 200 ms at p95
Gap Events Emitted on Event Bus
Given a gap is created, updated, resolved, or dismissed When the gap state changes Then an event is published on the event bus within 150 ms at p95 with payload containing event_type, claim_id, field_id, rule_id, confidence_score, state, actor_id (if any), source_channel, and ISO 8601 timestamp And events are delivered at-least-once with an idempotency key for de-duplication by consumers And if publishing fails Then the system retries with exponential backoff up to 5 attempts and moves the message to a dead-letter topic on final failure
Prompt Action Logging and Dismissal Handling
Given a prompt is shown When the user taps a one-tap script Then the script text is inserted into the note at the cursor position and the gap transitions to pending verification until the required detail is present, after which it is resolved automatically When the user provides the missing detail in any channel Then the completion is logged automatically with claim_id, field_id, actor_id, method=auto, and timestamp When the user dismisses a prompt as Not Applicable or Known Deferred Then a reason selection is required and the gap state becomes dismissed, and it does not reappear unless claim context changes make the rule applicable again And if content changes remove a previously provided value Then the associated gap reopens within 200 ms at p95
One-tap Script Suggestions
"As a claims adjuster, I want one-tap suggested scripts for missing details so that I can ask for the right information quickly and consistently."
Description

Offer curated, carrier- and claim-type-specific one-tap scripts for common missing items (e.g., policy number, contact phone, loss location) that can be inserted into notes or outbound messages with a single action. Support token substitution (claim ID, policyholder name), localization, and accessibility, and allow team-level curation with versioned templates. Track script performance to rank most effective prompts and ensure consistent, compliant language across teams.

Acceptance Criteria
Targeted Script Suggestions Based on Carrier and Claim Type
Given an adjuster is composing a claim note for carrier Y with claim type T and required details (e.g., policy number, contact phone, loss location) are missing per rules When the system detects one or more missing details Then display up to 3 relevant one‑tap scripts mapped to carrier Y and claim type T within 300 ms of keystroke And do not display scripts not mapped to carrier Y or claim type T And remove a suggestion immediately when its corresponding detail is captured in the note or claim record And show a short reason tag indicating the detected gap (e.g., "Missing: Policy Number")
One‑Tap Insertion into Notes and Outbound Messages
Given targeted suggestions are visible in the editor When the user selects a script via click, tap, or Enter Then the fully rendered text inserts at the current cursor location in the note editor in under 100 ms And an Undo action is available for at least 5 seconds to revert the insertion And insertion is idempotent (a single selection inserts a single instance) And the user can choose Send via channel submenu (SMS, email, in‑app) to insert into the selected outbound composer with a single action
Token Substitution with Fallbacks and Preview
Given a template that includes tokens such as {claim_id}, {policyholder_first_name}, {adjuster_name}, {loss_date:MMM d, yyyy} When the script is previewed or inserted Then all tokens resolve from the active claim context using specified formats and time zone And unresolved optional tokens are replaced by configured fallbacks (e.g., {policyholder_first_name} → "Policyholder") and visibly flagged in preview And if a required token lacks a value and no fallback exists, block insertion and display an actionable error within 100 ms And token rendering respects locale-specific formats for dates and names
Localization and Language Routing
Given the user's UI locale is L and the policyholder's preferred language is P When a suggestion is displayed Then the suggestion label and preview appear in locale L And when inserted for outbound to the policyholder, the script content uses language P if a P translation exists; otherwise it falls back to English with an "EN" badge And right‑to‑left languages render correctly (text direction, cursor behavior, punctuation) And phone numbers, dates, and currency inside tokens format per the active locale And ≥95% of published templates for a team have translations for all configured locales
Accessibility and Keyboard‑Only Operation
Given a keyboard‑only or screen reader user is interacting with suggestions When suggestions appear Then all suggestion items are reachable via Tab/Shift+Tab with visible focus indicators And items are announced with appropriate ARIA roles and names including gap type and the first 50 characters And actions are operable via Enter/Escape/Arrow keys without a mouse And color contrast for text and controls is ≥ 4.5:1 and touch targets are ≥ 44×44 px And automated accessibility checks (axe‑core) report 0 critical violations for suggestion and insertion flows
Team Curation and Versioned Templates with Compliance Locks
Given a team admin with Template Manager role is managing templates When creating or editing a template Then they can set target carriers, claim types, locales, channels, and an allowed token list, and define compliance‑locked segments And upon Publish, a new semantic version (MAJOR.MINOR.PATCH) is assigned with changelog and approver recorded And published changes propagate to end users within 5 minutes And rollback to any prior version is possible with full audit trail And non‑admin users cannot edit locked segments or publish templates And template visibility is scoped to the team with optional carrier‑specific overrides
Performance Tracking, Ranking, and Auto‑Logging
Given scripts are being suggested and used across claims When a script is shown, inserted, sent, and the missing field is subsequently completed Then the system records impression, insertion, send, response, and completion events with timestamps within ≤5 seconds And computes an effectiveness score daily per carrier/claim type: 50% weight completion within 24h, 30% response within 24h, 20% insertion rate And ranks scripts accordingly, surfacing the top 3 by default in suggestions And a dashboard exposes metrics filterable by date range, carrier, claim type, and team, with CSV and API export that excludes PII And all usage events are appended to the claim audit log including user, script version, channel, and outcome
Rule & SLA Configuration Console
"As an operations admin, I want to configure required fields and SLAs by carrier and claim type so that Gap Coach prompts align with our rules and compliance needs."
Description

Provide an admin UI to define, prioritize, and version required data elements per carrier, line of business, jurisdiction, and claim phase, with effective dates and exceptions. Map rules to prompt templates and severity (blocking vs. advisory), simulate outcomes on sample claims, and publish changes safely. Enforce RBAC, audit every change, and integrate with the existing ClaimFlow rules engine to avoid duplicating logic.

Acceptance Criteria
Define and prioritize multi‑dimension rules with effective dates and exceptions
Given a Rules Admin is creating a rule with required data elements and context (carrier, line of business, jurisdiction, claim phase) When they enter a start date (and optional end date), set a numeric priority, and add zero or more exceptions based on additional attributes Then the rule saves with a unique ID, required fields validated, end date >= start date, and is associated to the specified context. Given overlapping rules exist for the same required element and context When the system resolves applicability Then the rule with higher numeric priority applies; if priorities tie, the rule with more specific context applies; if still tied, the most recently Published version applies. Given a rule would duplicate an identical active rule (same required element, same context, same date range) When attempting to save Then the system blocks the save with a descriptive error listing the conflicting rule IDs. Given a date range is expired or not yet effective When retrieving effective rules for a claim context at a timestamp Then only rules active at that timestamp are returned.
Map rules to prompt templates and severity (blocking vs advisory)
Given a rule exists When a Rules Admin maps one or more prompt templates (with locale codes) and selects a severity of Blocking or Advisory Then the mapping saves and each template passes variable interpolation validation (all placeholders resolve to available claim fields). Given a rule has severity Blocking When a simulation or evaluation is performed Then the output marks the prompt as blocking; for Advisory, the output marks it as advisory. Given a template is missing for the default locale When attempting to publish Then the system blocks publishing and lists the missing locale(s).
Versioning, publish scheduling, and rollback workflow
Given a ruleset is in Draft When a Rules Admin submits it for Review and a Reviewer approves Then the state becomes Ready to Publish and all items are immutable until published or sent back to Draft with comments. Given a ruleset is Ready to Publish When a Publisher schedules an effective start timestamp (with timezone) and confirms Then a Published version is created that becomes active at that timestamp and only one active version per scope (carrier + line of business + jurisdiction + claim phase) is allowed. Given a Published version is active When a rollback is initiated to a prior Published version with a reason Then the prior version is re-published with a new effective timestamp, the current version is superseded, and both events are recorded in the audit trail. Given an attempt is made to edit a Published version When saving Then the system blocks the edit and offers “Create New Version” that clones to Draft.
Simulate rules on sample claims across versions
Given a Draft ruleset and a set of sample claims (uploaded or selected by ID) When the user runs a simulation Then the system returns for each claim: the list of missing required elements, associated prompt templates, severity, triggering rule IDs, and a summary count of Blocking vs Advisory. Given both Current Production and Draft versions exist When a differential simulation is run Then the output highlights adds/removes/changes in prompts and severities per claim and provides a downloadable CSV. Given invalid sample claim data is provided When the simulation runs Then the system reports validation errors per claim without blocking valid claims from running.
RBAC enforcement for configuration console and APIs
Given roles System Admin, Rules Admin, Reviewer, Publisher, and Viewer When each role accesses features Then permissions are enforced as follows: System Admin (all), Rules Admin (create/edit rules and run simulations), Reviewer (approve/reject), Publisher (schedule/publish/rollback), Viewer (read-only). Given an unauthorized user attempts a restricted action When the action is invoked via UI or API Then the system returns 403 Forbidden with an error code, no data is changed, and the attempt is logged in the audit trail. Given a user session is established When the UI renders Then only features available to the role are visible and actionable; hidden actions cannot be reached via direct URL.
Audit trail for all rule changes
Given any create/update/delete, state transition, publish, rollback, or simulation action When the action completes Then an immutable audit entry is recorded containing actor ID, timestamp (UTC), action type, entity IDs, before/after diffs, reason/comment (if provided), and source (UI/API). Given an auditor queries the audit log When filtering by date range, actor, carrier, ruleset ID, or action type Then matching entries are returned sortable and exportable to CSV. Given an attempt is made to alter or delete an audit entry When performed by any role Then the system blocks the action and records the attempted tamper in the audit log.
Integration with existing ClaimFlow rules engine (no logic duplication)
Given a ruleset is Published When the publish job completes Then the existing ClaimFlow rules engine is updated via its configuration API, and a version hash and engine config ID are stored with the ruleset. Given the simulation feature runs When evaluating rules Then it invokes the same rules engine evaluation API used at runtime and returns identical results for a reference set of claims as a direct engine call. Given the rules engine API is unavailable at publish time When a publish is attempted Then the system aborts publishing, reverts to the prior state, surfaces a clear error, and records the failure in the audit trail.
Auto-Completion Logging & Audit Trail
"As a compliance officer, I want a complete audit trail of prompts and their outcomes so that we can demonstrate adherence to carrier rules and SLAs."
Description

Automatically record every prompt event (shown, accepted, edited, dismissed, resolved) with timestamp, user, claim ID, prompt ID, and resulting data captured. Write outcomes back to the claim record as structured tags and note annotations, expose an audit view for compliance, and provide export to the data warehouse. Support configurable retention and privacy controls for PII with encrypted storage and access logging.

Acceptance Criteria
Prompt Event Lifecycle Logging
- Given a Gap Coach prompt is shown within a claim, When the prompt is displayed to the user, Then an event with type "shown" is recorded with timestamp (UTC ISO 8601 with ms), user_id, claim_id, and prompt_id. - Given a user accepts a prompt, When acceptance occurs, Then an event with type "accepted" is recorded with the same identifiers and resulting_data_captured stored as structured JSON. - Given a user edits a prompt response or one‑tap script, When the edit is saved, Then an event with type "edited" is recorded including a before/after diff of resulting_data_captured. - Given a user dismisses a prompt, When dismissal occurs, Then an event with type "dismissed" is recorded and includes an optional reason if provided. - Given a prompt’s required details are completed, When the prompt is resolved, Then an event with type "resolved" is recorded. - Given transient storage failure, When an event write fails, Then the system retries until success and persists the event within 60 seconds without creating duplicate records (idempotent by event key). - Given high‑volume logging at ≥100 events/second per tenant, When events are written, Then p50 write latency ≤200 ms and p99 ≤1 s.
Write Outcomes to Claim Record as Structured Data and Note Annotations
- Given a prompt outcome of type accepted or resolved with resulting_data_captured, When write‑back occurs, Then structured tags are created/updated on the claim record to mirror each data field and value. - Given write‑back occurs, When the claim note is updated, Then a note annotation is appended containing prompt_id, event_type, user_id, and timestamp, and is viewable in the claim timeline. - Given a subsequent edit to the same prompt outcome, When changes are saved, Then tags are updated in place and a new annotation is added, preserving prior values in the audit log. - Given duplicate acceptance events, When processed, Then tags and annotations remain idempotent (no duplicate tags/notes; latest value retained). - Given UI and API consumers, When they query the claim record, Then updated tags and the latest annotation are visible within 1 second of the event p95.
Audit View for Compliance
- Given a user with the ComplianceViewer role, When they open the Audit Trail for a claim, Then all related prompt events are listed chronologically with columns event_type, timestamp, user_id, prompt_id, and a flag indicating presence of resulting_data_captured. - Given filter inputs (date range, user_id, prompt_id), When filters are applied, Then the grid updates correctly within 2 seconds p95 and reflects only matching events. - Given an event row is selected, When details are opened, Then the full event payload is viewable subject to PII masking rules and role permissions. - Given a user without Audit access, When they request the Audit Trail, Then access is denied with a 403 and the attempt is access‑logged. - Given the Export action, When the user exports from the Audit View, Then a CSV containing the visible (filtered) events is generated and downloaded, respecting PII masking settings.
Data Warehouse Export
- Given new events exist, When the scheduled export runs hourly or an on‑demand export is triggered, Then all events since the last successful watermark are delivered to the configured warehouse destination with fields: event_type, timestamp, user_id, claim_id, prompt_id, resulting_data_captured. - Given a completed export window, When reconciliation runs, Then row count parity between source and destination for that window is 100% within 1 hour; otherwise an alert is raised and retry/backfill occurs automatically. - Given a backfill request for a historical date range, When executed, Then all events in range are exported exactly once (no duplicates) and watermarks advance correctly. - Given PII export policy configuration, When exporting, Then PII fields are included only when the destination is authorized for PII; otherwise those fields are redacted or omitted consistently.
Configurable Retention and Legal Holds
- Given a tenant‑level retention policy in days, When events exceed the configured retention period, Then the system purges or anonymizes those events per policy and creates a deletion audit log entry. - Given a legal hold is applied to a tenant, claim, or prompt_id, When retention would otherwise purge events, Then those events are retained until the legal hold is cleared. - Given a retention policy change, When a stricter policy is saved, Then subsequent purge cycles honor the new policy and do not resurrect previously deleted data. - Given routine purge execution, When the purge job runs, Then it processes at least 10,000 events per minute without referential integrity violations or partial deletes.
PII Encryption, Masking, and Access Logging
- Given fields labeled as PII in resulting_data_captured or note annotations, When stored, Then they are encrypted at rest and transmitted only over TLS 1.2+. - Given a user without PII permission, When viewing the Audit View or claim annotations, Then PII values are masked (e.g., last 4 only) while non‑PII remains fully visible. - Given any successful or failed read of PII, When it occurs, Then an immutable access log entry is created with user_id, timestamp, claim_id, action, and purpose code, retained per policy. - Given cryptographic key rotation, When keys are rotated, Then previously stored PII remains decryptable by authorized services with zero data loss and rotation is recorded in system audit logs. - Given a data subject erasure request, When executed, Then PII fields within events and annotations are purged or irreversibly anonymized within 30 days while preserving non‑PII audit context.
Prompt Throttling & User Controls
"As a claims adjuster, I want controls that minimize distracting prompts so that I can stay focused while still getting help when it matters."
Description

Reduce noise by batching related suggestions, suppressing duplicates, and rate-limiting prompts within a session based on context and user behavior. Provide user controls to snooze, mute, or mark prompts as not applicable with a reason, and learn from these signals to refine future suggestions. Ensure prompts are keyboard-first, non-blocking, and never obstruct text entry or screen readers.

Acceptance Criteria
Batch related suggestions within 5 seconds into a single prompt
Given three or more suggestion triggers occur within a 5-second window for the same claim and note context, When Gap Coach generates prompts, Then exactly one batch prompt card is displayed with a badge showing the total count, And the card groups suggestions by category (e.g., policy, contact, coverage), And no additional standalone prompt cards are shown for those triggers, And a single notification is emitted, And telemetry records a batch_id with item_count equal to the number of triggers.
Suppress duplicate prompts in-session using context hash
Given a prompt with normalized_key K and context_hash H has been shown in the current user session, When a prompt with the same normalized_key K and context_hash H would fire again, Then it is suppressed and not shown again in this session, And the suppression is logged with reason "duplicate_in_session", And if the context_hash changes, Then the prompt may be shown once with an "updated" badge.
Adaptive rate-limiting based on user engagement
Given Gap Coach is active in a note-taking session, When prompts are eligible to be shown, Then no more than one prompt (or batch card) is shown every 30 seconds (baseline), And no more than five prompts total are shown in any rolling 15-minute window, And if the user dismisses or ignores two prompts consecutively, Then the interval increases to 90 seconds until a prompt is accepted, And if the user manually opens the suggestions panel, Then the next eligible prompt may bypass the interval once, And prompts older than 2 minutes are dropped or merged into the next batch.
User controls: snooze, mute, and not applicable with reason
Given a prompt card is focused, When the user selects Snooze, Then they can choose 5 minutes, end of session, or until claim stage changes, And the prompt does not reappear until the selected snooze condition is met. Given the user selects Mute, Then the user can choose scope: this claim or this claim type for this user, And prompts with the same normalized_key do not appear within the selected scope thereafter. Given the user selects Not Applicable, Then a required reason must be captured from a controlled list with optional free-text (min 5 chars), And the prompt is dismissed and recorded with reason. For all actions, Then events are logged with user_id, claim_id, normalized_key, action, scope_or_reason, and timestamp.
Keyboard-first, non-blocking prompt experience
Given the adjuster is typing in the note field, When a prompt is generated, Then focus remains in the note field and no modal is shown, And the prompt appears in a side panel or inline area that does not overlap the text caret region, And 95th percentile keystroke-to-render latency remains under 50 ms with prompts active, And the following shortcuts work: Ctrl+Shift+S (Snooze), Ctrl+Shift+M (Mute), Ctrl+Shift+N (Not Applicable), Ctrl+Shift+P (Open prompts panel), And pressing Esc dismisses the active prompt card without affecting the note content, And tab order proceeds Note Field -> Latest Prompt Card -> Prompt Actions in logical sequence.
Accessibility: screen reader compatible and unobstructed text entry
Given a prompt is generated, When a screen reader is active (NVDA or JAWS on Windows, VoiceOver on macOS), Then the prompt is announced via an ARIA live region with politeness "polite" without stealing focus, And all controls expose accessible names, roles, and states, And color contrast for text and interactive elements is at least 4.5:1, And all actions are operable via keyboard only, And no prompt overlaps or obstructs the note entry region at 1280x800 and 1920x1080 resolutions, And automated accessibility audits (axe-core) report zero critical violations on the prompts UI.
Learning from feedback signals to refine future suggestions
Given a user marks a prompt with normalized_key K as Not Applicable with reason R three times across separate sessions for the same claim type, When the user starts subsequent sessions for that claim type, Then the display frequency of prompts with key K is reduced by at least 80% for that user over the next five sessions, And if a prompt is muted for a claim, Then prompts with key K do not reappear for that claim in any session, And nightly model updates incorporate snooze/mute/NA signals into suppression rules, And an audit report is available per user and claim type showing pre/post display rates and the effective date of rule updates.
Workflow Handoff for Unresolved Gaps
"As a claims manager, I want unresolved gaps to generate actionable tasks so that no claim progresses without critical information."
Description

When notes are finalized with unresolved blocking gaps, automatically create tasks in ClaimFlow workflows with assignees, due dates, and SLA timers, and attach the most relevant scripts for outreach. Prevent stage advancement when required details are missing (based on rule severity), notify stakeholders, and expose APIs/webhooks for downstream systems to consume unresolved gap lists.

Acceptance Criteria
Auto-create workflow tasks for unresolved blocking gaps on note finalization
Given a claim note is finalized and at least one gap with severity=Blocking remains unresolved When the note is saved as Final Then the system creates one workflow task per unresolved blocking gap within the claim’s active workflow And each task includes: gap ID, gap type, gap description, required fields, originating note ID, claim ID, and rule severity And duplicate tasks for the same active unresolved gap are not created on subsequent note edits; existing open tasks are referenced And task creation occurs within 2 seconds of finalization And an audit log entry is recorded with timestamp, actor, and created task IDs
Assign task owners and due dates based on carrier rules and claim attributes
Given routing rules configured by carrier and claim attributes (LOB, state, complexity, queue) When tasks are created for unresolved gaps Then the system assigns an owner per routing rule, or assigns to a default queue if no match And the due date is calculated from rule-defined SLA (e.g., 24 business hours) using the claim’s timezone and business calendar And tasks display owner, due date, and priority computed from severity and SLA proximity And if the assigned owner is marked unavailable (OOO), assign to the rule-defined backup; otherwise place in the target queue and notify queue members And changes to routing rules affect subsequent task creations without altering existing tasks unless a manual re-evaluation action is triggered
Start and track SLA timers for unresolved gap tasks
Given a task is created for an unresolved blocking gap When the task is created Then an SLA timer starts with duration defined by the applicable rule And the timer pauses when task status is set to Waiting on Insured/Third Party and resumes when moved back to In Progress And remaining time and predicted breach timestamp are displayed on the task and claim header And a warning event is emitted at 75% elapsed and an escalation to the supervisor is sent at breach And SLA outcomes (met/missed), total elapsed work time, and total pause time are recorded for reporting
Block stage advancement when required details are missing per severity rules
Given a claim is in a stage that requires all blocking gaps to be resolved And one or more unresolved gaps have severity=Blocking When a user attempts to advance the claim to the next stage Then the system blocks advancement and displays a list of blocking gaps with the required fields to resolve each And the Advance action remains disabled until all blocking gaps are resolved or downgraded by rule update And users with role=Admin may perform a one-time override with a mandatory reason; the override is captured in the audit log and flagged in SLA reports And gaps with severity=Non-Blocking do not prevent advancement
Attach most relevant outreach scripts to created tasks
Given a task is created for an unresolved gap When selecting scripts for the task Then the system attaches the top 1–3 scripts ranked by relevance to the gap type, claim type, and carrier preferences And scripts provide one-tap text/email/call prompts with placeholders (e.g., policy number, contact phone) auto-filled from claim data And sending a script logs the outreach on the task with timestamp, channel, recipient, and template ID And users may choose an alternative recommended script; the selected script ID is recorded
Notify stakeholders upon creation and updates of unresolved gap tasks
Given notification rules per carrier/team are configured When unresolved gap tasks are created, reassigned, nearing SLA breach (≥75% elapsed), breached, or resolved Then the system sends notifications to stakeholders via configured channels (in-app, email, Slack/MS Teams) And notifications are deduplicated per task-recipient within a rolling 10-minute window And each notification contains claim ID, gap summary, assignee, due date/SLA status, and a deep link to the task And delivery outcomes are logged; failures retry with exponential backoff up to 3 attempts
Expose APIs and webhooks for unresolved gap lists to downstream systems
Given authenticated partners with OAuth 2.0 client credentials When calling GET /claims/{id}/gaps?status=unresolved or GET /gaps?severity=blocking&carrierId={cid} Then the API returns paginated results within 500 ms p95 including gap IDs, severity, required fields, linked task IDs, assignee, due date, and SLA status And webhooks fire on gap task created, updated, resolved, and SLA breached events, delivering JSON payloads with event type, claim ID, gap IDs, and task metadata And webhooks use HMAC-signed headers, 10-second timeout, and retries with exponential backoff up to 5 times; failed deliveries are recorded to a dead-letter queue And APIs enforce tenant-scoped RBAC; unauthorized calls receive 403; rate limits of 100 rpm per client return 429 on exceed
Insights & Continuous Improvement Loop
"As an operations leader, I want visibility into prompt effectiveness and completeness metrics so that we can optimize rules and reduce rework over time."
Description

Provide analytics on first-pass completeness, prompt acceptance/ignore rates, time saved, unresolved gap frequency by carrier/LOB, and rule effectiveness. Enable A/B testing of prompt variants, collect structured feedback from users, and feed labeled examples into the model training pipeline to improve detection accuracy. Surface recommendations to retire low-value prompts and elevate high-impact ones.

Acceptance Criteria
First-Pass Completeness Analytics
Given a user with Analytics access selects a date range and filters (carrier, LOB, claim type, adjuster) When they open the Insights dashboard Then the First-Pass Completeness (FPC) rate is shown as numerator/denominator and percentage, computed as notes with zero unresolved gaps at submission divided by total notes in scope And FPC values match a validated offline calculation for the same scope within <=1.0% absolute difference And clicking the FPC widget reveals daily trend, a drill-down list of underlying notes, and a CSV export with claim_id, note_id, carrier, LOB, adjuster, submission_timestamp, unresolved_gap_count And metrics are updated at least every 2 hours; data freshness timestamp is displayed And p95 dashboard load time for the last 30 days scope is <=2.5 seconds
Prompt Acceptance/Ignore Metrics
Given event tracking is enabled When viewing Prompt Engagement for a selected prompt and scope Then acceptance rate, ignore rate, and dismiss rate are displayed with counts and percentages And metrics are segmented by carrier, LOB, claim type, and adjuster and respond to filters And events are deduplicated per prompt per note session and captured within 5 minutes of occurrence And end-to-end event capture success rate is >=99.5% over the selected period, with gaps flagged And users can export a CSV with prompt_id, variant_id, claim_id, note_id, user_id, event_type, timestamp
Time Saved Reporting
Given a baseline cohort configuration is set (e.g., no-prompt sessions over a prior 30-day window) When comparing assisted vs baseline for a selected scope Then median and p95 time saved per note (seconds) and per claim are displayed with sample sizes And a methodology tooltip describes the calculation method and baseline period used And results exclude the top/bottom 1% duration outliers And displayed medians match an offline recomputation within <=1.0% relative difference And a CSV export includes scope filters, sample sizes, median, p95, method, and baseline definition
Unresolved Gap Frequency by Carrier/LOB
Given a user selects a date range When viewing the Unresolved Gap Frequency report Then a table shows, for each carrier and LOB, the percentage and count of notes submitted with >=1 unresolved gap And rows can be sorted by percentage or count and filtered by claim type and adjuster And clicking a row shows the most common unresolved gap categories with counts And CSV export includes carrier, LOB, note_count, unresolved_gap_count, unresolved_gap_rate
Rule Effectiveness & Recommendations
Given rules/prompts generate suggestions during note-taking When viewing Rule Effectiveness Then each rule displays trigger rate, acceptance rate, lift in FPC versus unexposed cohort, and confidence intervals where N>=100 And rules with acceptance rate <10% over the last 30 days and FPC lift <0.5 percentage points are flagged with a Retire recommendation And rules with acceptance rate >=40% and FPC lift >=1.5 percentage points are flagged with an Elevate recommendation And clicking Apply Recommendation requires confirmation and records an audit entry with actor, timestamp, previous state, new state, and reason And a rollback option restores the prior configuration with a separate audit entry
A/B Testing of Prompt Variants
Given two or more prompt variants are configured When a test is started Then assignment is deterministic by claim_id with a 50/50 split ±2% and persists across a claim And the platform computes outcome metrics (acceptance rate, FPC lift, time saved) per variant and a two-sided significance test; tests with p<0.05 and N>=500 per arm are marked Significant And a winner can be promoted with one click, automatically pausing losing variants and recording an audit log And users can download a CSV of assignment and outcomes at the note level
Structured Feedback & Training Pipeline
Given a prompt is shown When the adjuster optionally rates usefulness (1–5) and selects a reason code or enters a comment Then the feedback is saved with prompt_id, variant_id, claim_id, note_id, user_id, timestamp And a Feedback report shows response rate, average rating, and top reason codes by scope, and is exportable to CSV And labeled examples from accepted/ignored prompts and feedback are queued daily into the model training pipeline with schema validation and PII scrubbing; failures are surfaced with error details And each training run records model version, dataset snapshot ID, number of examples, and validation metrics, visible in an audit trail

Hazard Sentinel

Detects safety risks mentioned in the recording—like downed lines, gas odors, standing water, biohazards, or structural instability—and time‑stamps each mention. Auto-generates a safety checklist and alerts the user with prioritized do/don’t guidance before they proceed. Improves field safety, documents duty‑of‑care, and provides auditable risk flags for QA and compliance.

Requirements

Hazard NLP Extraction
"As a field adjuster, I want the system to automatically detect safety hazards mentioned in my recording so that I’m warned about risks without manual review."
Description

Automatically transcribes user recordings and analyzes the transcript to detect safety hazards (e.g., downed power lines, gas odors, standing water, biohazards, structural instability). Uses a domain-tuned NLP model with synonym handling and confidence scoring to classify hazard type and severity. Outputs normalized hazard events into ClaimFlow’s data model for downstream modules (checklist generation, guidance, workflow gating). Processes securely with encryption, queues offline captures for later processing, and exposes detections via internal APIs for UI and workflow integration.

Acceptance Criteria
Online Recording: Hazard Detection and Timestamping
Given a user uploads a recording up to 10 minutes with network connectivity When transcription and NLP processing is initiated Then processing completes in ≤ 2x audio duration at p95 and ≤ 3x at p99 And each hazard mention is detected and time-stamped within ±1.0 second of its spoken position And detected hazards are limited to {downed power lines, gas odors, standing water, biohazards, structural instability} And each detected mention is associated to a normalized hazard event including {hazard_type, severity, confidence, mention_timestamp, mention_text} And no more than 1 false-positive hazard event is produced per 10 minutes of non-hazard speech in a clean-audio test set
Offline Capture: Queue and Retry Processing
Given the device is offline at the time of recording upload When the user saves the recording in ClaimFlow Then the recording is queued with status "Pending Sync" and an immutable checksum And the queued recording is encrypted at rest And sync retries with exponential backoff until connectivity is restored or a max delay of 24 hours is reached And upon connectivity restoration, the recording is transmitted and processed automatically without user action And at-most-once processing is guaranteed per checksum (no duplicate jobs created) And user-visible status transitions are available via internal API (Queued → Syncing → Processing → Complete/Failed)
Synonym Handling and Hazard Normalization
Given a transcript containing synonyms or colloquialisms for supported hazards (e.g., "downed wire", "sparking line", "smells like gas", "ankle-deep water", "sewage", "mold", "structure is shaky") When the NLP model processes the transcript Then each synonym maps to the correct canonical hazard_type in the ClaimFlow taxonomy {DOWNED_POWER_LINES, GAS_ODOR, STANDING_WATER, BIOHAZARD, STRUCTURAL_INSTABILITY} And on a curated synonym evaluation set (≥ 200 utterances per hazard), mapping accuracy ≥ 95% overall and ≥ 90% per hazard And non-hazard mentions yield no hazard event when confidence < T (default T=0.6)
Confidence Scoring and Severity Classification
Given labeled validation data for the five supported hazard types with severity annotations When the model is evaluated at threshold T = 0.6 Then hazard-type macro F1-score ≥ 0.85 and per-hazard F1 ≥ 0.80 And severity classification macro accuracy ≥ 0.80 And each hazard event includes confidence ∈ [0,1] with ≥ 2 decimal precision and severity ∈ {Low, Moderate, High, Critical} And events with confidence < 0.6 are flagged need_review = true and are excluded from default downstream gating and checklist generation
Internal API: Hazard Event Exposure
Given an authenticated internal client with service token scope "hazards:read" When it calls GET /internal/hazards?claim_id={id}&min_confidence=0.6 Then the API returns 200 with a paginated list of hazard events conforming to schema HazardEvent v1 (id, claim_id, hazard_type, severity, confidence, timestamps, source_id) And p95 response time ≤ 500 ms for result sets ≤ 100 records And filtering by time_range and hazard_type returns only matching events And unauthorized calls return 401; insufficient scope returns 403; invalid params return 422 with error details And OpenAPI documentation exists and matches actual responses
Security: Encryption and Data Handling
Given audio recordings, transcripts, and hazard events stored by the system Then data at rest is encrypted with AES-256 and keys are managed via KMS with rotation ≤ 90 days And data in transit uses TLS 1.2+ with modern cipher suites And raw audio and transcripts are not written to application logs; PII redaction is applied to error traces And access to storage and APIs is audited with immutable logs retained ≥ 1 year And CI security scans (SAST/Dependency) report zero High/Critical findings before release
Data Model Integration and Downstream Triggers
Given a claim with extracted hazards When hazards are persisted Then records are stored per ClaimFlow HazardEvent v1 schema and linked to claim_id And the safety checklist generator receives events with confidence ≥ 0.6 and produces checklist items aligned to hazard_type within 2 seconds of persistence (p95) And the do/don’t guidance module is invoked with the highest-severity hazard and returns prioritized guidance text And workflow gating blocks "Proceed to On-Site Task" when any Critical severity hazard exists until the checklist is acknowledged via API
Time-Stamped Hazard Mentions
"As a QA reviewer, I want each hazard mention time-stamped and linked to the audio so that I can quickly verify context and accuracy."
Description

Aligns each detected hazard to precise transcript timecodes and stores start/end timestamps with links to the corresponding audio snippet. Deduplicates repeat mentions, tracks first-seen and last-seen times, and highlights mentions in the transcript UI for quick verification. Persists timestamps with the claim for auditability and exposes them via API for QA and reporting.

Acceptance Criteria
Precise Timecodes for Hazard Mentions
Given an audio recording containing a spoken hazard phrase at known ground-truth times When Hazard Sentinel processes the file and aligns transcript tokens Then each detected hazard mention is stored with start_time and end_time aligned to the transcript with absolute error ≤250ms versus ground truth. And Then timestamps are ISO 8601 UTC with millisecond precision, and end_time >= start_time for every mention. And Then for overlapping mentions, all mentions are stored independently without dropped or merged timecodes. And Then the stored timecodes round-trip via persistence and API without loss of precision.
Audio Snippet Linking for Mentions
Given a hazard mention with stored start_time and end_time When a user clicks the mention highlight in the transcript UI Then the audio player starts within 250ms of start_time and stops within 250ms of end_time. And Then a deep link control opens the player to the same segment when shared. And Then the API field audio_snippet_url for the mention returns 200 OK with Content-Type audio/* and stream duration within ±500ms of (end_time − start_time). And Then authorization is enforced (401 for unauthenticated requests, 403 for unauthorized claims).
Deduplicate Repeat Mentions and Track First/Last Seen
Given multiple mentions of the same hazard_type occur within a single recording When processing completes Then the system emits one hazard aggregate per hazard_type with fields first_seen = earliest mention.start_time and last_seen = latest mention.end_time. And Then the aggregate includes mention_count equal to the number of mentions and a list of mention IDs with their individual start_time and end_time. And Then no duplicate aggregates of the same hazard_type exist for the same recording. And Then if only one mention exists, first_seen equals that mention's start_time and last_seen equals that mention's end_time.
Transcript UI Highlights Mentions
Given the transcript view is open for a processed recording When hazard mentions exist Then the exact token spans for each mention are highlighted with a distinct style per hazard_type. And Then clicking a highlight selects it, scrolls it into view, and syncs the audio player to the mention's start_time. And Then keyboard navigation (e.g., Alt+Up/Down) moves to previous/next mention. And Then highlight colors meet WCAG 2.1 AA contrast. And Then a "Hazard highlights" toggle shows or hides all highlights without reloading the page.
Persist Timestamps with Claim for Audit
Given a claim with extracted hazard mentions is saved When the claim is reopened after application/service restart Then all mentions, aggregates, timestamps, and audio links are present and unchanged. And Then an audit log entry records creation and any subsequent update with actor, UTC timestamp, and change summary. And Then records are retained according to retention_policy_days (default 2555 days) and purged only per policy. And Then database constraints enforce non-null start_time, end_time, hazard_type, and referential integrity to claim_id and recording_id.
API Returns Hazard Mentions with Timestamps
Given an authenticated client with scope claim.read and a valid claim_id When it calls GET /api/v1/claims/{claim_id}/hazards Then the response is 200 OK and returns a JSON array with fields: hazard_type, first_seen, last_seen, mention_count, and mentions[n]{id, start_time, end_time, transcript_span, audio_snippet_url}. And Then all timestamps are ISO 8601 UTC with millisecond precision. And Then query parameters type, start_after, end_before, and limit filter the results; invalid parameters return 400. And Then performance: for up to 200 mentions, median latency ≤800ms and p95 ≤1200ms in staging. And Then access control: 401 for unauthenticated, 403 for unauthorized, 404 for unknown claim_id.
Auto Safety Checklist Generation
"As a field adjuster, I want an auto-generated safety checklist tailored to the hazards so that I can take the right precautions before proceeding."
Description

Maps detected hazards to a configurable library of safety checklists and generates a tailored checklist per claim. Merges items across multiple hazards, orders tasks by severity and dependencies, and pre-fills dynamic steps (e.g., notify utility, establish perimeter) using available claim context. Publishes the checklist as a sub-task set in ClaimFlow, supports offline execution with later sync, and updates in real time if new hazards are detected.

Acceptance Criteria
Checklist Generation for Multiple Hazards in One Claim
Given a claim with detected hazards "downed power lines", "standing water", and "gas odor" And a configured library mapping each hazard to checklist items with severity scores and dependency rules When the system generates the safety checklist Then a single checklist is produced that contains the union of all mapped items And duplicate items across hazards are merged into one item with aggregated source-hazard tags And the checklist contains no items that are not mapped from the detected hazards or global safety prerequisites And checklist generation completes within 3 seconds for claims with <= 10 detected hazards
Severity- and Dependency-Ordered Tasks
Given the library defines numeric severity levels (e.g., Critical=4, High=3, Medium=2, Low=1) and explicit dependencies between items When the checklist is generated Then every item appears after all of its dependencies And items are primarily sorted by descending severity and secondarily by dependency topological order And for items with equal severity and no dependency relation, the order matches the library default order And the generated order is deterministic for the same inputs
Dynamic Pre-fill of Checklist Items Using Claim Context
Given claim context provides fields (e.g., policy carrier, utility provider, insured contact, loss location, occupancy status) And a checklist item includes dynamic placeholders (e.g., {utility_provider.name}, {utility_provider.phone}) When the checklist is generated Then placeholders are resolved using available claim context and populated into item fields And unresolved placeholders are surfaced as "Needs input" without blocking checklist publication And all prefilled values record their source and timestamp in the audit log And no item contains an unresolved placeholder token string at runtime
Publish Checklist as Sub-Tasks in ClaimFlow
Given a generated checklist for a claim When it is published to ClaimFlow Then a sub-task set named "Safety Checklist" is created under the claim And each checklist item is created as an individual sub-task with preserved order, severity, hazard tags, and dependencies And dependent sub-tasks cannot be marked complete until all prerequisite sub-tasks are complete And the publishing operation completes successfully and is visible to the assignee within 5 seconds
Offline Execution and Deferred Sync
Given the device is offline and the "Safety Checklist" sub-tasks are cached locally When the user records progress (complete/incomplete), notes, and photos on checklist items Then all actions are stored locally with timestamps and item IDs And upon connectivity restoration, all offline changes sync to the server within 60 seconds And attachments are uploaded and linked to their respective sub-tasks without loss And conflicts are resolved per field using last-write-wins with an audit entry and user notification when a local change is overwritten
Real-time Update on New Hazard Detection
Given the user has the checklist open and a new hazard is detected for the same claim When the system processes the new hazard Then new checklist items are added and existing items updated within 3 seconds And the updated checklist maintains dependency and severity ordering And already completed items remain completed; if new dependencies are introduced, they are added as pending with a change notice And the user is notified with a banner summarizing what changed and a link to the change log
Prioritized Do/Don’t Guidance
"As a field adjuster, I want prioritized do/don’t guidance so that I know the most critical actions to take immediately."
Description

Generates concise, prioritized do/don’t guidance for each detected hazard, emphasizing immediate life-safety actions. Presents guidance in an at-a-glance card with severity cues, icons, and links to SOP/OSHA references. Supports localization and text-to-speech for hands-free operation. Surfaces as a pre-proceed banner in the ClaimFlow UI and remains accessible throughout the claim workflow.

Acceptance Criteria
Immediate Life‑Safety Prioritization across Hazards
Given at least one hazard is detected, When guidance is generated, Then the first bullet on each hazard card addresses immediate life‑safety mitigation for that hazard type. Given multiple hazards are detected, When the list is rendered, Then hazards are ordered by severity descending (Critical, High, Medium, Low); ties are resolved by most recent mention timestamp (newest first). Given a Critical hazard is present, When the banner is displayed, Then that hazard appears at the top of the list and is prefixed with a critical attention cue.
Concise Do/Don’t Guidance Format per Hazard Card
Given a hazard card is generated, When its bullets are rendered, Then the card contains 2–4 total bullets with at least one "Do" and at least one "Don't". Given bullets are shown, When measured, Then no bullet exceeds 120 characters. Given text is analyzed, When readability is computed (Flesch–Kincaid), Then grade level is <= 8.0. Given localization is applied, When switching languages, Then bullet counts and order remain unchanged.
Guidance Card UI: Severity Cues, Icons, Timestamp
Given a hazard card is displayed, Then it includes: hazard name, severity label, color‑coded severity cue, hazard‑type icon, and latest mention timestamp (hh:mm:ss local). Given WCAG evaluation, Then the color contrast between text and background is >= 4.5:1 for normal text and >= 3:1 for large text/icons. Given the hazard type is unknown, Then a generic safety icon is used and no UI break occurs. Given viewport width from 320px to 1440px, Then the card layout remains readable without horizontal scroll.
SOP/OSHA Reference Linking and Availability
Given a hazard card is displayed, When references are available, Then the card shows at least one internal SOP link and one external OSHA reference link relevant to the hazard. Given a reference link is tapped, Then it opens in a new tab/window and returns HTTP 200 within 2 seconds on a 4G connection. Given the device is offline, When a reference is tapped, Then an offline notice is shown and a cached summary (>= 200 characters) is displayed if available. Given analytics is enabled, When a reference is tapped, Then a click event is logged with hashed user ID, hazard ID, and timestamp.
Localization of Guidance and UI (EN/ES) with Fallback
Given the app locale is EN‑US or ES‑US, When guidance is generated, Then all visible strings on the banner and cards appear in the selected locale. Given locale resources are missing for a string, Then the English string is shown and an error is logged. Given language is switched by the user, When on the banner or card, Then text updates within 500 ms without full‑screen reload. Given Spanish is selected, Then units and examples use locale‑appropriate terms.
Hands‑Free Text‑to‑Speech Playback
Given a hazard card or the pre‑proceed banner is visible, Then a TTS control (play/pause/stop) is present and focusable via keyboard. Given the user taps Play, Then guidance for the visible card is spoken in the current locale voice, starting within 1 second. Given the screen is locked, Then playback continues until paused/stopped by the user. Given a new card is opened during playback, Then the previous playback stops and the new card's guidance begins within 1 second. Given no TTS engine is available for the locale, Then the control is disabled and a tooltip indicates voice unavailability.
Pre‑Proceed Banner Surfacing and Persistent Access
Given at least one hazard is detected for a claim, When the user attempts to start the claim workflow, Then a pre‑proceed safety banner is shown before task screens. Given the banner is shown, Then the Proceed button is disabled until the user taps Acknowledge. Given the user acknowledged the banner, When navigating across workflow steps, Then a persistent Safety icon in the header re‑opens the full guidance list within 1 click/tap. Given a new Critical hazard is detected after acknowledgement, Then the banner re‑surfaces on the next navigation event and the header icon shows a red badge with the critical count. Given the banner is acknowledged, Then an audit record is stored with claim ID, user ID, hazard IDs, timestamp, and locale.
Safety Gate & Acknowledgment
"As a claims manager, I want a safety acknowledgment gate so that field staff cannot proceed without confirming they’ve reviewed critical guidance."
Description

Enforces a pre-proceed safety gate when high-severity hazards are detected. Requires the user to review guidance and acknowledge via checkbox or e-signature; supports role-based overrides with mandatory reason capture. Records timestamp, user ID, and optional GPS location. Integrates with ClaimFlow workflow to block or warn based on configurable thresholds and writes a non-editable acknowledgment event to the audit log.

Acceptance Criteria
High-Severity Hazard Blocks Progress Until Acknowledgment
Given Hazard Sentinel flags one or more hazards with riskScore >= blockThreshold for the active claim When the user attempts to proceed to the next workflow step or submit intake Then a Safety Gate modal appears within 500 ms with prioritized do/don’t guidance for the flagged hazards And all proceed/submit/navigation actions remain disabled until acknowledgment is completed per orgConfig.ackMethod And closing or dismissing the modal without acknowledgment keeps the user on the current step with no progression
Medium-Severity Hazard Warning with Conditional Acknowledgment
Given max hazard riskScore >= warnThreshold and < blockThreshold When the user attempts to proceed Then a non-blocking safety warning with prioritized guidance is shown And if orgConfig.requireAckOnWarn = true, the user must click “Acknowledge and Continue” before proceeding; otherwise, the user can proceed without acknowledgment And a warningShown audit event is generated with hazardIds and riskScore
Role-Based Override Requires Mandatory Reason Capture
Given the Safety Gate is blocking due to riskScore >= blockThreshold And the current user's role is included in orgConfig.overrideRoles When the user selects “Override and Proceed” Then the system requires a reason category selection and a free-text reason of at least 10 characters And the proceed action remains disabled until both fields are provided And users without override permission do not see the override option
Acknowledgment Methods and Guidance Review Enforcement
Rule (checkbox): Given orgConfig.ackMethod = "checkbox" When the user checks the acknowledgment box labeled with “I have reviewed the safety guidance” Then the Proceed action becomes enabled and userId + timestampUTC are captured Rule (eSignature): Given orgConfig.ackMethod = "eSignature" When the user provides a valid e-signature and confirms intent Then the Proceed action becomes enabled and userId + name + signature hash/image + timestampUTC are captured Rule (review enforcement): Given the Safety Gate guidance content When not fully viewed Then acknowledgment controls remain disabled; When the guidance panel is expanded and scrolled to end Then acknowledgment controls are enabled
Non-Editable Audit Log Event Persistence
Given an acknowledgment, override, or warningShown action is completed When the system records the event Then exactly one non-editable audit entry is written containing: claimId, userId, userRole, actionType (acknowledge|override|warningShown), hazardIds, maxRiskScore, thresholdType (block|warn), guidanceVersion, timestampUTC, workflowStepId, deviceId (if available), ipAddress (if available), gps (lat,long,accuracy,permissionStatus), overrideReason (if any), ackMethod, signatureHash (if any) And Proceed/Continue is finalized only after the audit write succeeds And if the audit write fails, an error is shown and proceeding is blocked with retry available; no partial state advances And audit entries are immutable and retrievable in the claim's audit log with read-only permissions
Optional GPS Capture and Metadata Recording
Given location permission is granted and a GPS fix is available When the user completes acknowledgment or override Then latitude, longitude, and horizontal accuracy are captured within 5 seconds and stored with the audit entry And if permission is denied or a fix is not available within 5 seconds Then gps.status = "unavailable" is recorded and progression is not blocked And captured GPS data is non-editable post-write
Auditable Risk Flags & QA Dashboard
"As a compliance officer, I want auditable risk flags with immutable records so that we can demonstrate duty-of-care during audits."
Description

Persists risk flags with metadata (hazard type, severity, confidence, timestamps, acknowledgments) in an immutable event log for duty-of-care evidence. Provides a QA dashboard to filter, search, and sample claims by hazard type/severity, and to play linked audio snippets. Supports export (CSV/JSON) and API access for compliance reporting and SOC/ISO audits, with role-based access controls and retention policies.

Acceptance Criteria
Persist and Verify Immutable Risk Flag Event Log
Given a claim has detected hazards When a new risk flag is generated Then the system writes a new append-only event record containing: claimId, hazardType, severity, confidence (0.00–1.00), sourceType, startTimestamp, endTimestamp (nullable), createdAt (UTC), acknowledged (bool), acknowledgedBy (nullable), acknowledgedAt (nullable), eventId (UUID), previousEventId (nullable), integrityChecksum And the record is readable immediately via UI, export, and API When a user acknowledges a risk flag Then a new event record is appended referencing the prior eventId and updating acknowledgment fields while the original record remains unchanged When an attempt is made to update or delete an existing event record directly Then the operation is rejected or results in an appended new version; the original record persists and remains retrievable When an integrity verification job runs Then 100% of event records pass checksum validation for untampered data and any discrepancy is logged with severity Critical within 60 seconds
QA Reviewer Filters, Searches, and Samples Claims by Hazard
Given the QA dashboard is open When the reviewer filters by hazardType = "Gas Odor", severity >= "High", date range = last 30 days, and confidence >= 0.80 Then only claims with matching risk flags are shown and the total count equals the filtered set size When a free-text search for "downed line" is applied Then only claims with matching hazard tags or transcripts appear in results When a random 10% sample (with seed) of the filtered set is requested Then the returned subset is reproducible for the same seed and filters, and the UI shows sample size and parameters When the filtered set contains up to 100,000 flags Then the first page loads within 2 seconds and supports pagination and sorting by severity, timestamp, and confidence
Play Linked Audio Snippets for Hazard Mentions
Given a risk flag sourced from audio with startTimestamp and endTimestamp When the reviewer clicks Play on the QA dashboard Then the corresponding audio segment plays aligned to the timestamps with ±200ms tolerance And the UI displays the segment duration and playback position When the segment duration is under 2 seconds Then a padded snippet of at least 2 seconds is played centered on the mention where available When the original audio file is unavailable Then the UI displays a non-blocking error, logs the missing asset, and no unrelated audio is played When multiple mentions exist in the same claim Then each Play control plays the correct segment for its own timestamps
Export Filtered Risk Flags to CSV and JSON
Given the QA dashboard has active filters When the reviewer exports as CSV or JSON Then the exported data contains only records in the filtered set and includes: claimId, hazardType, severity, confidence, sourceType, startTimestamp, endTimestamp, createdAt, acknowledged, acknowledgedBy, acknowledgedAt, eventId When exporting CSV Then the file is UTF-8, comma-delimited with RFC 4180 quoting, includes a header row, and all timestamps are UTC ISO 8601 When exporting JSON Then the output validates against the published schema and preserves data types (numbers, booleans, strings) When the export exceeds 50,000 records Then the system streams or chunks the download without timeout and the total rows equal the dashboard count
API Access with Role-Based Access Controls and Audit Logging
Given the compliance API is enabled When a user with role QA_Reviewer requests GET /risk-flags with filters Then the API returns 200 with only permitted records for that role When a user without permission requests the same endpoint Then the API returns 403 without revealing record existence When a Claims_Adjuster queries via API Then only flags for claims assigned to that user are returned and bulk export endpoints respond 403 When any API request completes Then an audit log entry is recorded with userId, role, IP, endpoint, parameter hash, UTC timestamp, response code, and record count When pagination is used Then pageSize is capped at 1000, nextPage tokens are provided, and rate limits of 100 requests/min per user are enforced with 429 on exceed
Retention Policies and Legal Hold for Risk Flag Events
Given a retention policy is configured (e.g., 7 years for hazardType = "Structural Instability") When events exceed the retention age and are not under legal hold Then they are purged by an automated job within 24 hours of eligibility When a legal hold is placed on a claim or hazard type Then covered events are excluded from purge until the hold is lifted and the hold status is visible in the dashboard When purge completes Then a non-PII purge receipt is written to the audit log with counts, date range, and policyId, and purged eventIds become inaccessible via UI, export, and API (410 Gone on direct lookup) When retention settings are exported for audit Then a JSON policy file is produced listing policy name, scope, duration, holds, and lastModified metadata
Configurable Hazard Taxonomy & Rules
"As an admin, I want to configure the hazard taxonomy, thresholds, and checklists so that the guidance aligns with our SOPs and jurisdictions."
Description

Offers an admin UI and API to manage hazard taxonomy, synonyms, severity scales, and mappings to checklists and guidance. Allows per-jurisdiction rules, client-specific configurations, and threshold tuning for guidance priority and workflow gating. Supports versioning, staged publishing, rollback, and change history to ensure consistent, auditable configuration management across environments.

Acceptance Criteria
Admin UI: Manage Hazard Taxonomy, Synonyms, Severity, and Mappings
Given I am an Admin with Config:Hazards permission, When I create a hazard with a unique code, name, severity scale bounds (1–5), and at least one synonym, Then the system saves it and displays it in the taxonomy list within 2 seconds. Given a hazard exists, When I add, edit, or delete synonyms and map checklist items and guidance templates, Then changes persist and the preview shows the associated checklist and guidance exactly as mapped. Given invalid input (missing name, duplicate code, duplicate synonym within the same hazard, severity outside 1–5), When I attempt to save, Then the save is blocked and field-level errors are shown; no partial updates occur. Given audit requirements, When I save any change, Then a change record is created capturing user ID, timestamp, change summary, and before/after values for affected fields.
Configuration API: CRUD with RBAC and Validation
Given a valid admin API token, When I POST /hazards with a valid payload, Then the API returns 201 with the created resource including id, version, and timestamps. Given a read-only API token, When I attempt POST, PUT, PATCH, or DELETE on configuration resources, Then the API returns 403 with an error code of "forbidden". Given invalid payloads, When I call POST or PUT, Then the API returns 422 with machine-readable field errors including the field path, rule violated, and message. Given optimistic concurrency control, When I update a resource with a stale version value, Then the API returns 409 Conflict; when I update with the current version, Then the update succeeds with 200 and an incremented version.
Per-Jurisdiction Rules: Targeting and Precedence Resolution
Given a base hazard rule exists, When I create a jurisdiction-scoped override for "CA", Then sessions tagged with jurisdiction "CA" use the override and sessions without "CA" use the base rule. Given both client-scoped and jurisdiction-scoped rules exist, When a session is for Client X in "CA", Then the system applies precedence: client override > jurisdiction override > base rule. Given a disabled jurisdiction rule, When I publish configurations, Then the disabled rule is not applied and the next-eligible rule by precedence is used.
Client-Specific Configurations: Isolation and Inheritance
Given two clients A and B, When I create a client-scoped synonym for A, Then it is not returned in GET queries scoped to B and cannot affect B’s detections. Given Client A lacks a custom severity scale, When a hazard is resolved for Client A, Then the system uses the base severity scale for any calculations and prioritization. Given multi-tenant security, When a user scoped to Client B queries for Client A’s configurations, Then the API returns 403 or 404 per RBAC policy and no data is leaked.
Threshold Tuning: Guidance Priority and Workflow Gating
Given guidance priority threshold = 0.85 and gating severity threshold = 4, When a detection outputs confidence 0.83 and severity 5, Then no priority alert is shown but workflow gating still blocks until the mapped checklist is completed. Given thresholds are changed and published at time T, When a new session starts after T, Then the new thresholds are applied; sessions started before T continue using the previously published thresholds. Given UI gating is active, When a user attempts to proceed without completing required checklist items, Then the Proceed action is disabled and an explanatory message is displayed and logged.
Versioning: Drafts, Staged Publishing, Rollback, and Change History
Given a draft v1.3, When I stage it to QA and publish, Then the QA environment reflects v1.3 while Production remains on its current version. Given a scheduled publish for v1.3 at 14:00 UTC, When time reaches 14:00 UTC, Then the target environment activates v1.3 and an audit record with actor, time, and comment is created. Given an issue in Production, When I initiate rollback to v1.2, Then Production reflects v1.2 within 1 minute and history records the rollback event with reason and actor. Given two versions v1.2 and v1.3, When I request a diff, Then the system shows added, removed, and changed fields for taxonomy, synonyms, mappings, and thresholds.
Runtime Resolution: Synonym-Based Hazard Mapping to Checklist and Guidance
Given a published taxonomy with hazard "Gas Odor" having synonym "smell of gas" mapped to guidance "Evacuate immediately" (priority High), When a recording transcript contains "smell of gas" with detection confidence 0.92, Then the system classifies the hazard as Gas Odor, time-stamps the mention, generates the mapped checklist, and displays High-priority guidance. Given a synonym is removed in a draft but not yet published, When a session runs in Production, Then detections still match the published synonym set; after publish, the removed synonym no longer triggers the hazard. Given multiple hazards are detected, When prioritization rules are applied, Then guidance is ordered according to configured severity and priority weights, and the ordering matches the configuration.

Timecode Anchors

Pins every extracted fact to its precise moment in the audio with a tappable waveform. Users can replay the exact snippet for quick verification, dispute resolution, or audit review. Delivers transparent traceability that speeds QA, reduces clarification calls, and strengthens chain‑of‑custody alongside Proof Seal.

Requirements

Word-Level Time Alignment Engine
"As a claims QA reviewer, I want every word of the transcript aligned to the audio so that any extracted fact can be traced back to an exact moment for fast, defensible verification."
Description

Implement a robust forced-alignment service that maps every transcript token to precise start/end timestamps in the source audio. The engine must accept ASR output, handle variable audio quality, and return word- and phrase-level timings with confidence scores. It should support retries, partial alignment when segments are missing, and diarization tags for speakers when available. Performance targets: align a 10‑minute recording in under 90 seconds at p95; accuracy targets: median word offset error ≤ 120 ms. Provide gRPC/HTTP APIs, idempotent job IDs, and health metrics. Store alignment artifacts in the claim’s data model for downstream anchoring and playback.

Acceptance Criteria
API Response and Artifact Persistence
Given a valid claimId, ASR transcript JSON (v1) with tokenized words and optional phrase segments, and the source audio, When the client submits an alignment request via HTTP POST /alignments or gRPC Align with a unique jobId, Then the service acknowledges with 202 Accepted (HTTP) or OK (gRPC) containing jobId and status ∈ {queued, processing}. Given a submitted jobId, When the client polls GET /alignments/{jobId} (or calls GetAlignment), Then on completion the response status is completed and includes for every input token: tokenText, startMs, endMs, confidence ∈ [0.0,1.0], and for each phrase: startMs, endMs, tokenIndexRange, with all timestamps monotonic and startMs < endMs. Given a completed alignment, When inspecting the claim’s data store by claimId, Then alignment artifacts (word timings, phrase timings, confidence scores, jobId, schema version) are persisted and retrievable by downstream services within 1 second of completion. Rule: Missing or filtered punctuation tokens are explicitly marked alignmentStatus = skipped; aligned tokens are alignmentStatus = aligned.
p95 Performance for 10-Minute Audio
Given a test set of 30 distinct 10-minute mono 16 kHz recordings of mixed quality and their ASR outputs, When processed sequentially on the reference production instance type, Then the measured wall-clock alignment time per job from accepted to completed has p95 ≤ 90 seconds and p50 ≤ 60 seconds. Rule: Any job exceeding 120 seconds is flagged latencyOutlier = true in metrics and logs.
Median Word Offset Accuracy ≤ 120 ms
Given a benchmark corpus with human-annotated word-level ground truth, When the alignment engine processes the corpus, Then the median absolute word onset error across all aligned words is ≤ 120 ms. Rule: Words with no ground-truth match are excluded from median but counted and reported as unalignedCount; unalignedCount/totalWords ≤ 10%.
Partial Alignment and Missing Segment Handling
Given audio containing dropouts or sections missing from the ASR transcript, When the alignment runs, Then the job completes with overall status = partial and returns aligned words where possible while marking others alignmentStatus ∈ {missing_audio, missing_transcript, low_confidence}. Rule: No aligned token may overlap a detected gap; contiguous gaps are represented as gapRegions with startMs/endMs and reason. Rule: The service must not fail the entire job due to partials; HTTP status remains 200 on GET for completed partial results.
Idempotent Job IDs and Safe Retries
Given an alignment request submitted with jobId = X and payload P, When the same request with jobId = X and identical payload P is retried after a network error, Then no duplicate processing occurs and the same alignment result is returned with identical artifact hashes. Given an alignment request submitted with jobId = X and a different payload P', When submitted, Then the service rejects it with 409 Conflict and does not mutate stored artifacts. Rule: All submission endpoints accept an Idempotency-Key or jobId header/field and are safe for at-least-once retry semantics.
Speaker Diarization Propagation
Given ASR output that includes speaker diarization segments with speakerId and time ranges, When alignment completes, Then each aligned word includes speakerId matching the diarization active at word startMs, and speaker turn boundaries do not split within a single word. Rule: If diarization is absent, words have speakerId = null and no diarization-derived fields are emitted.
Health Endpoints and Metrics Exposure
Given the service is deployed, When calling GET /health/ready and /health/live, Then readiness returns 200 only when dependency checks (storage, queue, model assets) pass, and liveness returns 200 if the process is responsive. Given a metrics scraper, When scraping /metrics (Prometheus format), Then counters and histograms exist for: requests_total by endpoint and status, jobs_total by status, alignment_latency_seconds with p50/p95/p99, queue_depth, and error_total by type. Rule: Metric names and labels follow the documented contract and are present continuously under nominal load.
Fact-to-Timecode Linking
"As an adjuster, I want each extracted loss detail to include its exact audio timecodes so that I can audit where it came from without re-listening to the entire call."
Description

Extend the NLP extraction pipeline to attach one or more timecode anchors to each extracted fact, referencing start/end offsets, confidence, and speaker. Support aggregation when a fact is stated multiple times and maintain provenance across transcript edits. Persist anchors in the claim graph with versioning so that updates do not break historical references. Expose anchors in the Fact API and ensure they are queryable and filterable (e.g., by confidence, speaker, section). Validate links during ingestion and flag low-confidence anchors for manual review.

Acceptance Criteria
Anchor Creation on Fact Extraction
Given an ingested audio file with aligned transcript and speaker diarization When the NLP pipeline extracts a fact from the transcript Then the fact must have at least one timecode anchor with fields: start_ms, end_ms, confidence, speaker_id, transcript_version_id And start_ms >= 0 And end_ms > start_ms And end_ms <= audio_duration_ms And confidence is between 0.0 and 1.0 inclusive And speaker_id is one of the recognized speakers for the call or "unknown" And GET /facts/{fact_id}/anchors returns the anchors sorted by start_ms ascending
Multiple Mentions Aggregation and Anchor Union
Given a fact content that appears multiple times in the audio When aggregation is performed during extraction Then the fact's anchors list contains all unique occurrences sorted by start_ms And anchors within 100ms of each other are deduplicated into a single occurrence And the fact exposes first_seen_ms = min(anchors.start_ms) and last_seen_ms = max(anchors.end_ms) And aggregated_confidence = max(anchors.confidence)
Provenance Preservation Across Transcript Edits
Given a fact with anchors linked to transcript_version_id = V1 When the transcript is edited producing version V2 (insertions, deletions, resegmentation, or speaker changes) Then existing V1 anchors remain retrievable by ID and by transcript_version_id = V1 And new anchors for V2 are created without mutating V1 records And GET /facts/{fact_id}/anchors?transcript_version_id=V1 returns only V1 anchors and GET /facts/{fact_id}/anchors?transcript_version_id=V2 returns only V2 anchors And a speaker change in V2 does not alter the speaker_id on V1 anchors
Anchor Persistence and Versioned Graph References
Given anchors are persisted in the claim graph When a fact is updated or reprocessed Then a new anchor version is created and linked; prior versions remain intact and queryable And dereferencing any historical anchor_id returns the original start_ms, end_ms, confidence, speaker_id, and transcript_version_id And graph integrity validation reports zero dangling anchor references from fact nodes
Fact API Querying and Filtering of Anchors
Given the Fact API supports anchor filtering When a client queries with confidence_min=0.7, speaker_id="claimant", section="accident_details", and time_range=[t0,t1] Then only anchors meeting all filters are returned And results are paginated with default limit <= 100 and max limit <= 1000 And results can be sorted by start_ms ascending or descending via a sort parameter And the endpoint responds within 500 ms for up to 1000 anchors in a preloaded test dataset
Ingestion Validation and Low-Confidence Flagging
Given the ingestion pipeline processes anchors When an anchor has confidence < 0.60 (or below the configured threshold) Then the anchor is marked review_required=true and a ManualReview task is created with a reference to fact_id and anchor_id And anchors with invalid bounds (start_ms < 0, end_ms <= start_ms, or end_ms > audio_duration_ms) are rejected, logged with severity=error, and not persisted And the ingestion summary includes counts for anchors_created, anchors_rejected, and anchors_flagged_for_review
Tappable Waveform with Anchor Markers
"As a claims manager, I want a waveform with tappable markers for facts so that I can quickly jump to the exact snippet to verify details."
Description

Render an interactive waveform synced to the recording that displays visual markers for each anchored fact. Users can hover to see a tooltip (fact summary, timestamps, confidence) and tap to jump to playback. Support zooming, scrubbing, keyboard shortcuts, and accessibility (WCAG AA: focus states, screen-reader labels). Handle long recordings with virtualized rendering and clustering of dense markers. Maintain synchronization between waveform, transcript highlight, and fact panel selections.

Acceptance Criteria
Hover Tooltip on Fact Anchor Marker
Given the waveform is rendered and facts are loaded When the user hovers a fact anchor marker with a pointing device Then a tooltip appears within 200 ms anchored to the marker And the tooltip displays: fact summary (<=120 chars), start and end timestamps in mm:ss, and confidence as a percentage with 1 decimal And the tooltip remains visible while the pointer is over the marker or tooltip and hides within 300 ms after exit or immediately on Esc And the tooltip stays within the viewport (no clipping) by repositioning as needed And the tooltip content matches the corresponding fact record ID in the fact panel
Tap-to-Playback from Anchor Marker
Given an anchor marker is visible When the user clicks/taps the marker or presses Enter/Space while the marker is focused Then the audio currentTime jumps to the anchor start within ±50 ms And playback starts (or continues) from that time And the waveform playhead, transcript highlight, and fact panel selection update to that fact within 100 ms And the fact panel scrolls the selected fact into view if off-screen And repeated activation of the same marker does not queue duplicate playbacks
Zooming, Scrubbing, and Keyboard Shortcuts
Given the waveform is focused When the user performs Ctrl/Cmd + Mouse Wheel or a trackpad pinch gesture Then the zoom level changes smoothly centered on the pointer with bounds of 1x–64x When the user drags horizontally on the timeline (scrub) Then the audio currentTime updates continuously without audible artifacts and the playhead tracks the pointer And marker positions and densities remain accurate at each zoom And keyboard shortcuts work: +/- to zoom in/out, Left/Right to seek 1s, Shift+Left/Right to seek 5s, Home/End to jump to start/end And all interactions respond within 100 ms median latency
Marker Clustering and Expansion on Dense Sections
Given multiple markers would overlap within 8 px at the current zoom level Then they render as a single cluster badge showing the count of markers And the cluster tooltip shows the time span (start–end) covered by the clustered markers When the user zooms in or activates the cluster (click/Enter) Then the cluster expands so that individual markers are visible without overlap at the new zoom level And cluster counts are accurate and visually update within 150 ms And at no zoom level do overlapping markers render closer than 4 px to each other
Cross-Component Synchronization (Waveform, Transcript, Fact Panel)
Given a fact is selected in the fact panel When selection changes Then the corresponding marker is highlighted and centered in the waveform within 150 ms, and the matching transcript span is highlighted Given audio playback or scrubbing enters a time range covered by a fact When currentTime is within a fact’s [start, end] Then the corresponding fact and transcript segment become active; when currentTime leaves the range, the highlight advances to the next fact or clears And if multiple facts share the same timestamp, the highest-confidence fact is selected; on ties, select the earliest created
Accessibility Compliance (WCAG AA)
Given a keyboard-only user When navigating the waveform and markers Then all interactive elements (play/pause, zoom controls, markers, clusters) are reachable via Tab/Shift+Tab and actionable via Enter/Space with a visible focus indicator meeting 3:1 contrast And focus order follows visual order without traps; Esc dismisses tooltips/popovers And each marker/cluster has an accessible name combining fact summary, start–end time, and confidence via ARIA label And tooltip content is available on focus (not hover-only) And text and essential non-text contrast meet WCAG 2.1 AA (1.4.3, 1.4.11); interaction targets are at least 24x24 dp (2.5.5) And tested to operate with NVDA, JAWS, and VoiceOver without loss of information
Performance on Long Recordings with Virtualized Rendering
Given a 3-hour recording at 48 kHz with 5,000 fact markers When the waveform first renders Then initial render completes within 1500 ms on a standard laptop (4-core CPU, integrated GPU) And panning/zooming/scrubbing maintain >=55 FPS with median input-to-frame latency <=100 ms And DOM nodes for markers are virtualized to <=300 simultaneously And memory usage attributable to the waveform stays <=250 MB And marker clustering ensures on-screen marker elements do not exceed 300 at any zoom level
Contextual Snippet Replay Controls
"As a dispute resolution specialist, I want to replay the exact quoted snippet with a bit of surrounding context so that I can confirm intent and resolve disagreements faster."
Description

Provide precise playback of anchored snippets with configurable pre/post context (e.g., ±5–10 seconds) and automatic transcript highlighting during playback. Include variable speed, skip-back/forward, and loop region. Ensure low-latency start (≤200 ms p95 after seek) and graceful handling when anchors overlap or fall near file boundaries. Surface a quick-copy link that deep-links to the same snippet inside ClaimFlow for internal sharing.

Acceptance Criteria
Low‑Latency Start After Seek
Given an audio recording with timecode anchors is loaded on a supported browser When the user taps an anchor, scrubs the waveform to a snippet, or opens a deep link to a snippet Then playback begins within 200 ms at the 95th percentile measured over 100 seeks/taps in the QA test matrix And the first audible audio frame corresponds to the requested start time ±50 ms And the playhead and transcript highlight appear within 100 ms of audio start
Configurable Pre/Post Context Playback
Given user preferences allow configuring pre/post context between 0 and 10 seconds in 0.5 s increments (default ±5 s) When the user initiates snippet playback from an anchor Then playback starts at max(anchor.start − pre, 0) and ends at min(anchor.end + post, audio.duration) And the effective pre/post values are displayed in the UI and persisted per user And context settings apply consistently across all snippets in the session
Automatic Transcript Highlighting In Sync
Given the transcript is word‑timed to the audio When snippet playback starts, pauses, seeks, speed changes, or loops Then the currently spoken words are highlighted with average drift ≤100 ms and worst‑case drift ≤200 ms relative to audio And on seek, the highlight updates to the new position within 100 ms And on pause, the highlight remains on the last played word
Variable Speed, Skip, and Loop Controls
Given snippet playback controls are visible When the user selects a playback speed of 0.5×, 1.0×, 1.5×, or 2.0× Then audio plays at the chosen speed and transcript highlighting respects the effective timing within the defined drift thresholds When the user taps Skip Back or Skip Forward Then the playhead moves by 5 seconds backward or forward respectively, clamped to [0, audio.duration] When Loop is enabled for the current snippet region Then playback repeats seamlessly between region start and end with loop gap ≤50 ms until Loop is disabled or playback stops
Overlapping Anchors Disambiguation
Given two or more anchors overlap on the waveform When the user taps within the overlapping region Then a popover lists overlapping facts by label and timestamps for selection And tapping directly on a specific anchor chip selects that anchor without a popover And the selected anchor determines playback region, transcript highlighting, and the deep‑link payload
Graceful Handling Near File Boundaries
Given an anchor lies within the configured pre/post context of the file start or end When snippet playback is initiated Then the actual start time clamps to 0 and/or end time clamps to audio.duration without error And the UI displays a non‑blocking indicator that context was truncated And Skip Back at t=0 does not underflow; Skip Forward at end stops or pauses playback predictably
Quick‑Copy Deep Link To Snippet
Given the user is viewing an anchored snippet When the user clicks Quick Copy Link Then a deep link is copied to the clipboard within 100 ms containing claimId, recordingId, anchorId, startMs, endMs, and applied pre/post context And opening the link in a supported environment opens ClaimFlow to the same recording, selects the anchor, applies the same context, and seeks to start And if the user lacks permission, an authorization error is shown and no audio is played And if the anchor is missing, the link falls back to the provided time range and displays a notice
Immutable Anchor Audit Trail with Proof Seal
"As a compliance officer, I want every timecode anchor to be sealed with immutable evidence so that chain-of-custody is provable during audits or disputes."
Description

Record each anchor’s creation, modification, and verification events in an append-only audit log and include its audio segment hash and transcript hash in the existing Proof Seal workflow. Generate a tamper-evident chain by timestamping and sealing anchor artifacts upon claim submission or export. Support auditor view that shows the snippet, hashes, sealing receipts, and responsible user/service. Provide exportable evidence bundles for legal/audit review.

Acceptance Criteria
Append-Only Anchor Audit Log
Given a user or service creates a new anchor, When the anchor is saved, Then an audit entry is written with event=CREATED, anchorId, claimId, actorId, actorType, timestamp (RFC3339 with ms), sequence=1, prevEntryHash=null, entryHash=SHA-256(payload). Given an existing anchor is edited, When changes are saved, Then an audit entry is written with event=UPDATED, sequence incremented by 1, a changeset of fields with from/to values, prevEntryHash set to the prior entryHash, entryHash recalculated, and no prior entry is altered. Given an anchor is verified, When the verifier confirms, Then an audit entry is written with event=VERIFIED, verifierId, method (manual|auto), signatureId (if available), and hash links preserved. Given any request attempts to modify or delete an audit entry, When the API receives PUT/PATCH/DELETE to audit resources, Then the request is rejected with 405/403 and an ATTEMPTED_TAMPER event is recorded. Given an anchor with N audit entries, When the chain is validated, Then every entry's prevEntryHash links to the previous entryHash and validation returns chainValid=true. Given a request to GET /anchors/{id}/audit for up to 200 entries, When processed under nominal load, Then the response returns in ≤300 ms and entries are sorted ascending by sequence.
Proof Seal Integration for Anchor Artifacts
Given claim submission or claim export is initiated, When the sealing job runs, Then for each anchor a record is included with audioHash=SHA-256 of the normalized audio snippet and transcriptHash=SHA-256 of the normalized transcript text, and these hashes are included in the Proof Seal payload. Given the sealing provider accepts the payload, When sealing completes, Then a receipt is stored per claim with providerTxId, merkleRoot (or equivalent), sealTimestamp (RFC3339 with ms), providerSignature, and each anchor stores a pointer to the receipt. Given any anchor artifacts change after a seal, When the claim is subsequently submitted or exported, Then a new seal is created referencing the new hashes and version; the original receipt remains immutable and linked to prior versions. Given sealing fails transiently, When the job encounters provider errors, Then retries occur up to 3 times with exponential backoff starting at 10s, and persistent failure sets sealStatus=failed and surfaces an alert on the claim. Given a sealed claim, When recomputing hashes from stored snippets/transcripts, Then the hashes match the stored values and the receipt verifies with the provider.
Time-Triggered Sealing on Submission and Export
Given a claim with anchors in Ready state, When a user clicks Submit Claim, Then sealing for all anchors starts within 5 seconds and completes within 60 seconds for up to 500 anchors under nominal conditions. Given a claim export is requested, When generating the export, Then any unsealed anchors are sealed before bundle creation; already sealed anchors are not resealed. Given a user performs a draft save, When no submission or export is triggered, Then no sealing operation occurs. Given sealing is in progress during submission, When the user navigates away, Then progress persists and resumes server-side until completion, with final status reflected in the claim timeline.
Auditor Read-Only Anchor Evidence View
Given a user with Auditor role opens a claim, When navigating to Anchor Audit, Then the UI displays for each anchor: playable audio snippet (±0.5s padding from timecode), transcript snippet, audioHash, transcriptHash, audit log entries, and sealing receipt details including provider and txId. Given the Auditor view is loaded for a claim with 200 anchors, When accessed under nominal load, Then the initial screen renders within 2 seconds and remaining anchors lazy-load without blocking UI. Given any attempt to edit anchors or audit entries from the Auditor view, When an action is invoked, Then controls are disabled and any direct API call returns 403 Forbidden and is logged. Given the Auditor clicks Copy on a hash or receipt id, When the action completes, Then the value is copied to the clipboard and a confirmation toast appears.
Exportable Evidence Bundle for Legal/Audit
Given an auditor exports a claim evidence bundle, When the export completes, Then the system produces a single ZIP containing: manifest.json, audit_log.jsonl, sealing_receipts.json, /audio_snippets, /transcripts, and checksums.txt with SHA-256 for every file. Given the manifest is opened, When inspected, Then it lists each anchor with anchorId, claimId, version, timecodeStart/End, audioHash, transcriptHash, actor identities, and receipt references, and includes a top-level bundleHash. Given the offline verifier tool is run against the ZIP, When verification completes, Then 100% of file checksums match, anchor hashes recompute to the same values, and receipt signatures validate. Given the export size exceeds 500 MB, When generated, Then the bundle is split into numbered parts with individual checksums and an index manifest describing the parts; otherwise a single ZIP is generated. Given the export contains PII, When the user selects Encrypt bundle, Then the ZIP is AES-256 password-protected and the password policy enforces 12+ characters with mixed types.
Automated Tamper Detection and Alerting
Given a claim's audit chain is scheduled for validation, When the background job runs hourly, Then it validates hash chains and sealing receipts for all active claims and records results. Given any broken hash link or altered entry is detected, When validation runs, Then the claim is flagged with chainValid=false, a Security Incident is opened with firstInvalidEntry details, and an alert banner appears to Admins and Auditors within 1 minute. Given the Proof Seal provider cannot verify a receipt, When validation runs, Then the claim is flagged with sealValid=false and remediation guidance is linked. Given a tamper write is attempted outside the append-only path, When the write occurs, Then the attempt is blocked, the source IP/user is recorded, and an ATTEMPTED_TAMPER event is appended to the log.
Anchor Export and API Access
"As an operations analyst, I want programmatic access and exports of timecode anchors so that I can integrate them with external QA and reporting systems."
Description

Offer secure APIs and exports for timecode anchors, including JSON/CSV exports and signed deep links to specific snippets. Provide field mappings (fact ID, start/end ms, speaker, confidence, hashes) and pagination/filters. Enforce RBAC and scope anchors to authorized users only. Support webhook notifications when anchors are created/updated to enable downstream systems (e.g., carrier QA tools) to ingest anchors in near real time.

Acceptance Criteria
JSON Export with Field Mappings, Filters, and Pagination
Given an authorized user with role Claims Manager for claim C123 containing 3 anchors When they call GET /v1/claims/C123/anchors?format=json&limit=2&fields=factId,startMs,endMs,speaker,confidence,hashes Then the response status is 200 And the Content-Type is application/json And the body.data contains exactly 2 anchors And each anchor includes factId,startMs,endMs,speaker,confidence,hashes And the body.pagination.nextCursor is present Given the nextCursor from the previous response When they call GET /v1/claims/C123/anchors?format=json&cursor={nextCursor}&fields=factId,startMs,endMs,speaker,confidence,hashes Then the body.data contains the remaining 1 anchor And no anchor from other claims is present Given filter parameters confidenceMin=0.85&speaker=Adjuster When they call GET /v1/claims/C123/anchors?format=json&confidenceMin=0.85&speaker=Adjuster Then every returned anchor has confidence >= 0.85 and speaker = "Adjuster" Given a createdAt range filter of 2025-09-01T00:00:00Z to 2025-09-30T23:59:59Z When they call GET /v1/claims/C123/anchors?format=json&createdAtStart=2025-09-01T00:00:00Z&createdAtEnd=2025-09-30T23:59:59Z Then every returned anchor has createdAt within the specified range
CSV Export with Field Mappings and Escaping
Given an authorized user for claim C123 containing anchors When they call GET /v1/claims/C123/anchors/export?format=csv Then the response status is 200 And the Content-Type is text/csv And the first row is a header containing factId,startMs,endMs,speaker,confidence,hashes And each subsequent row contains mapped values for those columns And fields with commas, quotes, or newlines are properly quoted per RFC 4180 And the CSV includes only anchors from claim C123 Given a claim C999 with zero anchors When they call GET /v1/claims/C999/anchors/export?format=csv Then the response contains only the header row and no data rows
Signed Deep Link Generation and Validation for Snippets
Given an authorized user and anchor A123 on claim C123 When they call POST /v1/anchors/A123/deeplinks with body { ttlSeconds: 600 } Then the response status is 201 And the body contains url, token, expiresAt, anchorId, startMs, endMs And the url includes a signature and expiresAt parameter Given the generated url before expiry When it is requested by any holder Then the response resolves to the exact snippet bounded by startMs and endMs with status 200 or a 302 redirect to the playback resource Given the same url after expiresAt When it is requested Then the response status is 403 Given a tampered token or signature When the url is requested Then the response status is 401 Given the deep link for anchor A123 When a request attempts to access a different anchor or claim via the link Then access is denied
RBAC and Tenant Scoping for Anchor Access
Given a user in tenant T1 assigned to claim C123 with role Adjuster When they call GET /v1/claims/C123/anchors Then the response status is 200 And only anchors for claim C123 in tenant T1 are returned Given the same user When they call GET /v1/claims/C999/anchors for a claim they are not assigned to Then the response status is 403 Given a user with role Admin in tenant T1 When they call GET /v1/tenants/T1/anchors Then the response status is 200 And only anchors from tenant T1 are returned Given a user from tenant T2 When they attempt to access any T1 anchor endpoint Then the response status is 403
Webhook Notifications on Anchor Create and Update
Given a webhook subscription for tenant T1 with event types anchor.created and anchor.updated and a shared secret When an anchor is created for claim C123 Then a POST is delivered to the subscriber within 10 seconds And the request body includes eventId, eventType, occurredAt, tenantId, claimId, anchorId, factId, startMs, endMs, speaker, confidence, hashes And the request contains an X-Signature header with a valid HMAC-SHA256 signature over the raw body using the shared secret Given the subscriber responds with HTTP 500 When the platform retries delivery Then at least 3 retries occur with exponential backoff And all retries reuse the same eventId for idempotency Given the subscriber receives duplicate deliveries When it de-duplicates by eventId Then processing occurs exactly once
Hashes and Chain-of-Custody Integrity Fields
Given an export response or webhook payload for anchor A123 When inspecting the hashes object Then it contains deterministic SHA-256 values for anchorHash, mediaHash, and transcriptHash And anchorHash is the SHA-256 of the canonicalized anchor payload excluding the hashes object And mediaHash equals the SHA-256 of the source media file referenced by the anchor And transcriptHash equals the SHA-256 of the transcript segment text used to derive the anchor And recomputing these values from available artifacts reproduces the same hashes
API Authentication and Authorization Scopes
Given a valid access token with scope anchors:read for tenant T1 When calling GET /v1/claims/C123/anchors Then the response status is 200 Given an access token missing anchors:read When calling GET /v1/claims/C123/anchors Then the response status is 403 Given an expired or invalid access token When calling any /v1/*/anchors endpoint Then the response status is 401 Given a valid access token with scope anchors:write When calling POST /v1/anchors/A123/deeplinks Then the response status is 201

Confidence Nudge

Highlights low‑confidence extractions inline and suggests quick confirmations (e.g., “Say the VIN slowly” or “Repeat address”). Supports voice or tap corrections and routes unresolved items to a lightweight review queue. Improves data accuracy without disrupting the 2‑second experience and shortens approval cycles.

Requirements

Inline Confidence Highlighting
"As an independent adjuster, I want low-confidence fields highlighted in the transcript so that I can quickly spot and fix risky data without hunting through the record."
Description

Display low-confidence NLP extractions inline within the intake transcript and form fields using subtle visual cues (e.g., amber underline, icon). Each highlighted token/field exposes its confidence score and a minimal hint on hover/tap. Clicking or focusing a highlight opens a compact correction panel without navigating away. Supported entities include VIN, policy number, loss date, address, claimant name, phone, and email. The component consumes confidence metadata from the extraction service, respects per-entity thresholds, and emits structured events for analytics. It must be non-blocking, preserve the 2‑second experience, and gracefully degrade if confidence data is unavailable.

Acceptance Criteria
Highlight Low-Confidence Entities Inline
Given the extraction service returns entities with confidence scores and per-entity thresholds are loaded When the intake transcript and form fields render Then each VIN, policy number, loss date, address, claimant name, phone, and email with confidence below its threshold is visually marked with an amber underline and a low-confidence icon And entities at or above their thresholds render without highlight And the visual cues do not modify field values or cursor behavior
Reveal Confidence Score and Hint on Hover/Tap
Given a highlighted entity is visible on a pointer device When the user hovers the highlight or moves keyboard focus to it Then a tooltip appears within 200 ms showing the numeric confidence as a percentage (one decimal) and a concise hint And when hover/focus leaves, the tooltip dismisses within 200 ms And on touch devices, the first tap shows the tooltip and a subsequent tap or an explicit Edit affordance is required to open the correction panel
Open Compact Correction Panel In-Place
Given a highlighted token or field is present When the user clicks it or presses Enter or Space while focused Then a compact correction panel opens inline without page navigation And it pre-fills the current extracted value and entity label and provides Save and Cancel controls And the panel opens within 200 ms and does not block other input And clicking Save updates the underlying value, removes the highlight for that entity, emits an analytics event, and closes the panel And clicking Cancel, pressing Escape, or clicking outside closes the panel without changing the value
Per-Entity Threshold Application
Given thresholds exist for VIN, policy number, loss date, address, claimant name, phone, and email and a default threshold is defined When determining whether to highlight an entity Then the entity’s confidence is compared against its specific threshold, or the default when a specific one is missing And if confidence is less than the threshold the entity is highlighted, otherwise it is not And for VIN confidence 0.86 with threshold 0.90 the VIN is highlighted And for policy number confidence 0.93 with threshold 0.90 the policy number is not highlighted And updating a threshold in configuration takes effect on next render without code changes
Structured Analytics Events for Highlight Interactions
Given the analytics collector is available When a highlight is displayed, a tooltip is shown, a correction panel is opened, a value is saved, or a panel is dismissed Then the component emits a structured event for each action with fields: event_name, entity_type, confidence (0–1), action, origin (hover|focus|click|tap), timestamp, session_id And events are emitted exactly once per action and failures to emit do not affect UI behavior
Graceful Degradation Without Confidence Metadata
Given confidence metadata is missing, null, or fails to load When the intake transcript and form fields render Then no low-confidence highlights or icons are shown and no errors are displayed to the user And correction affordances are not shown solely due to missing confidence metadata And an analytics event named confidence_unavailable is emitted with a request identifier And overall render remains within the 2-second experience target
Performance and Non-Blocking Behavior
Given typical production payloads and target devices When rendering the transcript and form with highlighting enabled Then time from data availability to interactive state with highlights is less than or equal to 2,000 ms at the 95th percentile And opening a correction panel completes in less than or equal to 200 ms at the 95th percentile And highlighting computation does not block input; input latency remains less than or equal to 100 ms at the 95th percentile during interactions
Multi‑Modal Quick Confirmations
"As a claims manager, I want one-tap or voice confirmations for uncertain fields so that I can correct data without breaking my flow."
Description

Provide one-tap and voice-driven prompts to confirm or correct low-confidence fields in place. For voice, play concise guidance such as “Say the VIN slowly” or “Repeat the street address,” capture the utterance, and re-validate. For tap, present pre-filled editable inputs with smart masks (VIN, phone, postal code) and single-tap confirm. Include retry handling, partial acceptance (e.g., confirm city, edit ZIP), and immediate re-scoring. The UX must be accessible (screen readers, large tap targets), mobile/desktop friendly, and localized. All interactions must complete within the overall 2‑second interaction budget and never block continued intake.

Acceptance Criteria
Inline Low-Confidence Highlight and Prompt
Given an extracted field’s confidence is below the configured threshold T When the field is rendered in the intake UI Then the field is visually highlighted inline and labeled as “Needs confirmation” And both options “Confirm” (tap) and “Speak” (voice) are visible and enabled And the user can continue to the next field without interacting with the prompt And the highlight appears adjacent to the field it refers to And the highlight state is removed automatically once the field’s confidence is >= T
Tap Confirmation with Smart Masks and Partial Acceptance
Given a low-confidence field is selected for tap confirmation When the user opens the confirmation input Then the input is pre-filled with the current value and includes a type-specific mask and validation And a single-tap Confirm action is available to accept the pre-filled value if unchanged And for VIN: the mask enforces 17 uppercase alphanumeric characters excluding I, O, Q and validates checksum where applicable And for Phone: the mask formats per current locale and normalizes to E.164 on save And for Postal Code: the mask validates per current locale or falls back to a generic alphanumeric mask with length constraints And for multi-part addresses: the user may confirm any sub-field (e.g., City) while editing others (e.g., ZIP), with confirmed sub-fields immediately marked as accepted And validation errors are announced inline and do not block navigation to other fields
Voice Confirmation with Guided Prompt and Mic Handling
Given a low-confidence field is selected for voice confirmation and microphone access is granted When the user taps Speak Then a concise localized guidance prompt plays (<= 7 words, <= 2 seconds duration) And the system records the utterance, transcribes it using the current locale, and re-validates the field And if the resulting confidence is >= T, the field value is updated and marked confirmed And if microphone access is denied or revoked, the system gracefully falls back to tap confirmation without blocking intake And the user can cancel recording at any time without losing previously entered data
Retry Handling and Review Queue Routing
Given a confirmation attempt (tap or voice) results in confidence remaining below threshold T When the user retries Then the system allows up to R configurable retries (default 2) per field And each retry preserves any confirmed sub-fields and only requests remaining unresolved portions And the user can skip further attempts and continue intake without blocking And when retries are exhausted or the user skips, the item is added to the lightweight review queue within 1 second And the review queue entry includes field name, current value, candidate values, confidence scores, attempt count, and (for voice) transcript reference
Immediate Re-Scoring and UI Update
Given a user confirms or corrects a value via tap or voice When the user submits the confirmation Then the field’s confidence is re-scored immediately and the updated score is reflected in the UI within 200 ms And if the confidence is >= T, the inline nudge is cleared and downstream workflow rules are re-evaluated without creating duplicate tasks And if the confidence remains < T, the nudge persists and offers available confirmation options And any dependent fields (e.g., address components) are re-validated and updated accordingly
Accessibility, Localization, and Cross-Platform UX
Given the intake UI is used across supported devices and locales When interacting with prompts and inputs Then all controls have accessible names, roles, and states announced correctly by screen readers (e.g., VoiceOver, TalkBack, NVDA) And focus order is logical, visible focus indicators are present, and keyboard navigation supports all actions (including Speak trigger and Confirm) And tap/click targets are at least 44x44 px with a minimum 4.5:1 text contrast ratio And all guidance prompts, labels, error messages, and masks are localized to the current locale with correct number/address/phone formats And the UI is responsive and usable on mobile and desktop viewports per the product support matrix
Performance Budget and Non-Blocking Behavior
Given a user initiates a confirmation action (tap or voice) When the system processes the action Then the end-to-end interaction (prompt render to result or fallback) completes within 2 seconds at the 95th percentile on supported devices and networks And UI threads remain responsive (no frozen frames > 100 ms) during processing And long-running work executes asynchronously so the user can continue intake without waiting And telemetry captures latency percentiles for highlight render, prompt playback, transcription, validation, and re-scoring
Dynamic Confidence Thresholds by Entity
"As a carrier admin, I want to tune when nudges fire for different fields so that we balance accuracy with speed for our teams."
Description

Enable configurable nudge thresholds per entity type, workflow, and carrier. Provide sensible defaults (e.g., VIN > 0.95, address > 0.85) and allow admins to tune thresholds and retry limits via settings or config files. Incorporate contextual heuristics (e.g., cross-check against policy data, geocoding match quality) to raise or lower thresholds at runtime. Expose a rules API for advanced conditions (e.g., higher scrutiny for total-loss claims). Persist versioned configurations, validate changes, and roll back safely.

Acceptance Criteria
Per-Entity Defaults Applied Per Carrier/Workflow
Given a tenant (carrier) with no custom thresholds for a workflow When ClaimFlow evaluates an extracted VIN (confidence = 0.93) and Address (confidence = 0.86) Then a nudge is triggered for the VIN (0.93 < 0.95) and not for the Address (0.86 >= 0.85) And the applied thresholds are VIN 0.95 and Address 0.85 from system defaults And the thresholds are scoped to the specific carrier and workflow with no cross-tenant leakage And an audit record notes default-sourced thresholds for the evaluation
Admin UI and Config File Updates with Validation and Versioning
Given a tenant-admin is authenticated and on Settings > Confidence Thresholds When they set VIN.threshold = 0.97 and VIN.retry_limit = 2 and click Publish Then inputs are validated (threshold in [0.0,1.0], retry_limit integer 0–5) and invalid inputs are rejected with inline errors And a new config version is created with author, timestamp, semantic diff, and status Published And the new version becomes active within 60 seconds and is used for subsequent evaluations And when a valid JSON/YAML config file with the same changes is uploaded via Admin API Then the same validations, versioning, and activation semantics apply
Rules API Enforces Advanced Conditions with Defined Precedence
Given a ruleset defines: when claim.type = "total_loss" then VIN.threshold = 0.98 and VIN.retry_limit = 3 When a total-loss claim is evaluated for VIN confidence 0.97 Then a nudge is triggered because 0.97 < 0.98 and retry_limit is 3 for that entity And when a non-total-loss claim is evaluated, the rule does not alter VIN settings And if a rules payload is syntactically invalid, the API responds 400 with error details and no config version is created And precedence is Base Defaults < Tenant Overrides < Rules API < Contextual Heuristics
Contextual Heuristics Adjust Thresholds at Runtime with Traceability
Given Address base threshold = 0.85 and geocoding.match_quality = 0.60 When evaluating the effective threshold Then the threshold is raised by 0.05 to 0.90 (clamped to [0.0,1.0]) And the evaluation log includes reason "low_geocode_quality" and the before/after values And given VIN base threshold = 0.95 and policy.vin_verified = true When evaluating the effective threshold Then the threshold is lowered by 0.05 to 0.90 (clamped to [0.0,1.0]) And heuristic adjustments are applied after Rules API overrides and before nudge decision
Safe Rollback to Previous Version Without Downtime
Given active config version v7 and prior version v6 exists When an admin initiates a rollback to v6 Then v6 becomes the active version atomically without service interruption And all evaluations started after rollback use v6, while in-flight evaluations complete with their originally loaded version And an audit log records the rollback initiator, timestamp, from_version v7, to_version v6, and reason And if v6 fails validation on load, rollback is aborted and v7 remains active with an error reported to the admin
Runtime Performance and Graceful Degradation
Given threshold evaluation requires tenant overrides, rules, heuristics, and context lookups When processing 1,000 requests under nominal load Then the added evaluation latency is <= 50 ms at p95 and <= 100 ms at p99 And context lookups each have a 200 ms timeout; on timeout the system falls back to base thresholds and logs a warning And a per-tenant cache is used so that repeated evaluations with identical inputs avoid external lookups for 5 minutes or until config/rule version changes And the end-to-end nudge decision preserves the product 2-second experience budget
Retry Limits Route Unresolved Items to Review Queue
Given VIN.retry_limit = 2 and a VIN extraction with initial confidence 0.60 and threshold 0.95 When the user provides up to 2 corrections (voice or tap) and the confidence remains below 0.95 Then the system stops prompting for VIN corrections and routes the item to the review queue And the review queue record includes entity type, latest confidence, effective threshold, retries_used = 2, and suggestion history And if the confidence meets or exceeds 0.95 before retries are exhausted, the item is not routed to the review queue
Unresolved Items Review Queue
"As a claims supervisor, I want unresolved low-confidence items queued for review so that nothing blocks approvals or slips through unnoticed."
Description

Automatically route unconfirmed or repeatedly failed extractions into a lightweight review queue. Create concise review tasks with links to the original artifacts (photo, transcript snippet), suggested values, confidence scores, and change history. Support assignment, prioritization, SLAs, and bulk actions. Provide keyboard-first triage, quick approve/edit/reject, and audit logging. Notify assignees via in-app alerts and optional email. Seamlessly update the claim record upon resolution and unblock downstream workflow steps.

Acceptance Criteria
Auto-route unresolved extractions to Review Queue
Given an extraction remains unconfirmed at the end of the intake step and its confidence score is below the configurable threshold (default 0.60) When the intake step completes Then a Review Queue task is created and linked to the claim within 2 seconds and no duplicate task is created for the same extraction And the task records attemptCount incremented by 1 if a task already exists And extractions that fail confirmation twice (>=2 failed attempts) are routed immediately upon the second failure And extractions confirmed or corrected by the user are not routed
Review task content completeness and traceability
Given a Review Queue task created from an extraction sourced from a photo and transcript When the task is opened Then it displays field name and ID, claim ID, suggested value, confidence score (0–1 with two decimal places), and attemptCount And it shows change history entries with timestamp, actor, previous value, new value, and reason (if provided) And it provides working links to the original artifacts: photo opens to the correct image with the extracted region highlighted and transcript opens to the snippet with the phrase highlighted And artifact links respect permissions: authorized users can open, unauthorized users receive an access denied message And all values in the task are read-only until an approve/edit/reject action is initiated
Assignment, prioritization, SLAs, and notifications
Given Review Queue tasks exist with varying priority and SLA due times When the queue list is viewed Then tasks are sorted by priority (P1 highest to P3 lowest), then by SLA due time ascending, then by createdAt ascending And an unassigned task can be assigned to a user or team and reflects the assignee immediately When a task is assigned to a user with notifications enabled Then that user receives an in-app alert instantly and an email within 60 seconds When an SLA enters Due Soon (<=15 minutes to due) Then the task shows a yellow indicator and the remaining time countdown updates at least every 60 seconds When an SLA is breached Then the task shows a red Overdue state, escalates per configuration, and the assignee receives an in-app alert and email (if enabled) within 60 seconds
Keyboard-first triage with approve/edit/reject
Given a user focuses the Review Queue list When they use only the keyboard (Arrow Up/Down to navigate, Enter to open, A=Approve, E=Edit, R=Reject, Esc=Close) Then they can complete an approve action for a task in 3 or fewer keystrokes after opening And all actions (approve/edit/reject) execute without mouse input and provide visible focus states And edits support tabbing through fields and form validation messages appear without requiring a mouse And action latency from keypress to UI confirmation is <=500 ms on a stable connection And after action completion, focus returns to the next task in the list
Bulk actions for fast triage
Given a user selects multiple tasks using keyboard or checkbox toggle When they choose Bulk Approve with suggested values Then all selected tasks are approved in a single operation and a success count and failure count are displayed When they choose Bulk Edit and supply a value Then the value is applied to all selected tasks of the same field type; tasks with incompatible types are skipped with a clear reason When they choose Bulk Reject and select a reason code Then all selected tasks are rejected with that reason and require a confirmation step before execution And bulk operations process up to 200 tasks per request with progress feedback and per-item atomicity (a failure on one does not stop others)
Seamless claim update and workflow unblocking
Given a task is approved or edited in the Review Queue When the action is confirmed Then the associated claim record is updated atomically with the resolved value and the Review Queue task status changes to Resolved And any downstream workflow step waiting on that field transitions from Blocked to Ready within 2 seconds And repeated submissions of the same action are idempotent and do not create duplicate updates When a concurrent change to the same field occurs Then the user is prompted to reconcile differences before the action is applied
Comprehensive audit logging of triage actions
Given any triage action occurs (approve, edit, reject, bulk operation, assignment change) When the action is completed Then an immutable audit log entry is created within 1 second containing actor, timestamp (UTC), claim ID, task ID, action type, source=ReviewQueue, previous value, new value, reason (if provided), and bulkOperationId (if applicable) And the entry is visible in the claim’s audit log UI and exportable via the audit export endpoint And audit entries cannot be altered or deleted by end users
Correction Capture & Model Feedback Loop
"As an ML engineer, I want structured correction data from nudges so that we can improve extraction accuracy over time."
Description

Capture every confirmation, correction, and rejection with before/after values, context (entity type, source artifact), and confidence deltas. Store as structured, privacy-compliant events with redaction for PII per carrier policy. Batch and deliver labeled examples to the ML feedback pipeline with lineage and model/version tags. Provide opt-in controls, data retention settings, and performance safeguards so feedback collection does not impact latency. Expose a simple export for offline training and a toggle to exclude sensitive fields.

Acceptance Criteria
Inline Correction Event Capture
Given a user confirms, corrects, or rejects an extracted field in Confidence Nudge When the action is submitted Then an event is created containing action_type (confirm|correct|reject), entity_type, field_name, before_value, after_value, source_artifact_type/id, extraction_confidence_before, extraction_confidence_after (if recalculated), confidence_delta, locale, timestamp (UTC ISO8601), session_id, claim_id, anonymized_actor_id, event_id, and schema_version Given an event is created When validated against the event schema Then all required fields are present, types conform, and model_name/model_version from the originating extraction are attached Given multiple actions occur in a single intake session When events are recorded Then each event is independently persisted and linked via session_id and claim_id without overwriting prior events Given a transient failure during capture When a user submits an action Then the event is queued durably and retried with exponential backoff up to 5 attempts within 2 minutes total, without blocking the user flow
Privacy Redaction and Policy Compliance
Given carrier-specific PII policy rules are configured When an event is persisted Then PII-marked fields (e.g., SSN, full VIN if excluded, phone, email, address lines) are redacted or tokenized per policy before storage and transport Given a field is marked sensitive and exclude_from_feedback=true When a correction is captured Then before_value and after_value are replaced with redaction tokens and excluded from downstream batches and exports while non-sensitive metadata is retained Given an auditor reviews the system When exporting a 1,000-event sample Then zero unredacted PII values are present and an audit log shows policy_version, redaction method, and time of application Given a regulatory deletion request for a claim_id When the purge job runs Then all related feedback events are hard-deleted within 24 hours and the deletion is logged with evidence
Batching and Delivery to ML Feedback Pipeline
Given feedback events are captured When batching runs Then events are grouped by carrier and model_version with batch size up to 500 events or a max wait of 60 seconds, whichever occurs first Given a batch is sent to the ML feedback endpoint When the endpoint responds with 2xx Then events are marked delivered with delivery_timestamp and feedback_job_id Given the endpoint responds non-2xx or times out When retries occur Then the system retries with exponential backoff and jitter for up to 6 hours while preserving event order within a batch Given duplicate delivery risk When a batch is retried Then idempotency keys ensure the receiver achieves exactly-once application while the sender provides at-least-once delivery with deduplication rate ≥ 99.9% Given rolling 24-hour operations When delivery metrics are evaluated Then successful delivery rate is ≥ 99.5% and stuck batches trigger an alert within 5 minutes
Opt-in Controls and Retention Settings
Given tenant-level feedback capture is disabled by default When a carrier has not opted in Then no feedback events are captured or exported and admin surfaces indicate how to enable capture Given a carrier enables feedback capture When retention_days is configured (or defaults to 180) Then events older than retention_days are automatically purged daily and the purge is logged with counts and time range Given per-field sensitivity toggles exist When exclude_from_feedback is enabled for a field Then event values are masked while recording entity_type and confidence_delta for analysis Given a carrier disables feedback capture When the setting is toggled off Then new event capture stops within 1 minute; if purge_on_disable is enabled, queued and stored events are deleted within 24 hours
Latency and Experience Safeguards
Given a user submits a correction, confirmation, or rejection When capture executes Then additional client-side processing adds ≤ 5 ms p95 and server-side processing adds ≤ 20 ms p95 over 10,000 actions, preserving the overall 2-second experience target Given the ML feedback pipeline is degraded or unavailable When corrections occur Then capture is deferred to an async queue and the user flow remains uninterrupted with no error presented to the user Given queue backpressure thresholds are exceeded When thresholds are hit Then the system reduces capture via a configurable sampling rate (default 50%), emits metrics and alerts, and never blocks the user action Given retries are exhausted for an event When persistence ultimately fails Then a minimal error event with error_code and masked context is stored if possible, and an alert is fired within 2 minutes
Offline Training Export
Given an authorized admin requests an export When filters include date range, carrier, entity_types, and include_values toggle Then the system generates CSV and Parquet files with schema: event_id, timestamps, claim_id, session_id, entity_type, field_name, before_value_masked, after_value_masked, action_type, confidence_before, confidence_after, confidence_delta, source_artifact_type/id, model_name, model_version, lineage_ids, policy_version, redaction_flags Given include_values=false or sensitive fields are excluded When the export is generated Then all sensitive values are masked and no PII is present in the files Given up to 1,000,000 events match the request When export is requested Then files are available within 2 minutes at the 95th percentile via a signed URL valid for 24 hours and accompanied by a checksum Given lineage requirements When export completes Then a manifest JSON is produced with counts by entity_type, time window, model_version, and a hash of contents
Lineage and Model Tagging
Given an extraction produced an initial value When a feedback event is created Then the event includes model_name, model_version, extraction_run_id, and document_id linking to the source artifact Given models are upgraded When new events are captured post-upgrade Then events reference the new model_version and do not overwrite history from previous versions Given analysts query feedback data When filtering by model_version and entity_type Then the results contain only matching events with zero cross-version contamination, verified by sampled checks
Nudge Analytics & Reporting
"As an operations lead, I want analytics on nudge usage and outcomes so that I can optimize thresholds and demonstrate ROI."
Description

Offer dashboards and exports showing nudge volume, trigger rate, acceptance/correction rates, average time-to-confirm, and downstream impact on approval cycle time and rework. Break down by entity, workflow, carrier, channel (voice/tap), and user segment. Support cohort comparisons, A/B testing for thresholds, anomaly detection (e.g., sudden spike in VIN corrections), and funnel views from extraction to resolution. Integrate with the existing BI layer and emit standardized telemetry events.

Acceptance Criteria
Analytics Dashboard: Segmented Metrics Overview
- Users with Analytics_View permission can access the Nudge Analytics dashboard. - Time range selector supports Last 24h, 7d, 30d, and Custom (UTC), and applies to all widgets. - Metrics tiles display: Nudge Volume, Trigger Rate, Acceptance Rate, Correction Rate, Avg Time-to-Confirm, Unresolved Rate, Review Queue Count; definitions are shown on-hover. - Filters for entity_type, workflow_id, carrier_id, channel (voice|tap), and user_segment can be applied singly or in combination; applied filters are reflected in URL for shareable views. - With filters applied, all widgets update within 3 seconds p95 for datasets ≤ 1,000,000 nudges. - Given a seeded dataset of 10,000 extractions with 2,500 nudges and 1,000 acceptances, Trigger Rate displays 25.0% ±0.1% and Acceptance Rate 10.0% ±0.1%. - Channel breakdown totals equal overall totals within ±1 event.
CSV Export: Filtered Metrics and Events
- Export button is enabled on the analytics dashboard; clicking opens a modal with two modes: Aggregated Metrics and Event-Level. - Aggregated export includes one row per selected breakdown (entity_type, workflow_id, carrier_id, channel, user_segment, time_bucket) with columns: nudge_volume, trigger_rate, acceptance_rate, correction_rate, avg_time_to_confirm_ms, unresolved_rate, review_queue_count. - Event-level export includes one row per nudge event with columns: event_id, claim_id, entity_type, channel, user_segment, workflow_id, carrier_id, event_type, event_ts, ab_variant, confidence_score, resolution_type (confirmed|corrected|unresolved), time_to_confirm_ms. - Exports respect current filters and time range; time zone is UTC; numbers use dot decimal; CSV is UTF-8 with header. - For data sets ≤ 500,000 rows, export completes and downloads within 60 seconds p95; for larger sets, user is prompted to narrow filters. - Exported totals match on-screen metrics within ±0.1%.
Cohort Comparison and A/B Threshold Testing
- Users can create up to 5 cohorts by specifying filters and/or configuration snapshots (e.g., low-confidence threshold versions) and save them by name. - The comparison view displays side-by-side metrics per cohort and the absolute and percent differences. - For A/B tests where ab_variant ∈ {A,B}, the system computes uplift for acceptance_rate and avg_time_to_confirm_ms and displays 95% confidence intervals; results are marked "insufficient sample" if any arm has < 500 nudges. - Variant assignment is read from telemetry and is immutable per nudge; mismatched or missing variants are excluded from A/B calculations and reported as a count. - Users can export the cohort comparison table as CSV; exported numbers match on-screen within ±0.1%.
Funnel View: Extraction-to-Resolution Journey
- Funnel stages are defined as: Extractions Attempted -> Nudges Triggered -> Nudges Viewed -> Confirmations -> Corrections -> Unresolved -> Routed to Review -> Resolved in Review. - The funnel shows counts, conversion rates between stages, and average time between (Triggered->Viewed, Viewed->Resolved). - Applying filters/time range updates the funnel within 3 seconds p95 and persists stage definitions in a help tooltip. - The sum of Confirmations + Corrections + Unresolved at the 'Viewed' step equals 'Viewed' within ±1 count. - Clicking any stage opens a sample list (up to 100 items) with claim_id and entity_type for audit.
Anomaly Detection and Alerting for Nudge Metrics
- Users can enable anomaly detection per metric (e.g., VIN correction rate) with a 7-day rolling baseline and 3-sigma threshold; minimum baseline volume is 1,000 events. - When an anomaly is detected, an alert banner appears on the dashboard and a webhook is fired within 2 minutes with payload including metric, current value, baseline mean/std, z-score, filters context, and sample_ids. - Anomalies are de-duplicated within a 60-minute window; users can mute a metric for 24 hours. - Synthetic test: injecting a 3x spike in VIN corrections for carrier X triggers an alert with z-score > 3.0. - All anomaly events are logged and can be exported.
Downstream Impact on Approval Cycle Time and Rework
- The impact view attributes claims to cohorts {with_nudges, without_nudges} based on whether any Confidence Nudge event occurred during intake. - Metrics displayed: median and p90 approval_cycle_time_hours (intake_start to approval_complete) and rework_rate (% claims with post-approval corrections). - Results can be filtered by entity_type, workflow_id, carrier_id, channel, and user_segment; filters apply to both cohorts. - Differences (absolute and percent) are computed along with 95% CIs using bootstrapping (1,000 resamples) for cycle times and proportion CIs for rework; mark "insufficient sample" if cohort < 200 claims. - Data freshness SLA: metrics include data up to 15 minutes ago; last_updated timestamp is shown.
Standardized Telemetry and BI Integration
- The system emits the following events to the BI layer: nudge_triggered, nudge_shown, nudge_confirmed, nudge_corrected, nudge_unresolved, review_routed, review_resolved, funnel_transition, ab_variant_assigned, export_generated. - Each event includes required properties: event_id (UUIDv4), claim_id, workflow_id, carrier_id, entity_type, channel, user_segment, confidence_score, ab_variant (nullable), event_ts (ISO 8601 UTC), schema_version, and, where applicable, resolution_type and time_to_confirm_ms. - Events are delivered to the BI ingestion topic within 60 seconds p99 with end-to-end success rate ≥ 99.9% and are idempotent by event_id; duplicates are < 0.1%. - Contract tests validate schema compliance; any schema change increments schema_version and is backward compatible; noncompliant events are quarantined with an error code and surfaced in ops dashboard. - A reference model/dashboard in the existing BI layer reproduces core metrics (trigger_rate, acceptance_rate, correction_rate) and matches in-app metrics within ±0.2%.
Latency Guardrails for 2‑Second Experience
"As an adjuster, I want nudges to appear instantly without slowing intake so that I can maintain my rhythm and finish faster."
Description

Define and enforce an end-to-end latency budget for nudge detection and rendering (95th percentile under 2 seconds). Precompute candidate nudges where possible, stream confidence metadata, and render nudges asynchronously to avoid blocking input. Prefetch prompt templates and voice guidance, cache speech models locally, and fall back to non-voice prompts on poor networks. Instrument with SLOs, alerts, and traceability to isolate slow components. Provide graceful degradation rules (e.g., limit concurrent nudges, batch updates) to preserve user flow.

Acceptance Criteria
E2E 95th-Percentile Nudge Render ≤2.0s (Ref Devices, Typical Networks)
Given a low-confidence extraction is produced during a claims intake on reference devices (iPhone 12/13, Pixel 6/7) over typical LTE/Wi‑Fi (20–80 ms RTT, 3–50 Mbps) When the nudge is detected and prepared Then the time from extraction availability to nudge visible is ≤ 2000 ms at P95 and ≤ 1200 ms at P50 across ≥ 5,000 events per platform, verified via RUM timers and traces And fewer than 0.5% of sessions exceed 2500 ms end-to-end
Asynchronous Rendering Does Not Block User Input
Given the user is typing or speaking during intake When a nudge is detected, fetched, and rendered Then keystroke latency is ≤ 50 ms at P95 and audio capture has zero dropped samples attributable to nudge processing And the UI thread is not blocked > 16 ms for more than 5 consecutive frames during render And input focus remains unchanged and caret position is preserved
Streaming Confidence Metadata Within Budget
Given the server computes confidence scores for new photos/messages When confidence metadata becomes available Then the first metadata chunk arrives at the client ≤ 250 ms at P95 after server compute completion via WebSocket And if WebSocket is unavailable, Server-Sent Events or HTTPS polling is used with added latency ≤ 300 ms at P95 And the client begins render preparation immediately upon first chunk without awaiting the full payload
Prefetch Prompt Templates, Voice Guidance, and Local Speech Model Caching
Given app cold start or session start with network available and ≥ 200 MB free storage When the nudge subsystem initializes Then prompt templates and voice guidance audio prefetch achieve a ≥ 90% cache hit rate over a rolling 7-day window And on-device speech model loads from cache ≤ 300 ms at P95 when a voice nudge is first invoked And on cache miss, model download is deferred to idle and a non-voice prompt is shown within 1200 ms at P95 without blocking input And total initial voice asset download size is ≤ 25 MB and supports resumable download
Adaptive Fallback to Non‑Voice on Poor Networks
Given network quality drops below thresholds (RTT > 200 ms or throughput < 1 Mbps or packet loss > 2%) When a voice nudge would otherwise be presented Then a non-voice prompt is shown within 1200 ms at P95 and no voice assets are fetched mid-flow And users can complete the correction via tap with added latency ≤ 100 ms versus baseline
Graceful Degradation with Concurrency Limits and Batching
Given multiple low-confidence extractions occur within a short interval When nudges are queued for display Then no more than 2 nudges are shown concurrently; additional nudges are queued And updates are batched to render at most once per 500 ms And the E2E nudge render SLO (P95 ≤ 2000 ms) is maintained under a synthetic load of 5 simultaneous extractions
Observability: SLOs, Alerts, and Traceability for Latency Breaches
Given production traffic is receiving nudges When any slice (device, network, region, version) breaches the P95 ≤ 2000 ms SLO for 5 consecutive minutes Then an alert is emitted within 5 minutes with slice metadata and top suspected components And distributed traces include spans for detection, streaming, and render with a shared correlation ID for ≥ 95% of sampled sessions And dashboards display P50/P95/P99 by component and slice with ≤ 1-minute staleness And at least 1% of sessions have full-fidelity traces for root-cause analysis

Phrase Normalizer

Maps field jargon and regional slang to standardized terms and codes (ACORD fields, cause‑of‑loss categories, part names) during transcription. Auto-expands abbreviations and harmonizes synonyms so downstream systems receive clean, consistent values. Reduces manual mapping, prevents integration errors, and improves analytics quality.

Requirements

Canonical Terminology Dictionary
"As a product administrator, I want to manage a canonical dictionary of synonyms and codes so that claims data is standardized and integrations remain consistent across all workflows."
Description

Provide a centrally managed, versioned lexicon that maps industry jargon, abbreviations, and regional slang to standardized codes and labels (e.g., ACORD fields, ISO cause-of-loss, OEM part catalogs). Supports per-line-of-business scoping (Auto, Property, GL), regional tagging, effective dating, and bulk import/export. Exposes read APIs to the NLP engine at runtime and an admin UI for CRUD operations, conflict detection, and rule testing. Ensures consistent normalization across transcription, forms, and messaging within ClaimFlow.

Acceptance Criteria
Effective Dating and Versioned Resolution
- Given multiple dictionary versions with effective_start and effective_end dates, when the NLP engine requests a mapping at a specified timestamp T, then the API returns the mapping from the version where effective_start <= T < effective_end. - Given a term that is retired (end-dated) before T, when requested, then the API returns HTTP 404 with code TERM_NOT_EFFECTIVE. - Given a future-dated change, when T is before effective_start, then the current active version is returned. - Given no applicable version exists for T, then the API returns 404 with code NO_ACTIVE_VERSION. - Given request omits T, then the API resolves using the server's current UTC time. - All responses include version_id, effective_start, and effective_end in the payload.
Line-of-Business and Regional Scoping
- Given lob and region are supplied, when a phrase maps differently by scope, then the mapping returned matches the most specific available scope in this order: lob+region > lob-only > region-only > global. - Given an unsupported lob or region value, then the API returns 400 with code INVALID_SCOPE and includes the list of allowed values. - Given overlapping rules of equal specificity exist in a published state, then the read API returns 409 with code RULE_CONFLICT and the conflicting rule identifiers. - Mapping responses include applied_scope fields: lob, region, and specificity_rank.
Abbreviation Expansion and Synonym Harmonization
- Given input phrase 'R/F Fender' in Auto-US scope, when normalized, then the API returns canonical_label 'Right Front Fender' and OEM part code per configured catalog, and ACORD field identifier if applicable. - Given known abbreviations (e.g., 'TPD', 'PD'), when normalized, then expansions match dictionary entries; unknown abbreviations are not expanded and return 422 UNMAPPED if no synonym match exists. - Given phrase variants with differing case, punctuation, or plurality, when normalized, then the same canonical_code is returned (case- and punctuation-insensitive matching). - Exact dictionary matches return confidence >= 0.99; synonym matches return confidence >= 0.90; results below thresholds return 422 LOW_CONFIDENCE with top 3 alternatives including their confidence scores.
Admin UI CRUD, Conflict Detection, and Rule Testing
- Given an admin with the 'Dictionary Editor' role, when creating a term, then required fields are enforced: canonical_code, canonical_label, lob[], region[], effective_start, synonyms[], abbreviations[]. - Given a proposed term duplicates canonical_code within an overlapping scope/effective window, when saving, then the UI blocks publish, surfaces conflict details (conflicting rule ids, scopes, dates), and saves the record as Draft until resolved. - Given a rule is edited, when the admin clicks 'Test', then the test harness returns normalization results for provided sample phrases within 500 ms P95 and shows source_rule_id and applied_scope. - All create/update/delete operations write audit logs including actor, timestamp, before/after values; audit logs are filterable and exportable to CSV.
Bulk Import/Export with Validation and Transactional Apply
- Given a valid CSV or JSON file with required columns and schema version, when imported in Dry Run mode, then the system produces a report of row-level actions (create/update/delete), conflicts, and schema errors without persisting any changes. - Given Apply mode, when any row fails validation or unresolved conflicts exist, then no changes are committed (atomicity) and the job status is Failed with a downloadable error file containing row numbers and error codes. - Given a 100k-row valid import, then the job completes within 5 minutes, increments the dictionary version once, and returns a job_id for status polling and a summary of actions taken. - Export endpoint returns a file containing active and future-dated terms filtered by scope, includes checksum and schema_version, and completes within 60 seconds for up to 1M records.
Read API Contract, Performance, and Caching
- Given GET /v1/normalize?phrase=...&lob=...&region=...&at=..., then the API returns 200 with fields: canonical_code, canonical_label, applied_scope, version_id, effective_start, effective_end, confidence, source_rule_id. - Given batch POST /v1/normalize with up to 500 items, then per-item P95 latency <= 150 ms and aggregate P95 <= 300 ms; P99 error rate < 0.1% during a 15-minute load test at 1000 RPS. - Responses include Cache-Control: max-age=60 and ETag; when the dictionary is republished, the ETag changes and conditional GETs with If-None-Match return 304. - API enforces rate limiting at 1000 requests/min/client; exceeding the limit returns 429 with Retry-After and no more than 1% of legitimate traffic is throttled during normal operation.
Cross-Channel Consistency Within ClaimFlow
- Given the same input phrase appears in transcription, web forms, and messaging for the same claim context (lob, region, timestamp), then the normalized canonical_code and canonical_label are identical across channels. - Given a new dictionary version is published, when clients have cached values, then all channels reflect the new normalization within 60 seconds of publish. - Given normalization confidence is below threshold, then all channels display the raw phrase, tag the field as Unmapped, and create a review task with a consistent task type and payload. - Analytics events from each channel include canonical_code, version_id, confidence, and applied_scope for 100% of normalized events; missing fields trigger a schema validation error in telemetry pipelines.
Real-time Transcription Normalization
"As an adjuster, I want abbreviations and slang auto-expanded and standardized while I’m capturing a claim so that I don’t need to retype or clean data later."
Description

Normalize phrases as audio, chat, and email are ingested, expanding abbreviations and mapping terms to canonical field values in real time. Annotate tokens with both original and normalized values and surface inline confirmations when user-facing. Provide structured outputs (code, label, system) to ClaimFlow’s workflow engine so downstream steps operate on clean data without manual intervention. Must perform within latency budgets (<150ms per phrase) and support offline retry for intermittent connections.

Acceptance Criteria
Audio Intake: Real-time Abbreviation Expansion and Mapping
Given a streaming audio phrase contains abbreviations, jargon, or slang When the phrase is transcribed and normalized Then normalization completes within 150 ms per phrase at P95 and within 250 ms at P99 And abbreviations are expanded to full terms in the transcript view And terms are mapped to canonical values with fields {code, label, system} And the normalized value, original text, and confidence score are stored together And no inline confirmation is shown when confidence >= 0.85 And all mappings conform to configured vocabularies (ACORD fields, cause-of-loss, part names)
Chat Intake: Inline Confirmation for Low-Confidence Normalizations
Given a user-facing chat session and a term normalizes with confidence < 0.85 When the message is displayed Then an inline confirmation UI is rendered within 150 ms of message render And up to 3 candidate normalizations are shown with {code, label, system} and confidence And the user can accept or override in 2 clicks or fewer And the selected normalization replaces the pending value and is persisted with original text and user ID/timestamp And declining a suggestion leaves the original text unnormalized and logs the event And subsequent workflow steps consume the selected normalization without manual mapping
Email Ingestion: Structured Output to Workflow Engine
Given an email intake event containing loss details When the email is parsed and phrases normalized Then for each normalized field the payload to the workflow engine includes {code, label, system, originalText, confidence, sourceChannel=email} And the payload validates against the Normalization Output schema (no validation errors) And all mapped fields reference a known vocabulary version ID And delivery to the workflow engine is acknowledged; on failure a retry is scheduled And downstream workflow executes without unmapped-field errors
Token Annotation and Char Offsets for Auditability
Given any normalized phrase from audio, chat, or email When stored Then tokens are annotated with original text, normalized value, startOffset, endOffset, and confidence And 100% of normalized tokens have non-null offsets aligned to the source transcript/message And an API endpoint returns annotations filterable by channel, sessionId, and time range And audit logs include user actions on confirmations (accept/override/decline) with timestamps
Performance Under Load: Latency and Error Rate
Given 100 concurrent intake sessions producing 10 phrases/second each When normalization runs for 10 minutes Then P95 latency per phrase < 150 ms and P99 < 250 ms And error rate (5xx or failed normalizations) <= 0.1% And CPU and memory utilization remain below configured thresholds (CPU < 75%, memory < 75%) And no backlog exceeds 1 second of phrases per session
Offline Retry, Ordering, and Idempotency
Given network connectivity is intermittently unavailable during intake When normalization requests fail to deliver to the workflow engine Then requests are queued locally and retried with exponential backoff up to 7 attempts And upon reconnection, queued phrases are delivered in original order within each session And duplicate deliveries are prevented using idempotency keys/correlationIds And after final failure, the item is dead-lettered and observable via monitoring
Regional Slang and Synonym Harmonization
Given the tenant region is configured (e.g., en-US or en-GB) When phrases contain regional slang or synonyms (e.g., "bonnet" vs "hood", "wing" vs "fender") Then mappings resolve to the correct canonical values for the configured region And per-tenant overrides take precedence over global mappings And mapping changes can be hot-reloaded without downtime and take effect within 60 seconds And if a regional mapping is missing, the system falls back to the default mapping and logs a warning
Context-aware Disambiguation Engine
"As a claims manager, I want ambiguous phrases resolved using claim context so that normalized values are accurate without increasing manual reviews."
Description

Use claim context (loss type, LOB, coverage, geography, vehicle/property attributes, stage) to resolve ambiguous terms and abbreviations. Combine rule-based heuristics with an NLP classifier to select the most probable canonical code, with configurable fallbacks. Provide tunable confidence thresholds, explainability metadata (top features, rules hit), and evaluation metrics (precision/recall by field, confusion matrices) accessible to admins. Integrates seamlessly with the dictionary and real-time pipeline.

Acceptance Criteria
Auto PD: Disambiguate 'totaled' to canonical code using context and threshold
Given claim context LOB=Auto, loss_type=Collision, geography=US-Midwest, stage=Intake, and message "the car is totaled" And the per-LOB confidence threshold for Auto is 0.85 When the disambiguation engine processes the message Then it selects the canonical code configured for 'Total Loss' in the dictionary for Auto LOB And the selected label probability is >= 0.85 And the processing time for this message is <= 75 ms at p95 measured over at least 1,000 similar events And the decision record includes model_version, dictionary_version, triggered_rules, top_5_features, and decision_probability
Property: Expand 'HVAC' and map to part code using property attributes
Given claim context LOB=Property, loss_type=Water Damage, property_type=Single Family, and note "HVAC flooded" And the dictionary contains a canonical part code for 'HVAC System' When the engine processes the note with the provided context attributes Then it expands 'HVAC' to 'Heating, Ventilation and Air Conditioning' And maps to the canonical part code for 'HVAC System' in the dictionary And emits explainability metadata listing used_context_features (e.g., property_type, loss_type, geography), and any rules_hit And processing time is <= 75 ms p95 over at least 1,000 events
Low-confidence fallback routes to Review queue with candidates
Given a configured per-LOB confidence threshold of 0.80 for Auto And an ambiguous term in an Auto claim where the top candidate probability is 0.62 When the engine evaluates the term Then the engine must not write a canonical code to downstream systems And it routes the item to the 'Needs Review' queue with the top 3 candidates and their probabilities And the event is tagged with fallback_reason='below_threshold' and is auditable by claim_id and event_id And SLA to enqueue is <= 200 ms end-to-end
Admin API/UI exposes explainability and decision details
Given an admin with role 'Claims Config Admin' When the admin requests decision details by claim_id and event_id via API or UI Then the response includes: model_version, dictionary_version, rules_hit (ids and names), top_5_features (name and weight), candidate_ranking (label, code, probability), and final_decision And the response time is <= 500 ms p95 And access is logged with user_id, timestamp, and purpose for audit
Metrics dashboard shows precision/recall and confusion matrices by field
Given a curated validation dataset with >= 2,000 annotated ambiguous mentions per target field and LOB When the admin opens the Evaluation tab and selects Field='Cause of Loss', LOB='Auto', Region='US' Then the dashboard displays precision, recall, F1 for the current model, and a confusion matrix for the selected slice And precision >= 0.92 and recall >= 0.90 on the selected slice And metrics are recomputed nightly and reflect data from the last 24 hours And the admin can export the metrics and confusion matrix as CSV
Real-time pipeline integration and resilience
Given the engine is running in the real-time intake pipeline When processing a sustained 95th percentile load of 50 events/sec Then the added latency from disambiguation is <= 75 ms p95 and <= 150 ms p99 measured over 10,000 events And on dictionary service unavailability, the engine trips a circuit breaker within 5 seconds And it falls back to local cached dictionary and rule-only disambiguation, emitting warning telemetry And all failures and fallbacks are exposed via observable metrics (rate, error, latency) using OpenTelemetry/Prometheus semantics
Configurable thresholds, rules, and fallbacks per LOB and region
Given an admin updates the Auto LOB threshold from 0.80 to 0.88 for Region='US-Midwest' and toggles rule 'Prefer OEM part names' ON When the admin saves the configuration Then a new configuration version is created with id, author, change_summary, and rollback link And changes propagate to all engine instances in <= 60 seconds And subsequent decisions reflect the new threshold and rule state And the previous version can be rolled back in <= 60 seconds, with all changes captured in the audit log
Standardized Output Mapping & API Integration
"As a systems integrator, I want normalized terms delivered in the correct standardized fields and codes so that downstream platforms ingest data without mapping errors."
Description

Emit normalized values in structured formats expected by downstream systems and partners (e.g., ACORD XML/JSON fields, internal canonical schemas). Enforce schema validation, code-set validation, and required-field checks before handoff. Provide idempotent, versioned APIs and workflow events so ClaimFlow routes clean, consistent data to policy, billing, and analytics systems. Include comprehensive error handling and retry logic with dead-letter queues.

Acceptance Criteria
ACORD JSON/XML Emission Post-Normalization
Given a transcribed claim containing slang and abbreviations When the Phrase Normalizer and standardized output mapper generate ACORD JSON and XML payloads Then the JSON validates against the configured ACORD JSON Schema with zero errors And the XML validates against the configured ACORD XSD with zero errors And required ACORD fields (e.g., causeOfLossCode, coverageTypeCode, partNameCode, lossDate) are present and non-empty And all coded fields resolve to values within the configured ACORD/partner code sets And the JSON and XML payloads are semantically equivalent by comparing a canonicalized hash of mapped fields
Required Field and Code-Set Enforcement
Given an intake missing any required mapped field per integration configuration When attempting downstream handoff Then the handoff is blocked and no payload is delivered to downstream systems And a 422 response is returned with an error list containing fieldPath, code=REQUIRED_FIELD_MISSING, and message for each missing field Given any mapped coded field not in its configured code set When attempting downstream handoff Then a 422 response is returned with code=CODESET_VIOLATION and details for each offending field Given the emitted payload fails schema structure validation When validation runs Then a 400 response is returned with code=SCHEMA_VALIDATION and a pointer to the failing schema paths
Idempotent, Versioned Ingestion API
Given a client calls POST /v1/normalized-claims without an Idempotency-Key header When the request is processed Then a 400 response is returned with code=IDEMPOTENCY_KEY_REQUIRED Given two POST requests to /v1/normalized-claims with identical bodies and the same Idempotency-Key within 24 hours When the second request is processed Then no additional downstream side effects occur and the response returns 200 with Idempotency-Replayed: true and the original response body Given two POST requests with the same Idempotency-Key but different bodies When the second request is processed Then a 409 Conflict is returned with code=IDEMPOTENCY_KEY_BODY_MISMATCH Given requests to /v1 and /v2 endpoints When responses are compared Then each version conforms to its published OpenAPI contract and changes in /v2 do not alter the /v1 response schema or semantics
Workflow Event Publication After Successful Handoff
Given a normalized payload passes all validations and the downstream handoff is accepted When processing completes Then a ClaimNormalized.v1 event is published to the topic claimflow.normalized within 2 seconds at p95 And the event payload validates against the published event JSON Schema with zero errors And the event includes claimId, policyId, correlationId, version, checksum, and codeSetVersion fields And the event contains a dedupId so consumers can safely ignore duplicates
Structured Error Responses for Validation and System Failures
Given a client input or validation error occurs When responding to the client Then the API returns 4xx with a machine-readable error object including code, message, fieldPath (if applicable), details[], and traceId, and includes X-Correlation-ID in headers Given an unexpected server error occurs When responding to the client Then the API returns 500 with code=INTERNAL_ERROR and includes traceId and X-Correlation-ID headers And all errors are logged with level=ERROR and include correlationId and traceId for end-to-end diagnostics
Retry Policy and Dead-Letter Queue for Handoffs
Given a transient downstream failure (timeouts or 5xx) occurs during handoff When retry policy executes Then retries use exponential backoff starting at 1s, doubling up to a max backoff of 60s, for up to 7 attempts or 15 minutes total, whichever occurs first And on a successful retry, the payload is marked Delivered with no duplicate side effects to downstream systems Given retries exhaust without success When the final attempt fails Then the payload and error metadata are written to the DLQ claimflow.normalized.handoff.dlq And an alert is issued to operations with claimId and failure reason And the DLQ dashboard surfaces the item with a Reprocess action that preserves original idempotency keys
Confidence Scoring & Human Review
"As a QA reviewer, I want low-confidence normalizations routed to me with suggested mappings so that I can quickly correct them and maintain data quality."
Description

Calculate confidence scores for each normalization and route cases below configurable thresholds to a dedicated review queue. Present reviewers with the original phrase, top suggestions with scores, context signals, and code definitions for rapid triage. Support one-click accept/override, keyboard shortcuts, bulk actions, and SLA tracking. Feed accepted overrides back into the system for continuous improvement and emit workflow events for audit and reporting.

Acceptance Criteria
Deterministic Confidence Scoring Per Normalization
Given an input phrase and its context When the Phrase Normalizer generates normalized suggestions Then each suggestion includes a confidence score as a float between 0.00 and 1.00 rounded to two decimals And the highest-scoring suggestion is identified as the top suggestion And given the same input, configuration, and model version When reprocessed Then the scores and ranking are identical within ±0.01 and the same top suggestion is produced And at least the top 3 suggestions are returned when available
Configurable Thresholds and Queue Routing
Given a configured review_threshold per field type (overridable per client) When a normalization result's top score is less than the effective threshold Then the item is routed to the Human Review Queue with status "Pending Review" And when the top score is greater than or equal to the effective threshold Then the normalization is auto-accepted and bypasses the review queue And when an admin updates a threshold Then new items created after the change use the updated threshold within 5 minutes and existing routed items retain their prior decision unless manually re-evaluated And the most specific threshold (client + field) takes precedence over global settings
Reviewer Panel Displays Required Context
Given a review queue item is opened When the reviewer panel loads Then it displays the original phrase text, source artifact link (message/photo), surrounding text snippet (±30 chars), detected language, region (if available), and field type And it displays the top 5 normalized suggestions with their codes, human-readable code definitions, and confidence scores And all panel data renders within 2 seconds at the 95th percentile
One-Click Accept/Override with Keyboard Shortcuts
Given a reviewer is viewing a review item When they click Accept on a suggestion or invoke its keyboard shortcut Then the decision is saved, the item is removed from the queue, the case is updated with the normalized value, and an audit record is written (user, timestamp, chosen suggestion, prior top suggestion, scores) And when they Override by selecting a different suggestion or entering a custom code and confirming via one click or shortcut Then the override is saved with equivalent audit metadata and the case is updated accordingly And keyboard shortcuts exist for Accept, Override, and Next Item and execute without mouse interaction And after action, the next item loads within 500 ms at the 95th percentile
Bulk Review Actions with Partial Success Handling
Given a reviewer multi-selects N items (N ≤ 200) in the review queue When they choose a bulk action (e.g., Accept Top Suggestion) Then the system attempts the action on each selected item and returns a per-item success/failure summary And items that have changed state since selection are skipped with a "stale" reason and are not duplicated And the bulk operation completes within 10 seconds at the 95th percentile when N ≤ 200
SLA Tracking and Escalation for Review Queue
Given an SLA policy (e.g., 4 business hours) is configured for the review queue When an item enters the queue Then an SLA deadline is computed using the tenant business calendar/time zone and stored on the item And the UI shows remaining time countdown with states: green (>50% remaining), amber (10–50%), red (<10%) And when remaining time reaches 10% of SLA Then an escalation notification is sent to the designated channel/user And when the SLA deadline passes without decision Then the item is marked Breached, a breach timestamp is recorded, and the item appears in SLA breach reports
Feedback Loop and Event Emission on Reviewer Decisions
Given a reviewer accepts or overrides a normalization When the decision is saved Then a feedback record is persisted containing original phrase, selected code, all suggestions with scores, context signals, user id, and decision type And an idempotent workflow event "Normalization.Decision" is published within 5 seconds including tenant/client id, case id, field id, chosen value, confidence, decision type, reviewer id, and correlation id And when the same phrase and context recur for the same tenant after feedback ingestion Then the chosen mapping receives a higher confidence and is auto-accepted if it meets the current threshold, or otherwise ranks above prior alternatives And feedback records are exportable and retained for at least 365 days for training and analytics
Audit Trail & Dual-Value Storage
"As a compliance officer, I want complete provenance of normalized values so that audits and disputes can be resolved with verifiable evidence."
Description

Persist both the original phrases and their normalized outputs along with canonical codes, code system, mapping source (rule/model), model version, dictionary version, timestamp, and reviewer identity (if applicable). Ensure immutability guarantees, searchable provenance, and data lineage views. Expose audit data via APIs and reports to support compliance, dispute resolution, and analytics backtesting across ClaimFlow environments.

Acceptance Criteria
Dual-Value Persistence with Codes
Given a claim intake event produces a normalized field When the normalization completes Then an audit record is created for that field capturing: claim_id, environment, field_name, original_text, normalized_text, canonical_code, code_system, mapping_source, model_version (if mapping_source = "model"), dictionary_version (if mapping_source = "rule" or "dictionary"), timestamp_utc, reviewer_identity (null) And the normalized_text and canonical_code in the audit record exactly match the values sent to downstream systems And the audit record is retrievable via the Audit API by claim_id and field_name
Immutable Audit Log with Append-Only Corrections
Given an existing audit record id When a client attempts to update or delete the record via the Audit API Then the operation is rejected and the stored record remains unchanged And any human review adjustment is recorded as a new audit record linked by previous_version_id, with reviewer_identity and review_timestamp populated And both the original and the new record are independently retrievable and time-stamped And a tamper-evident checksum or signature for each record can be verified via the Audit API
Complete Provenance: Source, Versions, Reviewer
Given a normalization produced by a rule When the audit record is stored Then mapping_source = "rule" and rule_id and dictionary_version are populated Given a normalization produced by a model When the audit record is stored Then mapping_source = "model" and model_version is populated Given a normalization adjusted by a human reviewer When the review is submitted Then mapping_source = "manual_review" and reviewer_identity and review_timestamp are populated
Searchable Lineage and Traceability API
Given multiple versions of a normalized field over time When a client calls GET /audit?claim_id={id}&field_name={name}&sort=asc Then the response lists all audit records for that field in chronological order with previous_version_id links And filtering by mapping_source, date range, and canonical_code returns only matching records And the response includes total_count and a pagination cursor when results exceed the page size
Environment-Scoped Backtesting Export
Given a request to export audit data for environment = "prod" and a date range When a client calls the export endpoint Then the system returns a downloadable file or stream containing: claim_id, environment, field_name, original_text, normalized_text, canonical_code, code_system, mapping_source, model_version, dictionary_version, timestamp_utc, reviewer_identity, previous_version_id for each record And the export includes a manifest with record_count and a checksum that validates the file content And the export can be filtered by model_version and dictionary_version
Compliance Report: Original vs Normalized with Provenance
Given a claim_id with normalized fields When a user generates the Normalization Audit report Then the report shows, for each field, original_text, normalized_text, canonical_code, code_system, mapping_source, timestamp_utc, and reviewer_identity if present And the report can be filtered by date range, field_name, and mapping_source And the report is downloadable in CSV and PDF formats
Continuous Learning & Governance Workflow
"As a taxonomy owner, I want the system to learn from corrections under an approval workflow so that the dictionary improves continuously without risking bad mappings in production."
Description

Capture reviewer corrections and field overrides as training signals to propose new synonyms or rule adjustments. Queue proposals for admin approval with impact analysis (affected fields, collision risks, test results) before publishing. Support safe rollout via versioning, environment promotion, rollback, and A/B evaluation. Provide dashboards for coverage gaps, drift detection, and quality KPIs to guide taxonomy curation.

Acceptance Criteria
Reviewer Correction Capture & Proposal Generation
- Given a reviewer modifies a normalized value during QA, When they click Save, Then the system records a training signal containing original text, prior normalized value, corrected value, target field, claim ID, reviewer ID, and UTC timestamp within 2 seconds. - Given a reviewer marks a correction as Do Not Learn, When saved, Then the signal is excluded from model training and proposal generation and is labeled as DNL in the audit log. - Given ≥3 identical corrections across ≥3 unique claims occur within a 7‑day rolling window, When the threshold is met, Then the system auto-creates a synonym/rule proposal with a suggested mapping, confidence score, and aggregated evidence links. - Given a correction is captured, When stored, Then any configured sensitive data elements are masked per data policy in the signal payload and logs.
Impact Analysis Report Generation for Proposals
- Given a synonym/rule proposal exists, When an analyst opens the proposal, Then the system displays an impact report including: affected fields and entities, potential collisions with existing rules, estimated coverage gain %, and regression test summary (precision, recall, F1, false positive delta). - Given access to a historical corpus, When impact analysis runs, Then it simulates the proposal on a configurable sample size (default 10,000 records) and completes within 15 minutes with reproducible seed and dataset snapshot ID. - Given a collision risk score ≥ configured threshold, When the report is generated, Then the proposal status is set to Blocked by Conflict and approval action is disabled until conflicts are resolved. - Given the analysis completes, When results are persisted, Then a versioned PDF/JSON report is attached to the proposal and is downloadable via API.
Admin Approval Workflow with Audit Trail
- Given a queued proposal, When an Admin views it, Then they can Approve, Reject, or Request Changes and must enter a reason comment (min 10 characters) for any decision. - Given a decision is submitted, When processed, Then the system records approver ID, decision, timestamp, diff summary, and changes the proposal status accordingly (Approved, Rejected, Changes Requested). - Given a non-Admin attempts to approve, When action is invoked, Then the system denies the action with a 403 error and logs the attempt. - Given any decision, When stored, Then the immutable audit trail is append-only and exportable (CSV/JSON) with filter by date range, user, proposal ID.
Versioning, Environment Promotion, and Rollback
- Given an Approved proposal, When published to Dev, Then a new taxonomy version is created using semantic versioning (e.g., 1.4.0) with a signed manifest and changelog link. - Given a version in Dev, When promoting to Staging or Prod, Then promotion is gated by automated regressions achieving ≥99.0% pass rate and 0 critical collisions; otherwise promotion is blocked with actionable errors. - Given a rollback is requested in Prod, When executed, Then the system restores the previous stable version within 5 minutes, routes all new requests to that version without errors, and records the rollback in the audit log. - Given a promotion or rollback completes, When checked, Then the active version per environment is visible via UI and API and consistent across nodes within 60 seconds.
A/B Evaluation and Guardrails
- Given two taxonomy versions (control and candidate), When an A/B test is configured, Then traffic split is configurable from 1% to 99% and is sticky per claim/session for the test duration. - Given the A/B test is running, When metrics are computed, Then the system reports at 15‑minute intervals: normalization accuracy on a labeled set, reviewer correction rate, and downstream integration error rate per variant. - Given KPI degradation exceeds configured thresholds for two consecutive intervals (e.g., accuracy drop >1.0 pp or error rate increase >0.2%), When detected, Then the system auto-pauses the candidate and routes 100% of traffic to control and sends alerts to the on-call channel. - Given the test ends, When results are finalized, Then the system produces a statistically annotated summary (effect sizes, confidence intervals) and archives raw metrics for 13 months.
Drift and Coverage Monitoring with Alerts
- Given live traffic, When monitoring runs hourly, Then the system computes drift per key field using PSI and flags any field with PSI > 0.2 over a 24‑hour window. - Given normalization attempts, When coverage is calculated, Then the system reports % unmatched slang/jargon and % mapped to fallback per LOB/region and creates auto-proposals for top N gaps. - Given a drift or coverage alert is triggered, When thresholds are breached, Then notifications are sent to configured channels (email/Slack/Webhook) with links to impacted samples and suggested actions. - Given monitoring configurations, When updated, Then changes take effect within 10 minutes and are versioned with rollback capability.
Quality and Governance Dashboard
- Given a user with Viewer role, When opening the dashboard, Then they can see KPIs (proposal counts by status, median approval time, coverage gap %, drift indicators, accuracy trend) with read-only access. - Given data refresh schedule, When checked, Then all widgets update at least hourly and display last refresh timestamp; historical views retain 13 months of data. - Given an Admin user, When using the dashboard, Then they can filter by environment, LOB, region, carrier, and export any widget’s underlying data to CSV within selected date ranges. - Given access control, When permissions change, Then dashboard visibility updates within 5 minutes and is enforced at API level.

Smart Pathing

Adaptive micro-forms that ask only what’s missing. Questions adjust in real time based on claim type, jurisdiction, and what’s already on file, auto-skipping verified items and inserting only the required follow-ups. Cuts claimant effort, boosts completion rates, and raises first‑pass completeness while auto-updating downstream workflow steps per answer.

Requirements

Real-time Adaptive Questioning
"As a claimant, I want the form to only ask me what’s truly needed based on my situation so that I can finish quickly without repeating or irrelevant questions."
Description

Builds and renders micro-forms on the fly based on claim type, jurisdiction, and data already on file, showing only the next necessary question. Automatically skips verified fields, inserts conditional follow-ups when answers introduce new requirements, and suppresses questions marked not applicable. Maintains answer state across steps, supports "unknown" responses with deferred follow-ups, and prevents contradictory inputs through validation and mutually exclusive choices. Ensures sub-200 ms next-question latency with client-side caching and prefetch of likely branches, and gracefully degrades to a linear path when rules cannot be evaluated. Exposes a configuration layer for product ops to author decision trees without code, and logs a decision trace for each question rendered for auditability and debugging.

Acceptance Criteria
Context-driven next question rendering
Given claim type "Auto" and jurisdiction "CA" and on-file verified fields [policyNumber, claimantName] When the micro-form session loads or the user submits any answer Then only questions required by the "Auto-CA" rules and not already answered appear And questions marked Not Applicable by rules are never rendered in UI or API payload And the next question is the highest-priority unanswered required question per rules And the question order respects declared dependencies
Auto-skip of verified fields
Given a field is present with status "Verified" in the claim record When the flow reaches the step where that field would be asked Then the question is skipped without rendering And the field is marked as completed with source "VerifiedOnFile" And the skip is reflected in progress indicators And the audit trail records the skip reason and source identifier
Immediate conditional follow-ups
Given answer "Injury involved?" = Yes When the answer is submitted Then follow-up questions [injuryType, numberOfInjured, treatmentSought] are inserted immediately after the current step And if "Injury involved?" changes to No, those follow-ups are removed and any captured answers are invalidated with reason "No longer applicable" And jurisdictional rule "NY-PhotoRequired" adds "Upload injury photos" only when jurisdiction = NY And follow-ups appear within 200 ms of submission at p95
'Unknown' responses with deferred follow-ups
Given a question supports an "Unknown" option When the user selects "Unknown" and submits Then the response is saved with value "Unknown" and timestamp and actor And a deferred follow-up task is created with due date per configuration and assigned owner And the flow continues to the next required question without blocking And the claim completeness indicator shows "Pending Info" with count incremented And when the deferred info is later provided, the task auto-closes and dependent workflow steps re-evaluate
Contradiction prevention and mutual exclusivity
Given mutually exclusive choices exist for "Vehicle condition" [Total Loss, No Damage, Minor Damage] When the user selects one option Then any conflicting options are automatically deselected And on submit with a conflict attempt, an inline validation error appears referencing rule code and resolution And the API rejects conflicting payloads with HTTP 422 and error code "RULE_CONFLICT"
Performance and graceful degradation
Given normal network conditions and a warmed client cache When the user submits an answer Then the next-question API response time is <= 200 ms at p95 and <= 300 ms at p99 over 5,000 interactions And the client renders the next question within 16 ms of receipt And the client prefetches the top 2 likely branches; prefetch hit rate >= 70% in test cohort And if the rules service times out or is unavailable, the UI switches to a linear fallback within 500 ms, displays a non-blocking notice, and continues collecting all required questions And after recovery, the flow resumes adaptive mode without re-asking already collected answers
Config authoring and decision trace logging
Given a Product Ops user with "DecisionTree.Editor" permission When they author or edit a decision tree in the configuration UI Then they can define conditions on claimType, jurisdiction, field presence, dependencies, mutually exclusive groups, and follow-up inserts without code And cyclic dependencies and unreachable nodes are prevented by validation with actionable errors And changes are versioned as drafts, previewable via a simulated micro-form, and publishable with a change log and rollback option And each rendered question emits a decision trace including rule version, inputs considered, selected branch, latency, timestamp, and session/claim identifiers And the trace is queryable per claim and exportable; PII fields are masked according to policy
Auto Pre-Fill & Evidence Verification
"As a claims manager, I want key fields pre-filled and clearly verifiable so that I reduce manual entry and trust the accuracy of the captured data."
Description

Pre-populates micro-form fields using existing claim data, policy metadata, prior messages, and extracted facts from documents and photos via the NLP engine. Displays provenance and confidence for each pre-filled value, requires confirmation when confidence is below configurable thresholds, and locks fields once verified. Allows users to view linked evidence snippets (e.g., image crop, message quote) before confirming, and supports one-tap acceptance of all high-confidence items. Prevents overwriting of user edits by subsequent data syncs, records verifier identity and timestamp, and emits verification events for downstream systems. Provides admin controls for source priority, field-level confidence thresholds, and fallback behaviors when sources disagree.

Acceptance Criteria
Pre-Fill With Provenance Display
Given a claim has existing claim data, policy metadata, prior messages, and NLP-extracted facts When the Smart Pathing micro-form loads for that claim Then fields are pre-populated according to the configured source priority And each pre-filled field displays its selected source label and a confidence score as a percentage to two decimal places And if multiple sources exist, the UI indicates the selected source and provides a View Evidence link And fields with no available sources remain empty and are flagged as Needs input
Confidence Threshold Enforcement
Given field-level confidence thresholds are configured by an admin And a field is pre-filled with a confidence below its configured threshold When the user attempts to proceed past the section or submit Then the system blocks progression and highlights the field for confirmation or correction And if a field’s confidence is at or above its threshold, the field does not require mandatory confirmation And changing a field’s value clears any prior verification status and requires re-verification
Evidence Snippet Preview
Given a pre-filled field has linked evidence When the user clicks View Evidence Then a preview opens within 500 ms showing the exact snippet (image crop or message quote) with the matched value highlighted And the user can Accept, Reject, or Close from the preview And Accept marks the field Verified; Reject clears the pre-fill and flags the field as Needs input And the system records which evidence item(s) were reviewed for the decision
One-Tap Accept High-Confidence Items
Given there are one or more pre-filled fields at or above their configured confidence thresholds and not user-edited When the user selects Accept All High-Confidence Then only those qualifying fields are marked Verified in a single action And a summary shows the count of accepted fields and any fields skipped with reasons And below-threshold or user-edited fields remain unverified and highlighted for review And a single audit entry records the bulk verification action with the list of field keys
Locking and Sync Overwrite Protection
Given a field has been Verified or manually edited by a user When a subsequent data sync provides a different value for the same field Then the existing value remains unchanged and is not overwritten by the sync And the incoming value is stored as a non-destructive suggestion with source and confidence, visible via Review updates And Verified fields are visibly locked in the UI and cannot be edited by default And any attempt to change a locked field is prevented and logged
Verifier Identity and Timestamp Audit
Given a field is Verified via individual confirmation or bulk acceptance When the verification is saved Then the system records the verifier’s user ID and an ISO 8601 timestamp And the field UI displays Verified by <user> at <timestamp> And the claim’s audit log includes the field key, value, source, confidence, verifier ID, and timestamp And exporting the claim includes verifier identity and timestamp for each Verified field
Downstream Verification Events
Given downstream integrations are configured (webhook or message bus) When any field transitions to Verified or is Rejected following evidence review Then the system emits an event within 2 seconds containing claimId, fieldKey, value, status, source, confidence, verifierId (if applicable), timestamp, and actionType And events are delivered over the configured channel and must receive a 2xx response or be retried up to 5 times with exponential backoff And failed deliveries are surfaced to admins with error details and current retry status
Jurisdictional & Line-of-Business Rules Library
"As a compliance lead, I want jurisdiction-specific requirements enforced and traceable so that every intake meets regulatory standards without manual checklists."
Description

Centralizes required fields, conditional questions, and validation rules per jurisdiction and line of business with effective-dating and versioning. Supports carrier- and program-level overrides, multi-tenant isolation, and rule provenance (citation, author, change notes). Provides a rule evaluation service used by the Smart Pathing engine to decide which questions to ask, with deterministic outcomes and performance budgets. Includes a no-code rule editor with preview, test cases, and staging environments, plus a publish workflow requiring review and approval. Maintains an audit trail of rule changes and backfills affected active sessions when a critical rule update occurs, prompting re-collection only where needed.

Acceptance Criteria
Deterministic Version Resolution by Jurisdiction, LOB, and Effective Date
Given a claim with jurisdiction=CA-ON, LOB=Auto, and asOf=2025-03-15T10:00:00Z When the rules are evaluated Then the version whose effectiveStart <= asOf < effectiveEnd is applied and the evaluation trace includes that versionId Given identical inputs (jurisdiction, LOB, asOf, claim facts) repeated 100 times When evaluated Then the question set, order, and evaluation trace hash are identical across all runs Given asOf exactly equal to effectiveEnd When evaluated Then the next version (if any) is applied per [start inclusive, end exclusive] boundaries Given no matching version for jurisdiction and LOB When evaluated Then the outcome code is NO_RULES_MATCH and the question list is empty
Carrier and Program Overrides Precedence
Given a base rule requires field `policeReportNumber`, a carrier override marks it optional, and a program override requires field `selfie` When evaluated for that carrier and program at an asOf where both overrides are effective Then `policeReportNumber` is optional and `selfie` is required in the resulting question set Given both carrier and program overrides with different effective windows When evaluated at an asOf within only one window Then only overrides effective at asOf are applied and others are ignored Given conflicting settings across layers for the same field When evaluated Then precedence is program > carrier > base, and the evaluation trace enumerates the applied layers in order
Multi-Tenant Isolation
Given Tenant A and Tenant B When a user from Tenant A queries rules or evaluates with tenantContext=A Then no rules, metadata, or traces from Tenant B are accessible; cross-tenant attempts are denied with an authorization error Given an evaluation request without tenantContext When evaluated Then the request is rejected with a validation error and no default tenant is assumed Given a full export of Tenant A rules and metadata When the export is generated Then only Tenant A data is present and record counts match in-tenant queries
No-Code Rule Editor with Preview and Test Cases
Given a rule author with Editor role When they create or edit a rule in the UI Then client- and server-side validation prevents saving with schema or logic errors and inline errors display within 200 ms of field blur Given a saved draft in Staging When Preview is run against a sample claim input Then the simulator shows the exact question set, required/optional flags, and skip logic that the evaluation service returns for those inputs Given one or more failing test cases attached to the draft When Publish is attempted Then publish is blocked and failing test cases are listed with expected vs actual deltas Given provenance fields citation, author, and changeNotes When the draft is saved Then these fields are required and persisted with the draft
Publish Workflow with Review, Approval, and Audit Trail
Given a draft ruleset in Staging When Publish is initiated Then a maker-checker workflow requires at least two distinct Approvers to approve before production activation Given all linked test cases pass and required approvals are recorded When the final approval is submitted Then the ruleset moves to Production, versionNumber increments, and the change is immutable Given any publish or rollback event When the audit log is queried Then it contains timestamp, actorId, diff of changes, provenance metadata, and approval chain; entries are read-only and exportable as CSV Given a rollback to prior version V When activated Then V becomes current for evaluations within 60 seconds
Critical Update Backfills Active Sessions
Given a rule update is marked Critical When published Then the system identifies all active Smart Pathing sessions impacted within 5 minutes and records their sessionIds for backfill Given impacted sessions When users resume their sessions Then only newly required fields or fields with changed validations are requested; previously answered unchanged items are not re-collected Given backfilled sessions are re-evaluated When downstream workflow steps are recalculated Then new tasks are inserted only where answers changed and obsolete tasks are canceled with reasons Given the backfill job completes When the summary report is generated Then it shows counts of sessions identified, notified, re-collected, and errors with error rate < 0.5%
Evaluation Service Performance and Idempotency
Given a normal load of 500 RPS with realistic payloads When the evaluation service runs for 10 minutes Then p95 latency per evaluate call <= 50 ms and p99 <= 150 ms, with error rate < 0.1% Given a burst load of 2000 RPS for 60 seconds When backpressure engages Then the service sheds load with 429s only and recovers to baseline p95 latency within 2 minutes after the burst Given identical inputs and the same ruleset version When evaluated repeatedly Then the response body and evaluation trace hash are identical (idempotent) across runs, and a deterministic cache key is emitted Given tracing is enabled for a request When the response is returned Then it includes a traceId and the list of applied ruleIds and provenanceIds for each decision
Answer-Driven Workflow Updates
"As an adjuster, I want the workflow to update automatically as the claimant answers questions so that I don’t have to manually create or re-sequence tasks."
Description

Maps answers and verification states to downstream workflow actions, automatically creating, updating, or skipping tasks in ClaimFlow based on responses. Publishes structured events (e.g., injury_reported=true) to the workflow engine, ensures idempotency, and replays updates when answers change to keep tasks in sync. Supports SLAs, assignees, and due dates derived from answers (e.g., injury within 24 hours triggers a statutory notice task) and provides a trace that links each task to the originating answers and rules. Allows adjustable severity and fallback behaviors when mappings are incomplete, and sends notifications to adjusters when critical path changes occur.

Acceptance Criteria
Create statutory notice task with SLA from injury answer
Given a claim with claimType='WorkersComp', jurisdiction='CA', injuryReported=true, and injuryReportedAt is set When the answers are saved by Smart Pathing Then the system creates a task name='Statutory Notice' with status='Open' And sets assigneeRole='Compliance' And sets dueAt = injuryReportedAt + 24h And sets priority='High' and sla='24h' And stores task.source.type='rule' and task.source.ruleId is not null
Idempotent task creation and update on repeated processing
Given a task name='Statutory Notice' already exists for claimId C sourced from ruleId R When the same answers are processed again (no effective change) Then no additional 'Statutory Notice' task is created And the existing task id remains unchanged And no task fields are modified When a derived field changes due to non-functional metadata (e.g., clock drift) but answers are identical Then the system preserves the existing task and recalculates only permissible fields (e.g., dueAt) without creating duplicates
Replay updates when answers change
Given injuryReported=false and no statutory notice task exists When injuryReported changes to true and answers are saved Then create 'Statutory Notice' with dueAt derived per rule and status='Open' And publish event injury_reported=true for the claim Given injuryReported=true and the task exists When injuryReported changes to false and answers are saved Then cancel the 'Statutory Notice' task with reason='Rule no longer applicable' And publish event injury_reported=false for the claim And the task trace shows both transitions with timestamps
Structured events emitted to workflow engine
Given any rule-to-workflow mapping fires due to an answer being created, updated, or cleared When the event is emitted Then the payload includes eventName, claimId, ruleId, answerPath, answerValue, occurredAt, and idempotencyKey And the event is published to the workflow engine topic/queue And the idempotencyKey remains stable for identical state so duplicate events are ignored by subscribers
End-to-end traceability from task to originating answers and rules
Given a task created or updated by an answer-driven mapping When the task is retrieved via API or viewed in UI Then the task detail includes: source.ruleId, source.ruleVersion, evaluationTimestamp, derivedFields {assigneeRole, dueAt, sla, priority}, and sourceAnswers[] with path and value And a 'View Rule Trace' action reveals the rule and the exact answers that triggered it
Fallback behavior and severity when mappings are incomplete
Given a required mapping is missing for an answer and severity='High' When the answer is saved Then create a 'Manual Review' task with dueAt=now+4h and priority='High' And notify the assigned adjuster via email and in-app notification within 1 minute And record a RULE_MISSING warning in the claim log and trace the fallback path Given the same condition with severity='Low' When the answer is saved Then do not create a task And record a non-blocking log entry and continue processing
Jurisdiction-based routing adjusts tasks and SLAs
Given jurisdiction='CA' and injuryReported=true with injuryReportedAt set When answers are saved Then create task name='State Notice - CA' with assigneeRole='Compliance-CA' and dueAt=injuryReportedAt+24h Given jurisdiction='TX' and injuryReported=true with injuryReportedAt set When answers are saved Then create task name='State Notice - TX' with assigneeRole='Compliance-TX' and dueAt=injuryReportedAt+48h
Save-and-Resume Across Devices
"As a claimant, I want to pause and resume my claim on another device so that I can complete it when it’s convenient without losing progress."
Description

Enables claimants to pause intake and continue on any device via secure magic links or authenticated sessions. Autosaves progress after each answer, tolerates network loss with local caching and queued sync, and resolves conflicts with last-write wins plus a review of changed fields. Supports configurable session expiry, redaction of sensitive fields in emails/SMS, and encryption at rest and in transit. Preserves decision context so that upon resume the next question remains correct even if rules have been updated, with options to prompt for re-validation only when necessary.

Acceptance Criteria
Autosave and Cross-Device Resume
Given a claimant is completing a Smart Pathing micro-form and is online When they submit an answer or 2 seconds elapse after typing stops Then the current state is persisted server-side within 1 second of the event and a resume token is updated Given the claimant opens a valid magic link on a different device within its configured TTL When the link is accessed Then the intake resumes at the next unanswered step with all prior answers pre-populated and zero data loss Given the claimant is authenticated via an existing portal session When they navigate back to the in-progress claim Then the session resumes without a magic link and at the same progression step
Offline Caching and Queued Sync
Given connectivity is lost mid-intake When the claimant continues answering Then each response is cached locally encrypted and an offline indicator is shown within 500 ms Given connectivity is restored When the app detects network availability Then queued responses are synced to the server within 5 seconds in original answer order and the offline indicator clears Given the app remains offline When 72 hours pass Then the cached progress persists and is available to resume without data loss
Conflict Resolution with Review
Given the same field is changed on two devices while one was offline When both devices sync Then the value with the latest server-received timestamp is stored (last-write-wins) and the field is flagged as "needs review" Given a field is flagged as "needs review" When the claimant resumes Then they see a review panel listing the conflicting fields with prior and current values, timestamps, and device labels Given the claimant chooses to revert a change When they confirm the selection Then the chosen value is saved, the review flag is cleared, and an audit entry records user, timestamp, old and new values
Configurable Session and Link Expiry
Given an administrator sets session expiry to 7 days and magic link TTL to 24 hours When a magic link older than 24 hours is opened Then access is denied, a secure re-auth prompt is shown, and upon successful auth the saved progress is restored Given no activity occurs for 7 days When the claimant next attempts to resume Then they must re-authenticate and continue from the last saved step without data loss Given a magic link is revoked by the user or admin When it is used Then access is denied and no PII is disclosed
Sensitive Data Redaction in Messages
Given an email or SMS containing a magic link is generated When the message includes references to answers or fields marked sensitive Then those values are redacted (masked except last 2 characters) and no raw sensitive values appear in the message body, subject, or URL Given message logs or templates are stored When they are viewed by support staff Then sensitive values remain redacted and cannot be reconstructed from stored content Given a magic link is generated When inspected Then it contains a short-lived opaque token and no inline PII or claim data
Encryption at Rest, In Transit, and Local Cache
Given data is transmitted between client and server When a connection is established Then TLS 1.2+ with strong ciphers is enforced and HTTP is redirected to HTTPS with HSTS enabled Given claimant data is stored server-side When persisted Then it is encrypted at rest using AES-256 or stronger with KMS-managed keys and documented rotation at least annually Given data is cached locally for offline use When written to device storage Then it is encrypted using the platform keystore and is unreadable when the device is locked
Decision Context Preservation and Re-Validation
Given Smart Pathing rules may change between pause and resume When a claimant resumes an in-progress intake Then the next question is computed using the rules snapshot version captured at the time of the last saved step and the rules version used is recorded in the audit log Given updated rules invalidate specific previously answered fields When the claimant resumes Then only the affected fields are marked for re-validation with clear prompts, and unaffected answers remain accepted without re-entry Given re-validation occurs When the claimant completes required confirmations Then the decision context is updated, downstream workflow steps are re-synced, and the next question remains correct and consistent
WCAG AA Accessibility & Localization
"As a claimant with accessibility needs, I want the adaptive form to work with assistive technologies and in my language so that I can complete my claim independently."
Description

Delivers Smart Pathing experiences compliant with WCAG 2.2 AA, including full keyboard navigation, screen reader labels, focus management, color contrast, and accessible error messaging. Localizes all question text, help content, and validation messages with support for RTL scripts and locale-specific formats (addresses, dates, currency, units). Provides admin tooling for translation management, fallbacks when a translation is missing, and runtime locale switching without breaking decision logic. Ensures performance and accessibility parity across mobile and desktop, and includes automated and manual accessibility testing in CI/CD.

Acceptance Criteria
Keyboard Navigation & Focus Management for Dynamic Smart Pathing
Given a user completing Smart Pathing using only a keyboard, When questions are revealed, skipped, or re-ordered based on answers, Then focus moves in a logical visual order with no keyboard traps and lands on the first interactive control of newly revealed sections. Given any modal, tooltip, or popover is opened from the form, When it is closed via Esc or action buttons, Then focus returns to the triggering control. Given any interactive element receives focus, Then a visible focus indicator is present with at least 3:1 contrast against adjacent colors and a minimum 2px outline or equivalent area, and the element remains fully visible in the viewport. Rule: All functionality is operable via keyboard (Tab, Shift+Tab, Arrow keys, Enter, Space, Esc) without requiring specific timings. Rule: Text contrast is ≥ 4.5:1 and non-text/interactive component contrast is ≥ 3:1.
Screen Reader Semantics and Live Announcements
Given Smart Pathing loads, Then landmarks and headings are structured (one H1; H2/H3 reflect hierarchy), and every control has an accessible name, role, and state via native HTML or ARIA. Given a question is dynamically inserted, updated, or removed, When a screen reader is running, Then changes are announced via aria-live="polite" without interrupting current speech. Given any label, When focus is on its input, Then the relationship is programmatic (label for/id or aria-labelledby) and the input’s purpose is unambiguous. Rule: Decorative icons are aria-hidden; meaningful images have alt text; reading order matches visual order.
Accessible Validation and Error Messaging
Given the user submits with missing or invalid inputs, When validation runs, Then focus moves to the first invalid field and an error summary appears at the top listing errors as links that move focus to each field. Rule: Each invalid field has inline error text programmatically associated via aria-describedby and does not rely on color alone; error text contrast is ≥ 4.5:1. Rule: Inputs present required/format instructions before entry (not placeholder-only), and errors are announced by screen readers when they appear. Rule: Errors are cleared and messages updated immediately upon correction without requiring a full page reload.
Localization, RTL Support, and Translation Management
Given a supported locale is selected (e.g., en-US, es-ES, fr-CA, ar-SA), Then all question text, help content, controls, system messages, and option values are localized with correct pluralization and variable interpolation. Given an RTL locale, Then layout, text alignment, iconography, and step progression mirror; html dir and lang attributes update; focus order remains logical. Given a translation key is missing, Then the UI uses the configured fallback chain (locale → language → default) without placeholder strings, and missing keys are logged for admins. Given an admin with translation permissions, When they upload/edit translations, Then the tool validates keys, flags missing/unused keys, maintains an audit trail, and supports export/import without breaking runtime.
Locale-Specific Formats and Validation Rules
Given a user enters dates, numbers, currency, addresses, and units, Then input masks, placeholders, grouping/decimal separators, and validation rules adapt to the active locale and country. Rule: User-entered values are stored in canonical formats (ISO 8601 dates, ISO 4217 currency codes with minor units, normalized numbers, standardized country-specific address schemas) independent of locale. Rule: Displayed values reflect the active locale; parsing and formatting are round-trippable without data loss. Rule: Country selection dynamically adjusts address fields and validation (e.g., postal code length/patterns).
Runtime Locale Switching Without Logic Regression
Given a user switches locale mid-session, Then all visible strings and formats update within 500 ms without a full page reload, focus is preserved, and current answers remain unchanged. Rule: Decision logic and workflow branching operate on canonical values and do not re-trigger questions or alter routing due to locale changes. Rule: Screen readers are informed of the language change (html lang updates; change is announced via a polite live region).
Performance, Mobile/Desktop Parity, and CI/CD Accessibility Gates
Rule: On mid-range mobile (simulated 4x CPU throttle, 4G), Smart Pathing’s initial view meets LCP ≤ 2.5 s, TTI ≤ 3.5 s, and interaction latency p95 ≤ 100 ms; desktop meets equal or better thresholds. Rule: Automated checks in CI/CD must pass with Lighthouse Accessibility ≥ 95, axe-core 0 critical/serious, and pa11y 0 errors; failing checks block merge. Rule: Manual assistive tech testing per release passes on JAWS + Chrome, NVDA + Firefox (Windows), VoiceOver (iOS Safari), and TalkBack (Android Chrome) for keyboard-only navigation, screen reader flow, and error handling. Rule: Accessibility features and behavior are functionally equivalent across mobile and desktop; any exceptions are documented with accessible alternatives.
Path Analytics & Experimentation
"As a product manager, I want visibility into where users drop off and the ability to test improvements so that I can continuously raise completion and first-pass accuracy."
Description

Captures granular funnel metrics (completion rate, time to complete, drop-off by question, first-pass completeness) and emits privacy-safe event streams for analysis. Provides dashboards segmented by claim type, jurisdiction, channel, and device to identify friction points and measure the impact of Smart Pathing. Supports controlled experiments on question order, wording, and UI affordances with guardrails to prevent non-compliant variants in regulated jurisdictions. Integrates with feature flags for gradual rollout, records experiment assignment in audit logs, and exposes APIs for exporting insights to BI tools.

Acceptance Criteria
Privacy-Safe Event Instrumentation
- Given a user interacts with Smart Pathing via web, mobile, or SMS, When a trackable action occurs (screen_view, question_shown, answer_submitted, validation_error, step_completed, session_ended), Then an analytics event is emitted with fields: event_name, timestamp_utc_ms, claim_id (opaque UUIDv4), session_id, user_role, jurisdiction_code, claim_type, channel, device_type, question_id (when applicable), variant_id (when applicable), schema_version, and event_id (UUID) for idempotency. - Given PII is present in the UI, When emitting analytics events, Then no raw PII values are included; sensitive fields are either omitted or irreversibly hashed with rotating salt, and a pii=false flag is set on all analytics payloads. - Given consent is required by jurisdiction, When consent is absent or revoked, Then analytics events are not sent (or only consent_change and aggregate counters are sent), and consent_state is captured without PII. - Given connectivity issues occur, When events cannot be delivered, Then events are locally queued encrypted-at-rest, retried with exponential backoff, and dropped after 72h; duplicates are prevented at the collector via event_id idempotency. - Given jurisdictional restrictions exist, When a prohibited field is configured for an event, Then the guardrail removes the field and rejects the release if removal would break schema, with a compliance test asserting the mapping per jurisdiction.
Funnel Metrics Capture and Segmentation
- Given Smart Pathing sessions occur, When events stream in, Then the system computes and stores per-day metrics: completion_rate, median_time_to_complete, p90_time_to_complete, dropoff_rate_by_question_id, and first_pass_completeness_rate (defined as zero follow-up tasks generated post-submission) using UTC event time. - Given a user applies filters for claim_type, jurisdiction, channel, and device_type, When viewing metrics, Then results reflect only the selected segment and update within 3 seconds of filter change. - Given new events arrive, When metrics are refreshed, Then end-to-end data freshness (event to dashboard) is ≤ 15 minutes and the dashboard displays last_processed_at. - Given a question_id is part of the flow, When calculating drop-off, Then drop-off is defined as percentage of sessions that reach question_shown and do not submit answer_submitted for that question before session_end or timeout.
Analytics Dashboards and Drilldowns
- Given an analytics user with analytics_viewer role opens the Path Analytics dashboard, When loaded, Then the default view shows last 7 days, overall metrics (completion_rate, time_to_complete, first_pass_completeness), and the top 5 questions by drop-off with counts and percentages. - Given a user clicks a specific question in the dashboard, When drilldown is requested, Then the view shows step-level conversion, pre/post step timing, and breakdown by device_type and jurisdiction with sortable columns. - Given an export is initiated from the current view, When CSV export is requested, Then a file is generated within 60 seconds containing the applied filters, column headers per data dictionary v1.2, values in UTC, and row counts matching the on-screen totals. - Given RBAC is enforced, When a user without analytics_viewer attempts access, Then access is denied and an access_denied event is logged without exposing data.
Controlled Experiments with Jurisdictional Guardrails
- Given an experiment is configured to test question order, wording, or UI affordances, When targeting rules are saved, Then eligible sessions are assigned deterministically using a stable hash (claim_id + session_id) and assignments are mutually exclusive across variants. - Given regulated jurisdictions have non-negotiable wording/order, When a variant violates a jurisdictional compliance rule, Then publishing is blocked with a specific validation error and no traffic is served to the non-compliant variant. - Given a session is first exposed to an experiment, When the first exposure occurs, Then an exposure event is recorded with experiment_id, variant_id, timestamp, targeting_snapshot, and is appended to an immutable audit log within 1 minute. - Given multiple experiments target overlapping surfaces, When conflicts are detected, Then the system either enforces predefined layering/holdouts or blocks activation with a conflict error prior to start.
Feature Flags and Gradual Rollout
- Given a feature flag gates Smart Pathing changes, When rollout is set to X% globally or per segment, Then observed traffic share per segment matches X within ±1 percentage point once n ≥ 10,000 sessions, and a kill switch disables the flag within 5 minutes when toggled off. - Given a user returns within 30 days, When the flag remains active and targeting unchanged, Then the user receives the same treatment (sticky bucketing) and the evaluation is logged. - Given an incident requires rollback, When the flag is set to 0%, Then all associated experiments pause automatically and an annotation appears on dashboards at the rollback timestamp.
Audit Logging and Compliance Traceability
- Given any experiment assignment or feature flag evaluation occurs, When a decision is made, Then an audit record is written with actor/service, subject (claim_id/session_id), inputs (targeting attributes), decision (on/off, experiment_id, variant_id), policy_version, and timestamp, retained for ≥ 2 years in a tamper-evident (hash-chained) store. - Given a compliance export is requested, When the export job completes, Then a signed JSONL file is produced with page size 10,000, SHA-256 checksum, delivered to a secure bucket, and both request and completion are logged with correlation_id.
Insights Export APIs for BI Tools
- Given an API client with analytics_export scope and valid OAuth2 credentials, When calling GET /api/v1/analytics/funnels with segment filters and date range, Then the API responds with HTTP 200 within 5s p95 and returns paginated results (limit, cursor) including metrics, segment keys, and last_processed_at. - Given experiment results are queried, When calling GET /api/v1/experiments/{id}/results, Then the response includes variant metrics, sample sizes, 95% confidence intervals, p-values, and an underpowered flag if minimum sample size is not met; schema is versioned. - Given rate limiting is enforced, When a client exceeds 600 requests/minute, Then the API returns 429 with Retry-After; TLS 1.2+ is required and all responses include a data dictionary version header.

Live Proofcheck

Real-time validation as claimants upload and enter data. Detects document type, page count, blur/glare, and date/name mismatches via OCR; confirms legibility and completeness; and provides instant, plain-language fix tips or auto-recapture prompts. Prevents back‑and‑forth, reduces manual QA, and delivers ingestion‑ready artifacts on the first try.

Requirements

Real-time Document Type & Page Detection
"As a claimant, I want the system to recognize the document I’m uploading and whether all pages are included so that I don’t submit the wrong file or miss pages."
Description

Classifies uploaded content as specific insurance document types (e.g., driver’s license, repair estimate, invoice, police report) and counts pages in real time during upload or capture. Detects duplicates and missing pages for multi-page documents, surfaces immediate alerts, and blocks submission until required pages are captured. Integrates with web and mobile capture flows, streaming frames to a lightweight classifier for instant feedback. Emits structured metadata (doc_type, page_count, is_duplicate) for downstream routing and fix-tip generation. Expected outcome is a reduction in wrong-file submissions and incomplete document sets, improving first-pass acceptance rates and cutting rework.

Acceptance Criteria
Web capture: real-time doc type classification and latency
Given a supported document set {driver_license, repair_estimate, invoice, police_report} and a valid image or PDF input When a claimant uploads a file or live-captures frames via web Then the system returns doc_type with top-1 confidence >= 0.90 for >= 95% of validation samples and latency <= 300 ms p95 per page/frame And When confidence < 0.60 Then doc_type = "unknown" and the document does not count toward required-document completion And Then the UI label for doc_type updates within 300 ms after each new page/frame is received
Multi-page detection and submission blocking
Given doc_type is detected and configured with min_pages for that type When a multi-page document is uploaded or sequentially captured Then page_count equals the actual number of pages with accuracy >= 99% on the validation set And When page_count < configured min_pages Then an immediate alert displays required vs. captured counts and submission is blocked until page_count >= min_pages And When page headers or footers indicate numbering (e.g., "Page X of Y") Then gaps or Y > captured are identified and the missing pages are listed
Duplicate document detection and alerting
Given a new upload or capture within the same claim session When its perceptual hash is within a Hamming distance <= 4 of an existing artifact or its content hash matches exactly Then is_duplicate = true and duplicate_of is set to the original artifact_id And Then an alert "Duplicate detected" is shown and required-document progress does not advance And The duplicate true positive rate is >= 98% and the false positive rate is <= 1% on the validation set
Mobile frame-stream classifier performance
Given the mobile capture SDK streaming camera frames to the lightweight classifier When the camera is pointed at a document Then on-device inference returns doc_type and provisional page detection feedback within 150 ms p95 on reference devices and maintains >= 15 FPS visual feedback And When on-device inference is unavailable Then the client falls back to edge inference with end-to-end latency <= 300 ms p95 And No more than 5% of frames are dropped due to inference
Metadata emission for downstream routing
Given any upload or capture event When detection completes Then a metadata payload is emitted with fields {doc_type:string, doc_type_confidence:number[0..1], page_count:int>=1, is_duplicate:boolean, artifact_id:string} And Then the payload is published to the "doc_detected" stream and available to downstream consumers within 100 ms p95 And Field names and types conform to schema version v1; unknown fields are ignored by consumers without runtime errors
Submission gating and completeness outcomes
Given the claimant is at the submission step When required documents per workflow configuration are incomplete or any required doc_type has page_count < min_pages Then the Submit action is disabled and a list of blocking items is displayed And When all blocking conditions are resolved Then the Submit action becomes enabled within 100 ms and proceeds without document-completeness errors And Over a 2-week A/B test window, first-pass acceptance rate for document completeness improves by >= 30% relative to pre-feature baseline
OCR Field Extraction & Mismatch Detection
"As a claims manager, I want uploaded documents to be checked for name, date, and policy mismatches against the claim so that errors are caught before intake."
Description

Performs OCR on uploaded documents to extract key fields (claimant name, policy number, dates of loss/service, VIN, invoice totals) and cross-checks them against the active claim context. Calculates confidence scores and flags mismatches or missing values with field-level highlights. Supports multiple languages and common insurance document formats, and normalizes outputs to standard schemas. Provides structured mismatch events to drive real-time guidance and prevents submission when critical inconsistencies are detected. Expected outcome is fewer data-entry errors, reduced manual QA, faster approvals, and lower follow-up volume.

Acceptance Criteria
OCR Extraction Accuracy and Normalization
Given a gold-standard test set of 200 insurance documents (invoices, estimates, proof-of-loss, police reports, IDs) across EN/ES/FR with clean scans (300 DPI, <=5% skew) When OCR runs on upload Then the system extracts claimant_name with F1 >= 0.97, policy_number exact-match accuracy >= 0.98, date_of_loss/service exact-match accuracy >= 0.96, VIN exact-match accuracy >= 0.98, invoice_total absolute error <= $0.01 in 95% of cases And dates are normalized to ISO 8601 (YYYY-MM-DD) and amounts to cents with currency code per ISO 4217 And VINs are normalized to 17 uppercase alphanumerics with invalid characters removed And policy numbers are normalized by stripping spaces and hyphens and uppercasing
Cross-Check and Mismatch Detection Against Claim Context
Given an active claim context containing claimant_name, policy_number, and date_of_loss And an uploaded document with extracted fields and per-field confidence scores When cross-checking runs Then exact mismatches on policy_number (after normalization) are flagged as Critical with reason=POLICY_MISMATCH And claimant_name is matched using case-insensitive, punctuation-insensitive comparison with Levenshtein distance threshold <= 2; distances > 2 are flagged as Critical with reason=NAME_MISMATCH And date_of_loss differences > 3 calendar days are flagged as Critical with reason=DATE_MISMATCH; differences <= 3 days are flagged as Warning And missing required fields are flagged as Critical with reason=MISSING_FIELD And all flags include field, extracted_value, expected_value, confidence, and normalized_value
Field-Level Highlighting in Document Viewer
Given a document preview is displayed in the Live Proofcheck UI And OCR produced bounding boxes for each extracted field When a field is flagged as mismatch or missing Then the corresponding region is highlighted in red overlay with 60% opacity and tooltip showing reason and values And overlay bounding boxes align with the text within ±5 pixels or ±1% of page width/height, whichever is greater, in 95% of cases And non-flagged extracted fields are highlighted in green on hover
Structured Mismatch Event Emission
Given any Critical or Warning flag is generated during cross-check When the flag is created Then an event with type=ocr.mismatch.v1 is published to the event bus within 500 ms of flag creation And the payload conforms to the JSON Schema contract including claim_id, document_id, field, severity, reason, extracted_value, expected_value, confidence, normalized_value, bbox, locale, and timestamp (RFC 3339) And events are idempotent by flag_id and deduplicated within a 2-minute window And 99.5th percentile end-to-end publish latency <= 1500 ms
Submission Blocking on Critical Inconsistencies
Given Critical flags exist for any of policy_number, claimant_name, or date_of_loss with confidence >= 0.8 When the user attempts to submit the document set Then the Submit action is disabled and an inline error list identifies each blocking issue with fix tips And submission becomes enabled immediately after all Critical flags are resolved or downgraded below threshold And backend submission endpoints reject attempts with unresolved Critical flags with HTTP 409 and machine-readable error codes
Multilingual and Document Format Coverage
Given documents in English, Spanish, and French across the following formats: invoice, repair estimate, proof-of-loss form, police report, government ID When OCR and classification run Then language detection accuracy >= 0.97 and field extraction F1 >= 0.92 per language on the gold set And document type classification accuracy >= 0.95 macro-average and page count detection accuracy >= 0.995 And numeric, date, and name fields are correctly localized during parsing (e.g., day-month order, thousand/decimal separators) and normalized to the standard schema
Confidence Scoring Calibration and Thresholding
Given per-field confidence scores in [0,1] When evaluated against the gold set Then scores are calibrated such that predicted probability bins are within ±0.05 of observed accuracy (ECE <= 0.05) And fields with confidence < 0.80 are labeled LowConfidence and trigger guidance prompts without blocking unless also mismatched or missing And confidence thresholds are configurable per field with default=0.80 and persisted in system settings
Image Quality Scoring with Live Retake Prompts
"As a claimant, I want live prompts to retake blurry or glary photos so that my documents are legible on the first try."
Description

Evaluates image frames and uploads for blur, glare, skew, shadows, resolution, and crop completeness in real time. Provides immediate visual and textual prompts to retake or adjust angle/lighting, and supports auto-capture when the view is steady and quality thresholds are met. Includes edge detection for page boundary guidance and automatic deskew/crop where permissible. Works offline for mobile capture with graceful degradation to server-side checks on web. Expected outcome is legible, ingestion-ready images on first capture, reducing retry loops and abandonment.

Acceptance Criteria
Mobile Real-Time Quality Scoring and Prompting
Given a claimant has opened the in-app camera, When each preview frame is processed, Then the system computes scores for blur, glare, shadow, skew, resolution, and crop completeness within 120 ms per frame on Tier-1 devices, And if any score is below threshold (blur<70/100, glare area>5% of page, shadow area>10% of page, pre-correction skew>20° or post-correction skew>1°, crop completeness<98% page included, shorter side<1200 px or longer side<1600 px), a visible on-screen tip and icon are shown within 200 ms indicating the primary issue (e.g., "Reduce glare", "Hold steady", "Move closer"), And if all thresholds are met, a "Looks good" indicator is shown within 200 ms, And the decision and per-metric scores are available in debug logs and capture metadata for QA verification.
Auto-Capture Trigger on Steady High-Quality Frame
Given the preview feed is active, When 8 consecutive frames over ≥1.0 s meet all quality thresholds and device motion is low (gyro delta <0.02 rad/s and translation <2 cm/s), Then the app auto-captures without user tap and provides a 200 ms pre-capture visual ring animation and haptic feedback, And if quality drops below thresholds before the trigger window completes, auto-capture is canceled and a "Hold steady" prompt appears, And if the user manually taps capture while below thresholds, the image is not accepted; a blocking banner lists the top failing metric(s) with fix tips and a one-tap "Retake" option.
Edge Detection with Live Guides and Auto Deskew/Crop
Given a rectangular document is in view, When edges are detectable, Then a live quadrilateral overlay snaps to the page within 50 ms and updates at ≥15 fps, And on capture, auto-crop and deskew produce an output with residual rotation ≤1° and no content loss (all page corners present with ≥2% margin), And if edges are not confidently detected for ≥500 ms, auto-capture is disabled and a "Align document inside frame" prompt appears, And when organization policy disables auto-crop, the app preserves the original image and still displays alignment guides and retake prompts.
Offline Mobile Operation with Graceful Degradation
Given the device is in airplane mode on mobile, When the user opens the capture flow, Then on-device quality scoring, prompts, edge detection, and auto-capture function without any network access, And no network requests are attempted until the session ends, And if advanced ML models are unavailable locally, the system degrades to baseline checks (resolution, exposure, edge presence) and displays a non-blocking "Limited checks offline" notice while allowing capture and retake prompts.
Web Capture Fallback to Server-Side Quality Checks
Given a claimant uses a desktop browser without supported real-time processing (e.g., no WebGL/WASM or camera permissions withheld), When the user uploads or captures an image, Then the client uploads the frame and receives server-side quality evaluation within 2 s of upload completion, And the UI presents the same issue-specific prompts (e.g., glare, blur) and a one-click "Retake/Upload new" action, And if the server response exceeds 2 s or fails, the UI shows a retry option and does not block the user from re-uploading.
Performance and Responsiveness Targets
Given reference devices (e.g., iPhone 12, Pixel 6, mid-tier Android 2021) and average indoor lighting, When the capture view starts, Then time-to-first-prompt is ≤300 ms and preview frame rate remains ≥24 fps during active scoring, And CPU utilization attributable to the module averages ≤60% on big cores with no thermal throttling over a 2-minute session, And memory usage increase stays ≤250 MB peak over baseline, And UI interactions (tap shutter, open/close tips) respond within 100 ms.
Accessible, Plain-Language Prompts and Feedback
Given any prompt is shown to the claimant, When assistive technologies are enabled (VoiceOver/TalkBack), Then all actionable controls and prompts are screen-reader accessible with descriptive labels and focus order logical, And prompt text is at or below 8th-grade reading level and localized for en-US and es-US, And visual indicators meet WCAG 2.1 AA contrast (≥4.5:1) and include non-color cues; haptic feedback accompanies auto-capture and blocking errors.
Dynamic Completeness Checklist & Rule Engine
"As an intake specialist, I want a dynamic checklist of required items based on claim type so that submissions arrive complete without follow-ups."
Description

Generates a real-time, claim-type–aware checklist of required documents and fields (e.g., ID, proof of loss, estimates, receipts) based on line of business, jurisdiction, coverage, and claim stage. Applies configurable business rules and thresholds to determine what is mandatory versus optional and blocks submission until mandatory items meet quality and match criteria. Provides admin controls to author rules, set quality confidence thresholds, and map requirements to claim attributes. Expected outcome is first-submission completeness, fewer follow-ups, and faster routing into automated workflows.

Acceptance Criteria
Real-time checklist generation by claim attributes
Given a claim with defined line of business, jurisdiction, coverage, and stage When the claim is opened or any of those attributes change Then a checklist is generated or updated within 1 second reflecting requirements mapped to the current attributes And each item is labeled Mandatory or Optional per the evaluated rules And irrelevant items are excluded from the checklist And the checklist shows a version and timestamp of evaluation
Mandatory vs optional determination and rule precedence
Given multiple rules apply to the same requirement When rules are evaluated Then precedence is applied as: Explicit Override > Jurisdiction > Line of Business > Default And the most specific scope wins in ties (e.g., coverage+stage over coverage only) And the final determination of Mandatory or Optional is stored with the rule IDs that contributed to the decision
Submission block until mandatory items meet quality and match criteria
Given a claimant attempts to submit the intake When any Mandatory requirement is incomplete, fails document-type match, has date/name mismatch, or is below quality thresholds Then submission is blocked And the blocking message lists each unmet requirement with reason and fix-tip And submission becomes enabled immediately after all Mandatory items meet their criteria without page reload
Admin authoring of rules, thresholds, and mappings
Given an authenticated admin with proper permissions When the admin creates or edits a rule that maps requirements to claim attributes and sets quality confidence thresholds Then the rule is validated for syntax and conflicts before save And the rule is versioned with author, timestamp, and effective date And a preview shows impacted requirements for a sample claim profile before publishing And the admin can rollback to a prior version
Document quality gating for requirement satisfaction
Given a document is uploaded for a checklist item When OCR detects document type and page count, and QC computes blur/glare scores Then the item is marked Satisfied only if the detected type matches the expected type, page count is within configured bounds, and quality scores meet or exceed thresholds And otherwise the item remains Unsatisfied and the user receives specific auto-recapture or fix guidance
Real-time recomputation on stage or coverage changes
Given the claim stage or coverage changes during intake When the change is saved Then the checklist is re-evaluated within 1 second And newly required items are added and highlighted And items no longer required are moved to Not Required and do not block submission And a change log records added, removed, and status-changed items
Transparent audit trail of rule evaluation
Given a user views Why required? for a checklist item When the decision details are expanded Then the system displays the evaluated rules (IDs and names), input attributes, thresholds applied, evaluation timestamp, and final decision And the details can be exported as JSON for audit purposes
Plain-Language Fix Tips & Localization
"As a claimant, I want plain, localized instructions that tell me exactly how to fix issues so that I can complete my submission quickly."
Description

Delivers contextual, plain-language guidance to resolve detected issues (e.g., “Your photo is too blurry; move closer and hold steady”) with step-by-step microcopy, icons, and short animations. Localizes tips into supported languages with region-specific terminology and ensures accessibility compliance (screen readers, high-contrast, large text). Personalizes tone and brevity to claimant context while maintaining regulatory-safe phrasing. Expected outcome is clearer self-service remediation, reduced abandonment, and higher first-pass success across demographics.

Acceptance Criteria
Blurry Image Tip and Auto-Recapture
- Given the camera preview blur score exceeds the blur threshold for 2 consecutive frames, When the claimant taps Capture or uploads a photo, Then a plain-language tip with 2–4 steps and an icon is displayed within 500 ms and an option to Retake is presented. - Given the Retake flow is active, When the blur score meets the acceptance threshold for at least 500 ms, Then auto-recapture triggers and the tip auto-dismisses. - Given the tip is displayed, When measured for readability, Then the microcopy reads at Grade 6 or below and is ≤180 characters for the primary message and fully visible on a 360×640 viewport without scrolling. - Given the claimant does not improve image quality after 2 attempts, When the third capture fails, Then the tip expands to show step-by-step guidance with a short looped animation (<3 s) demonstrating correct technique and a link to “Learn more.”
Document Type/Name/Date Mismatch Guidance
- Given OCR detects the uploaded document type is not among the expected types for the current task OR detects a name/date mismatch with the claimant profile, When the file is uploaded, Then a tip appears within 700 ms enumerating each specific issue and highlighting the conflicting value(s). - Given any blocking issue remains, When the claimant attempts to submit, Then the Submit action is disabled and an accessible explanation is announced; When all issues are resolved, Then Submit becomes enabled within 200 ms. - Given a date mismatch is detected, When showing guidance, Then the valid date range and correct field label for the claimant’s region are shown; If multiple issues exist, Then they are ordered by severity (blocking before advisory).
Spanish (US) Localization of Tips
- Given the device/browser locale is es-US or the user selects Español (EE. UU.), When any fix tip is displayed, Then all tip text, button labels, alt text, and captions render in Spanish using region-approved terminology per the glossary with no mixed-language fragments. - Given a translation key is missing for es-US, When the tip would render, Then the system falls back to English, exposes a visible language switcher, and logs a missing_translation event with key and locale. - Given Spanish is active, When viewed at 200% zoom on a 360×640 viewport, Then no text truncates or overlaps and numbers/dates are formatted per es-US conventions; readability is at Grade 6 equivalent in Spanish.
Screen Reader and Live Region Support
- Given a screen reader is active, When a new tip appears, Then its content is announced once via aria-live="polite" within 1 s and focus order remains consistent without trapping. - Given an icon conveys information in a tip, When read by assistive tech, Then it has a meaningful accessible name; decorative icons are aria-hidden. - Given a tip includes an animation, When Reduce Motion is enabled, Then a static frame replaces the animation and an accessible description is provided; otherwise, a Pause control is available and focusable. - Given keyboard-only navigation, When traversing tips, Then all interactive elements are reachable via Tab/Shift+Tab and operable via Enter/Space.
High-Contrast and Large Text Accessibility
- Given system high-contrast or in-app high-contrast mode is on, When a tip is shown, Then text meets WCAG 2.1 AA contrast (≥4.5:1), UI components/focus indicators meet ≥3:1, and link states are visually distinct. - Given the user sets text size to 200%, When viewing any tip, Then layout remains usable without truncation/overlap, critical actions remain visible without scrolling, and touch targets are ≥44×44 px. - Given dark mode is active, When tips render, Then colors maintain required contrast and do not introduce color-only cues for meaning.
Personalized Tone and Brevity Rules
- Given claimant context flags (e.g., first-time user, prior friction events ≥2, small-screen device), When generating a tip, Then the system selects a tone variant (concise, friendly, step-by-step) from a rules table and logs variant_id and rule_version. - Given the concise variant is selected, When the tip renders, Then the primary message is ≤120 characters; Given the step-by-step variant is selected, Then 2–4 numbered steps with icons are shown. - Given any variant, When passing through the readability check, Then the text is Grade 6 or below and avoids jargon per the plain-language glossary.
Regulatory-Safe Phrasing and Audit Trail
- Given a tip is generated, When evaluated by the compliance lexicon, Then prohibited phrases (e.g., guarantees, absolutes, liability-shifting) are absent; violations block rendering and trigger a lexicon_block event with offending tokens. - Given a tip is shown to a claimant, When the interaction completes, Then an audit entry is stored with timestamp, locale, variant_id, rule_version, and a SHA-256 hash of the tip text; entries are retained ≥7 years and exportable via API. - Given the claimant’s jurisdiction requires specific phrasing (e.g., CA, EU), When the tip renders, Then jurisdictional substitutions/disclaimers are applied per active rule set and recorded in the audit entry.
Ingestion-Ready Output Packaging & Workflow Handoff
"As an operations lead, I want validated documents and extracted data to be standardized and auto-routed into workflows so that manual QA and data entry are eliminated."
Description

Normalizes validated artifacts into standardized outputs: consolidated PDFs with correct page order, original media, and a structured JSON payload containing extracted fields, quality scores, and validation results. Attaches system tags (doc_type, claimant_id, claim_id, completeness_status) and pushes artifacts to ClaimFlow via internal events, APIs, or webhooks with idempotency and deduplication. Ensures downstream steps can auto-route without human QA. Expected outcome is immediate handoff into configurable workflows, eliminating manual data entry and reducing cycle time.

Acceptance Criteria
Consolidated PDF Assembly with Correct Page Order
Given a validated intake with one or more documents and images When packaging is executed Then a single consolidated PDF is produced containing all included pages And page order preserves original per-document sequence; multi-page documents remain contiguous And the PDF total page count equals the sum of included source pages And the PDF opens in standard viewers and passes integrity checks (no corruption) And identical inputs produce an identical PDF checksum to support idempotency
Structured JSON Payload with Extracted Fields, Quality Scores, and Validation Results
Given packaging completes successfully Then a structured JSON payload is generated and includes: schema_version, package_id, claim_id, claimant_id, completeness_status, artifacts[], extracted_fields[], quality_scores, validation_results And the JSON validates against the defined schema with zero errors And every extracted field includes: name, value, confidence (0.0–1.0), source {doc_id, page_number} And quality_scores provide per-page and per-field scores And validation_results list each rule with {rule_id, status, details} And every PDF page index is mapped to its source artifact(s) in the JSON
Original Media Preservation and Linkage to Outputs
Given packaging is executed Then all original media files are stored without modification and their SHA-256 checksums are recorded And JSON includes stable URIs/IDs and checksums for each original media file And each PDF page has a traceable linkage to its originating media (one-to-one or one-to-many as applicable) And if a recapture/auto-recapture occurred, both original and recaptured assets are retained and linked with role tags {original|recaptured}
System Tagging for Routing (doc_type, claimant_id, claim_id, completeness_status)
Given packaging is executed Then the consolidated PDF, original media records, and JSON payload are tagged with doc_type, claimant_id, claim_id, and completeness_status And tag values conform to controlled vocabularies and format rules (e.g., claim_id UUID/enterprise ID format) And completeness_status is set to Complete only when all required documents for the claim type are present and validated, else Incomplete And tags are present both in transport metadata and within the JSON payload
Idempotent Delivery and Cross-Transport Deduplication
Given delivery is attempted via internal event, API, or webhook and an idempotency_key is provided When the same payload is delivered again with the same idempotency_key Then the system responds with HTTP 200 (or equivalent ACK) indicating duplicate and does not create new artifacts And cross-transport duplicates are detected using package_id and content checksums within a defined time window, preventing multiple packages for the same input And concurrent duplicate deliveries result in exactly one committed package; others are de-duplicated And delivery receipts include {package_id, delivery_status, dedup=true|false} And retry logic is safe to repeat without creating duplicates
Immediate Workflow Handoff and Auto-Routing without Human QA
Given a package is successfully delivered to ClaimFlow When the routing service processes the delivery event/API/webhook Then the configured workflow starts automatically without any manual QA gate And the next workflow step is enqueued within p95 < 3s and p99 < 10s of delivery receipt And downstream steps can fetch artifacts by package_id/claim_id and receive completeness_status and tags for routing And if routing fails, the system performs automated retries and emits an alert without requiring repackaging
Validation Audit Trail & Evidence Export
"As a compliance officer, I want an audit trail of validation outcomes and what users saw so that we can evidence decisions and meet regulatory requirements."
Description

Captures an immutable log of validation checks, model versions, confidence scores, prompts shown, user actions (retakes, overrides), timestamps, and outcomes per artifact. Supports secure, role-based access, PII minimization, and retention policies aligned with regulatory requirements. Provides export-ready summaries for adjusters and compliance reviews, including why a document passed or failed and what corrections were made. Expected outcome is full traceability for internal review and external audits, reducing compliance risk and dispute resolution time.

Acceptance Criteria
Immutable Audit Log for Validation Lifecycle
Given a claimant uploads an artifact and Live Proofcheck runs validations When each validation check completes Then an append-only event is recorded containing artifact_id, validation_id, validation_type, rule_id_or_model_version, confidence_score, input_checksum, result (pass|fail), outcome_details, and timestamp in UTC ISO8601 with millisecond precision Given a client, API, or admin attempts to modify or delete an existing event When the operation is executed Then the change is rejected with 405/409, the attempt is logged as a security event, and the original event remains unchanged Given an integrity verification request for an artifact’s audit log When the system computes the hash chain/Merkle proof over the event sequence Then verification passes for untampered logs and fails for any alteration, returning the index of the first mismatched link Given transient storage or service outages during event writes When service recovers Then pending events are written exactly once using idempotency keys and original order is preserved per artifact
Comprehensive Capture of User Actions and Prompts
Given a user performs a retake, override, dismissal, or correction during Live Proofcheck When the action is submitted Then an event is recorded with user_id, user_role, action_type, targeted_field, previous_value_hash, new_value_hash (if applicable), reason_code (required for overrides), client_ip, and timestamp Given a guidance prompt or auto-recapture prompt is shown to a user When the prompt is displayed and acted upon Then prompt_id, prompt_text_hash, language, guidance_category, user_action (accepted|ignored|snoozed), and resulting outcome are recorded Given an override action missing a reason_code When the user submits the override Then the system blocks the action and returns a validation error requiring justification, and no state change occurs Given multiple sequential user actions on the same artifact When events are queried Then their order is strictly preserved and reconstructs the full decision history
Role-Based Access Controls for Audit Trail and Exports
Given an adjuster assigned to a claim When they request the audit trail summary for that claim Then access is granted and only claim-scoped data is returned with PII masked per policy Given a compliance officer with Compliance_Audit role When they request the full audit log for any claim Then access is granted; all access is logged with actor, purpose, and timestamp Given a user without Export_Audit permission When they attempt to generate or download an audit export Then the request is denied with 403 and no file is created Given any successful export download When the file is generated Then it is watermarked with requester_id, request_time, and claim_id and the download event is recorded
PII Minimization and Redaction in Logs and Exports
Given audit events contain PII fields (name, SSN, DOB, phone, address, email) When events are persisted Then values are tokenized or stored as hashes with format-preserving masking (e.g., SSN last4 only), and cleartext is excluded from the audit store Given an export is generated for a region with an active privacy policy (e.g., GDPR, CCPA) When the export content is prepared Then PII fields are redacted per policy defaults unless the requester has Compliance_Audit role and explicitly selects unredacted mode; the selection is logged Given a configuration change to PII masking rules When the new policy is activated Then subsequent events and exports apply the new rules, and the policy version is included in export metadata
Retention Policy and Legal Hold Enforcement
Given a retention policy of 7 years for LOB=Auto in region=US When an artifact’s retention end date is reached Then its audit events and generated exports are purged within 30 days, and a purge receipt (counts by object type, timestamps) is recorded Given a legal hold is applied to a claim When the retention end date elapses Then no purge occurs until the hold is lifted; hold_applied and hold_released events are recorded with actor and justification Given backups contain audit data When purge executes Then corresponding backup entries are deleted within 30 days and the deletion job produces a verifiable report with job_id and affected ranges
Export-Ready Compliance Summary with Evidence
Given an artifact with completed validations and user actions When an adjuster or compliance officer requests a compliance summary Then the system generates both JSON and PDF within 5 seconds at the 95th percentile including: pass/fail reasons, triggered rules, model_versions, confidence_scores, user overrides with reasons, prompts shown, timestamps, final disposition, and integrity checksum Given a claim with up to 50 artifacts When a single consolidated export is requested Then the file size is <= 10 MB; if exceeded, the export is chunked into sequential parts with an index manifest Given an export is generated When validation occurs Then the package is signed with the platform signing key, includes a signature and public key reference, and signature verification succeeds

Quick Prefill

One-tap confirmation of prefilled details pulled from policy and prior intake. Securely ties the SMS link to the claim, auto-populates names, policy numbers, loss dates, vehicle/property info, and relevant contact blocks so the claimant only verifies or edits. Slashes typing, lowers error rates, and speeds submissions.

Requirements

Secure SMS Link-to-Claim Binding
"As a claimant, I want to open a secure link that already knows my claim so that I can quickly verify details without re-entering my information or risking exposure of my data."
Description

Implement a cryptographically signed, single-use, time-bound token embedded in outbound SMS links that deterministically binds the recipient session to the correct claim. On open, the token authorizes read-only access to prefill context (policyholder, policy, loss, risk objects, contacts) with least-privilege scopes and optional device binding. Include replay protection, rate limiting, and automatic token rotation, with OTP fallback if the link is opened on an unrecognized device. Ensure end-to-end transport security, server-side verification, and detailed audit logging. On token verification failure, gracefully route to manual intake without exposing claim data. Integrates with ClaimFlow notifications and identity layers to ensure secure, frictionless entry into Quick Prefill.

Acceptance Criteria
Signed, Time-Bound Token Generation and SMS Link Embedding with Rotation
- Given a claim notification is triggered by ClaimFlow, when the outbound SMS link is generated, then the link contains exactly one cryptographically signed token parameter and no other identifiers (no claim ID, no PII). - Given token issuance, when the token is created, then it includes only token_id, claim_ref, scopes, iat, exp, nonce, and optional device_binding claims, with exp set to a configurable TTL between 5–60 minutes (default 15 minutes). - Given server-side verification, when the token signature or payload is tampered with, then verification fails and no claim context is returned. - Given a resend is requested, when a new token is issued, then all prior tokens for the same claim-recipient are revoked within 5 seconds and become unusable. - Given a token is opened within 2 minutes of expiry, when verification succeeds, then the server rotates to a fresh token transparently and continues the session without user action. - Given the notifications layer, when an SMS is dispatched, then the shortlink domain is from an approved allowlist and redirects preserve HTTPS only.
Single-Use Enforcement and Replay Protection
- Given a valid token is used to start a session, when a subsequent request reuses the same token, then the server responds 401 or 409 with a generic message and offers a safe path to request a new link, without revealing claim existence. - Given any attempt to use a consumed, revoked, or expired token, when verification occurs, then no prefill data is returned and the token state remains unchanged from consumed/expired. - Given network retries, when the same token_id is presented concurrently within 2 seconds from the same device, then exactly one session is allowed and others are rejected idempotently. - Given a token is intercepted and used from a different device or IP before the intended recipient, when verification occurs, then the token is rejected and flagged as suspected replay. - Given replay detection is triggered, when logging occurs, then an audit event with reason=replay_detected is written and alerts are sent to security telemetry within 60 seconds.
Deterministic Claim Binding with Least-Privilege Prefill Access
- Given a token is validated, when the session is established, then the bound claim context matches the token's claim_ref deterministically and cannot be switched by client input. - Given the Quick Prefill flow, when data is fetched, then only read-only endpoints with scope=prefill.read are accessible; any write or non-prefill endpoints return 403. - Given scope enforcement, when prefill data is returned, then only fields required for Quick Prefill are included (policyholder name, policy number, loss date, risk descriptor, contact channels) and no financials, notes, or adjuster data are present. - Given cross-claim attempts, when a user tries to access a different claim_ref, then access is denied and the original session claim_ref remains unchanged. - Given successful binding, when the UI renders, then prefilled fields match the claim data exactly and pass checksum/ETag validation.
Device Recognition with OTP Fallback for Unrecognized Devices
- Given device binding is enabled, when the link is opened on a previously recognized device, then the session is established without OTP and within 2 seconds of server verification. - Given the link is opened on an unrecognized device, when verification succeeds, then the user is prompted for a 6-digit OTP delivered via SMS to the verified number. - Given an OTP is issued, when the user enters the correct code within 5 minutes, then access is granted; after 3 failed attempts or expiry, the flow routes to manual intake. - Given OTP delivery, when sends are requested, then a maximum of 5 OTP sends per hour per claim-recipient is enforced with exponential backoff. - Given OTP validation, when mismatched phone numbers are detected, then no OTP is sent and the user is routed to manual intake without disclosing claim existence.
Token Validation Rate Limiting and Anomaly Controls
- Given the token validation endpoint, when requests exceed 30 per minute per IP or 5 per minute per token_id, then subsequent requests receive 429 with no indication of token validity. - Given burst traffic from multiple IPs against the same token_id, when thresholds are exceeded (100 attempts in 5 minutes), then the token is auto-revoked and a security alert is generated. - Given WAF integration, when known malicious patterns are detected in requests, then the request is blocked before application processing and logged. - Given rate limiting triggers, when a legitimate user subsequently accesses with a new token, then access is restored without persistent blocks. - Given configuration, when limits are updated, then changes take effect without downtime and are tracked in audit logs.
Transport Security and Server-Side Verification Safeguards
- Given an SMS link is opened, when the client connects, then TLS 1.2+ is enforced with HSTS enabled; HTTP access is disallowed and not auto-upgraded silently. - Given URL construction, when the link is generated, then no PII or claim identifiers appear in the URL path or query other than the opaque token; server and proxy logs redact the token value. - Given verification, when the token is processed, then all checks (signature, exp, revocation, scope) occur server-side; the client never decodes or inspects the token. - Given cryptographic verification, when signatures are compared, then constant-time comparison is used and keys are rotated per policy with zero downtime. - Given session establishment, when cookies are set, then they are HttpOnly, Secure, and SameSite=Lax or stricter.
Audit Logging and Graceful Degradation to Manual Intake
- Given any token lifecycle event (issued, rotated, validated, consumed, expired, revoked, failed), when it occurs, then an audit record is written including timestamp, correlation_id, token_id hash, claim_ref, event_type, device_fingerprint hash, IP, user_agent, result, and reason_code. - Given audit storage, when records are persisted, then they are append-only, tamper-evident (hash-chained), and retained per compliance policy (e.g., 7 years) with access restricted to authorized roles. - Given token verification fails for any reason, when the user flow continues, then the user is routed to the manual intake start without any prefilled data or confirmation of claim existence. - Given the manual intake route is displayed, when the page loads, then no claim data is present in HTML, API responses, or client storage, and copy uses generic language. - Given accessibility, when the failure screen renders, then it meets WCAG 2.1 AA for contrast, focus, and screen reader announcements.
Policy & Intake Data Aggregation
"As a claims manager, I want ClaimFlow to prefill claimant forms from policy and prior intake data so that submissions are faster and more accurate."
Description

Create a data aggregation service that retrieves and merges policy system records, prior intake submissions, and claim context into a canonical prefill schema. Map and normalize key fields (names, policy number, loss date, asset identifiers like VIN or property address, contact methods), preserving field-level provenance and timestamps. Apply recency and effective-date logic to select authoritative values, with configurable precedence rules by line of business. Provide resilient connectors with retry/backoff, caching, and idempotent requests to minimize latency during prefill. Expose a versioned API to the Quick Prefill UI and log payloads for traceability, while enforcing PII access controls and redaction where appropriate.

Acceptance Criteria
Canonical Prefill Schema Mapping and Normalization
Given an authenticated request with claimId and lineOfBusiness When the aggregation service is invoked Then it returns a 200 response with a payload that validates against Canonical Prefill Schema v1.0 And the payload includes required fields: claimId, lineOfBusiness, policyNumber, insured.fullName, loss.date, and one asset identifier (asset.vin or asset.property.address) And contact methods are normalized into contacts[] with method in [phone,email,sms] and values normalized (phone E.164, email RFC 5322), addresses normalized to the configured postal standard with country codes And all date/time fields use ISO 8601 (UTC) When an upstream field cannot be mapped Then it is excluded and a warning is added to metadata.warnings with code MAP_UNSUPPORTED_FIELD
Field-Level Provenance and Timestamps Preservation
Given any prefilled field in the response Then metadata.provenance exists for that field with sourceSystem, sourceType (policy|intake|context), sourceRecordId, and observedAt (ISO 8601) When effective dates are available from the source Then provenance.effectiveStart and provenance.effectiveEnd are populated for that field When a value is selected from multiple sources Then provenance.selectionReason includes ruleId, selectedSource, and candidateSources[] with at least two alternatives and their observedAt Then 100% of returned prefilled fields have provenance.sourceSystem populated
Recency and Effective-Date Resolution with LoB Precedence
Given multiple candidate values for the same field across sources When selecting the authoritative value Then the engine applies precedence rules configured for the request's lineOfBusiness When loss.date falls within a candidate's [effectiveStart, effectiveEnd) Then that candidate is prioritized over more recent observedAt values When no candidate has effective dates Then the most recent observedAt value is selected Then the selected value includes provenance.selectionReason.ruleId and selectedSource matching the applied rule And per-field decisionDurationMs is less than 5 ms When precedence configuration is changed and the service is redeployed Then new requests reflect the updated rules
Resilient Connectors with Retry/Backoff and Idempotent Requests
Given an upstream call returns HTTP 429, 5xx, or times out When the connector retries Then it uses exponential backoff with full jitter (base 200 ms, factor 2, max 3 retries) And each upstream call has a client timeout of 1500 ms; cumulative time per source does not exceed 5000 ms Given duplicate requests with the same Idempotency-Key within 5 minutes When the service processes the second request Then no duplicate upstream side effects occur and the cached result is returned with header Idempotent-Replay: true When all retries fail for a non-critical source (per configuration) Then the service returns HTTP 206 with partial prefill and metadata.warnings including code SOURCE_UNAVAILABLE and the failed source When all retries fail for a critical source (per configuration) Then the service returns HTTP 502 with error code PREFILL_UPSTREAM_FAILURE
Caching Strategy to Minimize Prefill Latency
Given a repeat request for the same claimId within TTLs (policy=10m, priorIntake=5m, claimContext=1m) When the aggregation runs Then cached results are used for those sources and no upstream calls are made Then end-to-end latency meets SLOs: cold-cache P95 ≤ 1200 ms and warm-cache P95 ≤ 600 ms measured over the last 24 hours with ≥ 1000 requests When an upstream change event is received for a cached entity Then relevant cache entries are invalidated within 60 seconds Then cache hit ratio for repeat requests within 10 minutes is ≥ 70%
Versioned API and Payload Traceability
Given a GET request to /api/prefill/v1 with claimId and valid Authorization When the request is processed Then the service responds 200 with header X-Schema-Version: 1.0 and a body conforming to that version When the client requests an unsupported API version Then the service responds 400 with error code UNSUPPORTED_API_VERSION and a list of supportedVersions Then every request and response is logged with correlationId, claimId, apiVersion, latencyMs, and outcome; PII fields are redacted per policy; logs are queryable by correlationId within 2 minutes When a breaking change is introduced Then the previous version remains available for at least 90 days and deprecation headers (Deprecation, Sunset) are included
PII Access Controls and Redaction
Given the caller's access token scopes and role When the response is built Then only fields permitted by RBAC policy are included; unauthorized fields are omitted or replaced with REDACTED and metadata.redactions lists field paths and reasons Then transport uses TLS 1.2+ and responses containing PII include Cache-Control: no-store When an unauthorized subject requests PII Then the service returns 403 with error code INSUFFICIENT_SCOPE and no PII fields in the body Then an audit record is written for each response containing PII with subjectId, claimId, fieldsServed count, timestamp, and correlationId
One-Tap Prefill Confirmation UI
"As a claimant, I want to confirm prefilled details with one tap and edit only what’s incorrect so that I can finish my submission quickly on my phone."
Description

Deliver a mobile-first, accessible UI that renders prefilled sections (policyholder, policy details, loss details, vehicle/property info, and contacts) with a single "Confirm All" action and inline, field-level edit capability. Visually differentiate prefilled fields, support quick section expand/collapse, and enable smart defaults and masked sensitive values. Persist changes in real time with optimistic updates and autosave, and handle intermittent connectivity gracefully. On confirmation, commit verified data to the claim record and trigger downstream workflow routing. Ensure compatibility with white-label theming and embed contexts within ClaimFlow’s intake flows.

Acceptance Criteria
Secure SMS Link Binding and Prefill Integrity
- Given a claimant opens the SMS intake link, When the token is exchanged, Then the session is bound to the claimId and policyId and scopes access to that claim only. - And the token is single-use, expires after first successful bind or 30 minutes of inactivity, and reuse returns 401 with a "Link expired" screen offering re-request. - When prefill data is retrieved, Then only fields in the allowed prefill schema are populated; all fields include prefillSource and prefillTimestamp in the payload. - If the link token is invalid or mismatched, Then no data is displayed and no API calls leak the existence of the claim.
Render Prefilled Sections with Visual Differentiation and Accessibility
- Given the session is bound, When the screen loads on a mobile device 360–430px width, Then sections render with prefilled values visually differentiated (badge or tint) and data-prefilled=true attributes for testability. - All colors meet WCAG AA contrast; focus order and aria labels include the "prefilled" state; tap targets are at least 44x44 px. - First Contentful Paint <= 2.0s on 3G Fast; total payload for initial render <= 1.0 MB. - Applied theme tokens (colors, fonts, spacing, radius) are respected; no default brand assets are visible.
Inline Field Edit with Optimistic Autosave and Validation
- Given a prefilled field is editable, When the user changes the value and blurs, Then the UI shows "Saving…" and updates the value immediately. - A PATCH is sent within 200ms; on 2xx, "Saved" appears within 1s with a lastSaved timestamp; the field is marked verified=false until "Confirm All". - On validation error (4xx), the field reverts to the last saved value, shows an inline error with guidance, and announces the error to screen readers. - While offline, the change is queued with status "Pending"; on reconnect, it syncs automatically in edit order; no data loss after app refresh.
Confirm All Commits and Triggers Workflow Routing
- Given all required fields are valid, When the user taps "Confirm All", Then a single commit API call with current field values and verification flags is sent and returns 2xx within 2s on 3G Fast. - The claim record persists verified=true per field with server timestamps and user context; an Intake.Verified event with correlationId is emitted for routing. - The UI transitions to the next step within 1s and disables the button during in-flight; repeated taps are idempotent (no duplicate events or updates). - If the commit fails, a non-blocking error banner appears with retry; no partial verification is applied.
Section Expand/Collapse with Progress and Accessibility
- Given sections are collapsed by default except the first, When a section is toggled, Then aria-expanded updates, the chevron rotates, and content renders within 300ms without layout shift. - Section completeness shows a checkmark when all required fields in that section are valid; counts update in real time as fields change. - Keyboard users can toggle via Enter/Space and navigate fields in logical order; open/closed state persists across navigation and reload within the session.
Masked Sensitive Values with Reveal and Audit
- Given sensitive fields exist (e.g., policy number), When rendered, Then values are masked by default and labeled "Hidden". - When "Reveal" is tapped, Then the full value is shown for up to 30 seconds and re-masked on timeout, navigation, or screen lock. - Unmasked values are never logged to analytics or client logs; copy is disabled until revealed. - An audit event is recorded with field name and reveal timestamp (no value).
Connectivity Resilience and Offline Sync
- Under simulated 150ms latency and 5% packet loss, When editing and confirming, Then autosave operations eventually succeed; retries use exponential backoff up to 5 minutes. - When offline is detected, Then an offline banner appears within 1s; edits are queued locally and marked "Pending"; navigation does not discard queued changes. - On reconnect, queued changes sync within 10s preserving field-level ordering; conflicts resolve by last-write-wins per field with a notification only if server validation fails.
Validation & Conflict Resolution Rules
"As an adjuster, I want the system to flag and resolve inconsistent prefilled data so that I can trust the submission and avoid rework."
Description

Implement a configurable validation engine that enforces format checks (e.g., policy number patterns, VIN length), semantic rules (loss date within coverage period, asset on policy), and cross-field consistency. When conflicts exist between sources (policy vs. prior intake), select a winner using configurable precedence and surface clear prompts for claimant verification. Normalize addresses, phone numbers, and names to standard formats, and provide real-time error messaging and suggestions. Log validation outcomes and unresolved conflicts for adjuster review, and expose admin-managed rule sets by line of business and jurisdiction.

Acceptance Criteria
Real-time Format Validation on Quick Prefill
Given a claimant opens the prefilled intake via secure SMS link and fields are auto-populated When a prefilled field loses focus or is edited (policy number, VIN, email) Then the system validates the value against the configured format rule within 250 ms, displays an inline error with a helpful example if invalid, and disables Submit until all format errors are resolved Given Line of Business = Auto and a VIN is present When the VIN is validated Then it must be exactly 17 characters, exclude I/O/Q, and match the configured VIN pattern; otherwise, show an inline error and a “Paste VIN from clipboard” suggestion if clipboard content matches VIN pattern Given a policy number is present When validated Then it must match the active policy-number regex for the claim’s carrier and jurisdiction; on failure, show the rule name and an example pattern Given an email or phone number is present When validated Then email must match the configured email pattern and phone must be parseable; on failure, display fix suggestions (e.g., “Add country code”)
Semantic Coverage Validation for Loss Date and Asset
Given policy effective and expiration dates are retrieved for the claim When the loss date is prefilled or edited Then the loss date must be within the coverage period (inclusive); otherwise, show a blocking error “Loss date is outside coverage period” and prevent submission Given Line of Business = Auto and a VIN is present When validating semantic rules Then the VIN must match an asset on the active policy; if not found, prompt the claimant to confirm or correct, and flag “Asset not on policy” for adjuster review Given Line of Business = Property and a loss address is present When validating semantic rules Then the loss address must match a covered location on the policy; if unmatched, require claimant confirmation and flag for adjuster review
Cross-Field Consistency by Line of Business
Given Line of Business = Auto When Incident Type = Collision Then require either “Other Party Name” or “Hit-and-run” = true, and hide property-only fields Given Contact Preference = SMS When validating cross-field dependencies Then require a valid mobile phone; if Contact Preference = Email, require a valid email address Given Loss Address Country and Postal Code are provided When validating cross-field consistency Then postal/ZIP format must correspond to the selected country; otherwise, display an inline error and prevent submission
Conflict Resolution with Configurable Source Precedence
Given conflicting values exist for a field between Policy System and Prior Intake When a precedence rule set is active (e.g., Policy > Prior Intake > Claimant Entry) Then the system selects the higher-precedence value, marks the field as “Resolved by precedence,” and records the losing value Given a field is configured as “claimant-verifiable” and a conflict is detected When displaying the prefilled form Then show a clear prompt with both values and require the claimant to choose or edit before submission Given a conflict is auto-resolved by precedence When the claimant edits the field Then the system revalidates, updates the resolution status to “Claimant override,” and logs the change
Data Normalization for Addresses, Phones, and Names
Given an address is entered or prefilled When the field loses focus Then normalize to the selected country’s postal standard with standardized casing, street suffix, and ZIP+4 when available; display the normalized form with an option to accept or revert Given a phone number is entered or prefilled When the field loses focus Then normalize to E.164, preserving country and area codes; display the normalized number and store both raw and normalized values Given a person or company name is entered or prefilled When the field loses focus Then normalize casing, remove leading/trailing whitespace, and strip invalid characters; do not alter intentional capitalization patterns beyond standard rules
Audit Logging of Validation and Conflicts
Given any validation rule executes When the outcome is produced Then log claim ID, user/session ID, timestamp (UTC), field, input value hash, normalized value hash, rule ID, rule set version, outcome (pass/fail), and any messages Given an unresolved conflict remains at submission When the claimant submits the form Then block submission if the field is mandatory; otherwise, allow submission but create an adjuster task with conflict details and link back to the field Given a claim is opened by an adjuster When viewing the Validation Log Then the adjuster can filter by rule set, field, outcome, and date range and export logs as CSV
Admin Rule Sets by LOB and Jurisdiction
Given an admin user is in the Rules console When creating or editing a rule set Then they can scope it to Line of Business and Jurisdiction(s), assign a version number, and set status (Draft, Active, Deprecated) Given multiple rule sets match a claim’s LOB and jurisdiction When evaluating rules Then the engine selects the single Active rule set with the highest version; ties are prevented by the console Given a rule set is published as Active When a new claim intake starts Then the engine loads that rule set within 200 ms and records the applied rule set ID and version on the claim
Confidence Indicators & Edit Audit Trail
"As a claims manager, I want visibility into what was auto-filled and what the claimant changed so that I can audit accuracy and improve our processes."
Description

Attach source metadata and confidence scores to each prefilled field, and display subtle confidence indicators to claimants and more detailed provenance to internal users. Track all claimant edits with before/after values, timestamps, and actor, and store an immutable audit record linked to the claim. Provide exportable audit views and events to feed QA and model training pipelines, enabling continuous improvement of extraction and mapping accuracy. Respect privacy constraints by minimizing on-screen exposure of sensitive data while retaining compliant auditability.

Acceptance Criteria
Claimant Confidence Indicator UI
Given a claimant opens a prefilled Quick Prefill form via a secure SMS link for an existing claim When any field is displayed with an associated confidence score c in [0.00, 1.00] Then a subtle indicator appears next to that field with tiers mapped as: High (c >= 0.85), Medium (0.60 <= c < 0.85), Low (c < 0.60) And numeric confidence values are not shown to the claimant And Medium/Low tiers display helper text prompting “Please review” while High does not And the indicator has an accessible name that states the tier (e.g., “Confidence: Low, please review”) And fields lacking a confidence score display an “Unknown” indicator and require explicit confirmation before submission And no source system or model details are shown in claimant-facing views
Internal Provenance Panel for Prefilled Data
Given an authenticated internal user with role Adjuster or Admin views a claim in ClaimFlow When the user expands the provenance for a prefilled field Then the panel shows: source_system, source_type (e.g., policy, prior intake, OCR/NLP), source_record_id, extractor (method), model_version, confidence_score (0.00–1.00, 2 decimals), ingest_timestamp (UTC ISO-8601), mapping_path, and transformation_rules_applied And if a source asset is available and permission allows, a “View Source” link is shown; otherwise a permission notice is displayed And if any metadata item is unavailable, a “Not available” placeholder is rendered for that item And claimant-facing screens never surface the provenance panel or its contents
Comprehensive Edit Audit Trail Capture
Given a claimant edits a prefilled field and saves or submits the form Then an audit event is appended containing: claim_id, field_key, before_value, after_value, actor="claimant", channel="SMS", timestamp_utc (ms precision), event_id, and sequence_number And multiple edits to the same field generate distinct sequential events preserving each before/after pair And a claimant’s explicit confirmation without change logs a "verified" event including value, actor, and timestamp And only committed changes (save/submit) generate audit events; transient keystrokes without commit do not
Immutable Audit Record and Integrity Verification
Given audit events are written for a claim Then events are persisted in an append-only store with write-once semantics And each event includes a sha256 hash of its contents and previous_event_hash to form a verifiable chain And a daily Merkle root over events is computed and stored separately for independent verification And attempts to modify or delete prior events are rejected by the storage layer and generate security alerts And a verification endpoint reports "valid" for an untampered chain and "invalid" if any event or linkage is altered
Audit Export and Streaming for QA and Model Training
Given an internal user with Export Audit permission applies filters (date range, claim_id(s), field_key(s), actor, confidence_tier) When the user requests an export Then the system produces a downloadable file in CSV or JSONL within 60 seconds for up to 100,000 events and returns a checksum And by default, exports redact Sensitive fields and exclude extraneous PII; values necessary for QA remain included per policy And including raw before/after values for Sensitive fields requires PII_View permission and an audit-noted justification entered by the user And webhook streaming can be configured with target URL and secret; committed events are delivered within 5 seconds with exponential backoff retries for up to 24 hours on failure
Privacy Minimization and Access Controls
Given fields are classified as Sensitive or Non-Sensitive Then claimant-facing UIs never display source metadata, raw extraction text, or numeric confidence values And internal provenance and audit views are accessible only to roles Adjuster, QA, or Admin; viewing raw before/after values for Sensitive fields requires PII_View permission And all exports default to masking Sensitive data unless explicitly overridden by a permitted user with justification captured in the audit And audit records are encrypted at rest, and all access to provenance/audit views is logged with user, timestamp, and purpose
Prefill Performance Analytics & A/B Controls
"As a product owner, I want analytics on how Quick Prefill performs and impacts completion so that I can optimize the experience and demonstrate time savings and error reduction."
Description

Instrument the Quick Prefill flow to capture funnel metrics (open rate, prefill load time, confirm rate, edit rate, error rate, completion time) and segment by channel, device, line of business, and geography. Provide configurable feature flags to enable/disable prefill or specific field groups, supporting A/B and holdout tests. Surface dashboards and export feeds to BI with privacy-safe, aggregated data, and define success KPIs and alerts (e.g., latency SLO breaches, increased edits on specific fields). Use insights to iteratively tune mappings, rules, and UI for measurable throughput and accuracy gains.

Acceptance Criteria
Funnel Metrics Instrumentation Coverage and Event Semantics
Given a claimant opens the SMS link, When the landing page renders, Then an "open" event with claim_id, session_id, and timestamp_ms is captured within 1 second of render. Given prefill begins, When data fetch is initiated, Then a "prefill_load_start" event is captured; When prefill is fully rendered, Then a "prefill_loaded" event is captured with load_time_ms = t_loaded − t_start. Given the claimant interacts, When one-tap confirm is pressed, Then a "confirm" event is captured; When a field is edited, Then an "edit" event is captured with field_group_id and field_id and diff_type (added/modified/cleared) without storing raw values. Given an error occurs, When a client or server error is encountered, Then an "error" event is captured with error_code, http_status (if applicable), and retry_count. Given a submission completes, When the claimant submits, Then a "completion" event is captured with total_duration_ms from first render. Rule: ≥95% of sessions that reach the landing page contain a coherent event sequence open → prefill_load_start → prefill_loaded before confirm/edits/completion under the same session_id.
Segmentation by Channel, Device, Line of Business, and Geography
Rule: All analytics events include dimensions channel (sms/email/portal), device_os (ios/android/other), device_type (mobile/tablet/desktop), browser_family, line_of_business (auto/home/commercial/other), and geo_country/geo_region derived from IP or claim metadata. Rule: Time is normalized to UTC with event_day and event_hour derived fields. Rule: Non-derivable dimensions are set to "unknown"; data completeness targets: ≥99% non-unknown for channel and line_of_business; ≥97% for device_os/device_type; ≥95% for geo_country. Given malformed user-agents, When parsing fails, Then device fields default to "unknown" and an internal parse_error flag is set for monitoring. Given segment filters are applied downstream, When events are queried by any single dimension, Then the filtered counts match unfiltered totals partitioned by that dimension within 0.5% for the same date range.
Feature Flags and A/B/Holdout Assignment Controls
Given prefill master flag and field_group flags, When toggled for a tenant/LOB/channel, Then changes propagate to clients within 5 minutes without redeploy and are audit-logged with actor, timestamp, and scope. Given an experiment configured with target split (e.g., 50/50), When eligible claims arrive, Then assignment is deterministic by hash(claim_id, experiment_id), sticky for 48 hours per claim, and mutually exclusive across experiments in the same namespace. Rule: Observed assignment proportion remains within ±2 percentage points of target per arm over any window of ≥10,000 assigned claims. Given a holdout of X%, When traffic flows, Then X%±2pp of eligible claims bypass prefill (or specified field_groups) and follow the default path. Given exclusion rules (e.g., region=CA or device_os=other), When a claim matches an exclusion, Then it is not assigned to the experiment and receives the default flag state. Given a user is assigned to control where prefill is disabled, When they reach the form, Then prefilled values are not displayed and manual entry is required.
Dashboards and BI Export with Freshness and Consistency
Given the analytics dashboard, When a user selects a date range, Then charts display open rate, prefill load time p50/p95, confirm rate, edit rate (overall and by field_group), error rate, and completion time p50/p95 for that range. Given filters for channel/device/LOB/geo, When filters are applied, Then all widgets update consistently and reflect the filtered population. Rule: Dashboard data freshness is ≤15 minutes delay for streaming views covering the last 24 hours. Rule: Dashboard p50 chart loads in ≤3 seconds for last 24 hours and ≤10 seconds for last 90 days under p95 of user requests. Given BI exports, When hourly exports run, Then partitioned files (parquet or csv) with schema version and event_date are delivered to the configured S3/BigQuery destination by HH:15 each hour with success markers. Rule: 7-day reconciliation: dashboard daily totals match BI export aggregates within 1% for each metric and segment. Rule: Dashboard monthly availability ≥99.5%.
Privacy-Safe Aggregation and Access Control
Rule: No raw PII (names, policy numbers, phone numbers, emails, VINs, street addresses) is stored in event payloads; only pseudonymous IDs, field_group_id/field_id, and categorical codes are retained. Rule: All data in transit uses TLS 1.2+ and at rest uses AES-256 equivalent encryption. Rule: Aggregated metric views enforce k-anonymity with k≥20; segments below threshold are suppressed or rolled up to higher-level aggregates. Given a user without Analytics role, When attempting to access dashboards or exports, Then access is denied with a 403 and the attempt is logged with user_id and timestamp. Rule: Data retention for raw events is 13 months; purge jobs run daily and log deletions with counts. Given a subject requests data removal, When a deletion request for claim_id is processed, Then associated analytics events are purged within 30 days and are excluded from future aggregates.
KPI Definitions and Alerting for Latency, Edit Rate, and Errors
Rule: For each tenant/LOB, baseline and target KPIs are stored: confirm_rate_target (e.g., +5pp over baseline), edit_rate_target per field_group, and prefill_load_time_p95_target ≤ 2000 ms. Given live traffic, When prefill_load_time_p95 exceeds 2000 ms for 5 consecutive 5-minute windows for any tenant/LOB, Then a Sev-2 alert is sent to Slack/Email/PagerDuty with affected services and top error codes. Given weekly aggregates, When edit_rate for any field_group increases by >25% week-over-week with two-proportion z-test p<0.05, Then a Sev-3 alert is created with field identifiers and segment heatmap link. Given hourly monitoring, When error_rate (events with error_code / sessions) exceeds 2% in the last hour for any segment, Then an alert is emitted and on-call is paged if sustained for 15 minutes. Rule: All alerts include runbook links and auto-close when metrics recover for 30 consecutive minutes.
Experiment Reporting and Iterative Tuning Workflow
Given an experiment with predefined primary metric(s), When minimum sample size per arm (e.g., 5,000 sessions) is reached, Then an automated report computes uplift, confidence intervals, and p-values using a predefined test and stores results with versioned artifacts. Given a statistically significant win on the primary metric at α=0.05 with power ≥0.8, When the report is approved, Then a change request is generated to promote the winning flag configuration to 100% in targeted segments. Given no significance or a regression, When the experiment completes, Then the system recommends rollback or additional sampling and documents next steps. Given field-level edit/error hotspots are detected (top 5 fields by excess edit rate vs. baseline), When weekly jobs run, Then a recommendation summary lists candidate mapping changes or UI copy tweaks with estimated impact. Rule: All experiment decisions, flag promotions, and rollbacks are audit-logged with approver, timestamp, and diffs.

AutoLocale

Delivers micro-forms in the claimant’s preferred language and reading level, detected from the conversation context. Localizes guidance, units, and date formats and auto-inserts jurisdiction-specific disclosures. Increases comprehension, reduces confusion, and supports compliant, inclusive communication at scale.

Requirements

Contextual Language Detection & Confirmation
"As a claims manager, I want the system to automatically detect a claimant’s preferred language so that I can communicate clearly without manual setup."
Description

Automatically infer the claimant’s preferred language and dialect from conversation context (incoming messages, previous interactions, device/browser locale, and policy metadata), compute a confidence score, and apply a deterministic fallback strategy with an optional one-tap confirmation prompt. Persist the selected language per claimant and per claim, support model-based detection for mixed-language threads, and expose an internal API and event to downstream components (micro-forms, guidance, disclosures) to consume the resolved locale. Ensure sub-200ms detection latency for chat, with graceful degradation to last-known locale.

Acceptance Criteria
Chat Message Language Inference with Confidence Thresholds
Given a new incoming chat message with available context (prior interactions, device/browser locale, policy metadata) When the language detection service processes the input Then it returns a BCP 47 tag (e.g., es-MX), a numeric confidence in [0.0–1.0], and the top-2 candidates with scores And the p95 end-to-end detection latency for chat is ≤ 200 ms over the last 10,000 requests And the p99 latency is ≤ 300 ms Given a detection result with confidence ≥ 0.85 When resolving the claimant’s locale for this chat Then the detected locale is applied without user prompt and recorded as auto-detected (not confirmed) Given a detection result with 0.50 ≤ confidence < 0.85 When resolving the locale Then the system applies the last-known locale if present and triggers a one-tap confirmation for the detected locale Else it applies the detected locale temporarily and triggers a one-tap confirmation Given a detection result with confidence < 0.50 and no last-known locale When resolving the locale Then the system applies the product default (en-US) and triggers a one-tap confirmation for the detected locale
Deterministic Fallback & Defaulting Order
Rule: Locale resolution order is deterministic: (1) claimant-confirmed per-claim locale, (2) claimant-confirmed global locale, (3) current-message detection (within latency budget), (4) last-known auto-detected per-claim, (5) last-known auto-detected per-claimant, (6) device/browser locale, (7) policy metadata locale, (8) product default en-US Given multiple sources are available When resolving the locale Then the earliest applicable item in the order above is selected and the chosen source is recorded Given the detector has not returned within 150 ms for chat When applying the order Then the resolver skips item (3) for this turn, proceeds to the next item, and completes resolution within an additional 50 ms budget Given any locale is resolved When persisting the decision Then the system stores: locale (BCP 47), source, confidence (if applicable), resolvedAt timestamp, and traceId Given the resolution order configuration is updated behind a feature flag When the flag is off Then production continues to use the prior order without behavior change
Locale Persistence per Claimant and per Claim
Given a locale is resolved for a claim interaction When persisting Then the system writes a per-claim record with fields: claimId, claimantId, locale (BCP 47), confirmed (bool), source, confidence (nullable), updatedAt, updatedBy (system|user) Given a claimant confirms a locale in the one-tap prompt When saving Then confirmed=true is stored for the current claim and the claimant’s global locale is updated only if the user selects “apply to all my claims” Given a new claim is created for an existing claimant with a confirmed global locale When initializing the claim Then the claim’s initial locale is set to the claimant’s confirmed global locale and marked confirmed=true, source=“claimantConfirmed” Given a subsequent auto-detection disagrees with a confirmed locale When resolving Then the confirmed locale remains in effect and no prompt is shown unless the user manually requests a change Given a persistence write is retried When the same resolution is submitted within 10 seconds Then the operation is idempotent and results in a single stored state
Mixed-Language Thread Handling
Given the last 5 user messages contain multiple languages When the model computes language distribution Then it outputs per-language weights summing to 1.0 and selects a dominant language if any weight ≥ 0.60 Given no language weight ≥ 0.60 and a prior confirmed locale exists When resolving Then the prior confirmed locale is retained and a one-tap confirmation is queued non-intrusively (no modal) for the alternative top language Given code-switching within a single message is detected When ranking candidates Then the top-2 candidates are returned; if score delta < 0.15, the result is marked lowConfidence and the confirmation prompt is triggered Given dialect cues are detected (e.g., es-MX vs es-ES) When emitting the locale Then a dialect-specific BCP 47 tag is returned; otherwise the base language tag is returned with reason=dialectAmbiguous
One-Tap Confirmation Prompt Behavior
Given locale resolution yields lowConfidence or first-time detection for this claimant/claim When presenting the UI Then a one-tap prompt appears within 300 ms showing the detected language name in both the current UI language and the detected language, with options: Confirm and Change Given the user taps Confirm When processing the action Then the locale is persisted as confirmed=true with source=userConfirmed and the prompt is dismissed without reappearing for 24 hours or until the locale changes Given the user taps Change When the language picker opens Then the user can search and select from supported locales; upon selection, the chosen locale is applied immediately and persisted as confirmed=true Given no user action within 30 seconds When the prompt times out Then the current applied locale remains, the prompt quietly dismisses, and a non-blocking reminder is allowed at most once per 24 hours Accessibility rule: The prompt, buttons, and picker are fully operable via keyboard and screen readers and meet WCAG 2.1 AA labels and contrast requirements
Internal Locale Resolution API and Event
Given a consumer requests GET /internal/locale/resolve?claimId={id}&claimantId={id} When the locale resolver handles the request Then it returns 200 with JSON: { locale, baseLanguage, region, script, confidence, confirmed, source, resolvedAt, traceId, version } where locale is a valid BCP 47 tag and version="v1" And p95 API latency ≤ 100 ms and p99 ≤ 200 ms under nominal load Given a locale is resolved or updated When publishing to the event bus Then a LocaleResolved.v1 event is emitted within 50 ms containing the same fields as the API plus claimId and claimantId Given the request references unknown IDs When resolving Then the API returns 404 only if both claimId and claimantId are unknown; otherwise it resolves using the known identifier Given a client supplies an override locale in the request with override=true When processing Then the resolver applies the override, persists it as confirmed=true with source=apiOverride, and emits the event
Performance, Timeouts, and Graceful Degradation
SLA: For chat interactions, p95 end-to-end locale resolution time (from message receipt to resolved locale applied) is ≤ 200 ms; p99 ≤ 300 ms Given the detector service returns error or exceeds 150 ms When resolving Then the resolver falls back per the deterministic order without exceeding an extra 50 ms and marks reason=fallbackTimeout or reason=detectorError Given 5 consecutive detector timeouts occur within 60 seconds When monitoring Then a circuit breaker opens for 5 minutes, all resolutions skip live detection, and an alert is sent to on-call Given the system is operating in fallback-only mode When a user interacts in chat Then no user-visible errors occur, last-known or default locale is used, and a LocaleResolved.v1 event is still emitted with source=fallback and confidence=null Observability rule: Metrics are emitted for latency, timeouts, error rates, confidence distributions, prompt trigger rates, and overrides; logs exclude PII and include traceId for correlation
Reading-Level Adaptation Engine
"As a claimant with varying literacy, I want forms written at an appropriate reading level so that I can understand and complete them accurately."
Description

Generate and deliver micro-form copy and guidance at configurable reading levels (e.g., Grade 6, 8, 10) using plain-language templates, controlled vocabulary, and automated readability scoring (e.g., FKGL), with per-locale tuning. Support fallback to nearest available level, highlight complex terms with tooltips or alternatives, and allow admins to set default reading-level policies by product line and jurisdiction. Provide an API for dynamic adjustments mid-conversation when comprehension signals drop.

Acceptance Criteria
Generate Copy at Requested Reading Level
Given a claimant locale of en-US and a requested reading level of Grade 8 When the micro-form copy and guidance are generated Then the FKGL score for the visible copy (excluding legal disclosures) is between 7.5 and 8.5 And only terms from the approved Grade 8 controlled vocabulary for en-US are present And the selected template is the en-US Grade 8 plain-language template And the response payload includes metadata fields readingLevelApplied=8, fkglScore, locale="en-US", templateId And no individual sentence exceeds FKGL 9.0
Fallback to Nearest Available Reading Level
Given the requested reading level (e.g., Grade 7) is not available and the available levels are Grade 6 and Grade 8 When the engine generates the micro-form Then the engine selects the nearest available level; if equidistant, it selects the lower level And the response metadata includes fallbackFrom=7 and fallbackTo=6 And the applied FKGL is within ±0.5 of the fallback level And an analytics event "reading_level_fallback" is emitted with conversationId and reason="level_unavailable"
Highlight Complex Terms with Tooltips or Alternatives
Given the generated copy contains terms outside the controlled vocabulary for the applied level When the micro-form is rendered Then each such term is either replaced with an approved simpler alternative or annotated with a tooltip containing a plain-language definition in the claimant's locale And tooltips are accessible via keyboard and screen reader And the presence of tooltips does not increase the computed reading level by more than 0.2 grade And at least 95% of flagged terms are replaced; no more than 5% rely solely on tooltips And highlighted terms use a consistent icon and aria-label "Definition"
Admin Policy Defaults by Product Line and Jurisdiction
Given an admin with role "Localization Admin" sets default reading-level policies via Admin API for ProductLine=Auto, Jurisdiction=CA-ON -> Grade 6; and ProductLine=Property (global) -> Grade 8 When new conversations start with matching attributes Then the engine applies Grade 6 for Auto claims in CA-ON and Grade 8 for Property claims in all jurisdictions And policy precedence is Jurisdiction+ProductLine > ProductLine > Global And overrides via conversation API are permitted and logged with actor, timestamp, oldLevel, newLevel, reason And an audit record is written for each policy change including who, when, before/after values
Dynamic Reading-Level Adjustment API Mid-Conversation
Given an active conversation with readingLevelApplied=10 and a comprehension score below threshold (e.g., 0.4) is detected When POST /conversations/{id}/reading-level/adjust is called with target=lower and an idempotencyKey Then the next generated micro-form uses the nearest lower allowed level per current policy And the API responds with 200 within 500 ms and body containing oldLevel, newLevel, effectiveAt="next_message", and reason And duplicate requests with the same idempotencyKey are idempotent and return the same newLevel And an event "reading_level_adjusted" is emitted and persisted with conversationId and trigger="low_comprehension"
Per-Locale Tuning and Readability Scoring
Given the claimant locale is es-MX and the requested reading level is Grade 6 When the copy is generated Then the engine uses the configured locale-appropriate readability metric for es-MX and achieves a score mapped to Grade 6 ±0.5 And date, number, and measurement formats are localized for es-MX And jurisdiction-specific disclosures for MX are inserted and tagged as legalDisclosure and excluded from readability scoring And the response metadata includes scoringMethod, scoreValue, readingLevelApplied, locale, and disclosureIds
Locale-aware Units, Dates, and Currency
"As a claimant, I want units and dates displayed in my familiar format so that I don’t make mistakes entering information."
Description

Localize measurement units, date/time formats, and currency presentation based on the resolved locale and jurisdiction, converting inputs and outputs as needed (e.g., inches↔centimeters, MM/DD/YYYY↔DD/MM/YYYY), and normalize captured data to system canonical units for downstream processing. Handle time zone offsets for appointment windows, ensure disambiguation in UI (e.g., month names), and support per-form section overrides where compliance requires fixed formats.

Acceptance Criteria
Locale-Dependent Unit Display with Canonical Storage
Given the resolved locale is en-US and the canonical length unit is centimeters When the claimant enters 12 in for the field "Dent Length" Then the value is stored as 30.48 cm (±0.01) in canonical storage And the claimant UI continues to display 12 in And a reviewer with locale fr-FR sees 30,48 cm for the same field And validations use canonical units (e.g., a minimum of 10 cm is satisfied)
Locale-Specific Date Entry with UI Disambiguation
Given the resolved locale is en-GB When the claimant enters 03/04/2025 in a date-only field Then the system parses as 3 April 2025 and stores 2025-04-03 (ISO 8601, date-only) Given the resolved locale is en-US When the claimant enters 03/04/2025 Then the system parses as March 4, 2025 and stores 2025-03-04 And the UI renders the chosen date with an unabbreviated month name to avoid DD/MM vs MM/DD ambiguity
Appointment Windows Converted Across Time Zones
Given the adjuster timezone is America/Los_Angeles and the claimant timezone is America/New_York When the adjuster schedules 2025-03-10 2:00–3:00 PM PT Then the claimant sees 5:00–6:00 PM ET And the window is stored as UTC start 2025-03-10T22:00:00Z and end 2025-03-10T23:00:00Z And all notifications include the local time with zone abbreviation plus the ISO 8601 timestamp with offset And times that are nonexistent or ambiguous due to DST cannot be scheduled without explicit offset selection
Currency Formatting by Locale with Canonical Normalization
Given currency code USD and amount 12345.67 in canonical value When rendered for locale en-US Then it displays as $12,345.67 Given currency code EUR and amount 12345.67 When rendered for locale fr-FR Then it displays as 12 345,67 € (locale-appropriate grouping and decimal separators) And values are stored canonically as minor units and ISO 4217 code (e.g., 1234567 + USD, 1234567 + EUR) And zero-decimal currencies (e.g., JPY) display with no decimals and store exact minor units And changing locale does not convert currency; only formatting changes
Compliance Overrides Enforce Fixed Formats Per Section
Given the "Regulatory Statement" section is configured to use fixed formats: date YYYY-MM-DD, currency "USD 1,234.56", units "cm" When the claimant locale is es-MX Then the section renders and validates exactly the configured formats regardless of locale And any input not matching the fixed formats is rejected with a localized error And stored values still normalize to canonical units and ISO formats for downstream processing
Jurisdiction-Based Currency Symbol Disambiguation
Given jurisdiction = MX and currency = MXN amount 1234.56 When rendered for a user with locale en-US Then the amount displays as MX$1,234.56 or 1,234.56 MXN (including an unambiguous currency marker) And for jurisdiction = CA with currency = CAD and user locale en-US Then the amount displays as CA$1,234.56 or 1,234.56 CAD And no amount is displayed using a symbol that is ambiguous without a code or country prefix
Jurisdictional Disclosure Injection & Consent Capture
"As a compliance officer, I want required disclosures to be auto-applied and tracked so that communications remain compliant across jurisdictions."
Description

Auto-insert jurisdiction-specific disclosures, notices, and consent language into micro-forms and messages based on detected location, policy address, or selected jurisdiction, with versioning, effective dates, and language-specific legal text. Require explicit consent where mandated, store signed consent artifacts and timestamps in the claim record, and block submission if mandatory disclosures are missing. Provide a rules engine for mapping lines of business to required texts and a content review workflow for legal sign-off.

Acceptance Criteria
Auto-insert Jurisdiction-Specific Disclosures from Context
Given a claimant opens a micro-form or an outbound message is generated, When a jurisdiction is available from explicit selection, detected device location, or policy address, Then the system determines jurisdiction using precedence: selected > detected location > policy address. Given the determined jurisdiction J and line of business L, When the micro-form renders or message is generated, Then all required disclosures, notices, and consent language mapped to (J,L) are inserted before the submission controls and above optional sections. Given insertion occurs, When the content renders, Then each inserted text displays the correct locale-specific date formats and units for J and is labeled with a clear Disclosure or Notice heading. Given content is inserted, When audit logs are checked, Then an immutable log entry records claimId, J, L, selected text IDs, version IDs, locale, and render timestamp in ISO 8601 UTC. Given performance objectives, When disclosure selection and rendering executes server-side, Then completion occurs within 300 ms at p95 for single disclosure sets.
Explicit Consent Capture and Artifact Storage
Given jurisdiction J mandates explicit consent, When the claimant views the micro-form, Then the Submit or Continue control is disabled until the consent checkbox is checked. Given consent is required, When J requires an electronic signature, Then the claimant must provide a typed full name or drawn signature per J requirements and validation enforces the mandated format. Given the claimant submits with consent, When submission occurs, Then a consent artifact (PDF or HTML snapshot) containing the exact rendered legal text, text/version IDs, J, locale, claimant inputs, and timestamp is stored with a tamper-evident hash. Given storage succeeds, When the claim record is queried, Then the consent event appears with claimant identifier, IP, user agent, geo, timezone, and UTC timestamp, and the artifact is retrievable via API and UI within 2 seconds at p95. Given future changes to legal text, When the artifact is viewed later, Then it shows the originally consented version and is immutable.
Submission Block on Missing Mandatory Disclosures
Given the rules engine indicates a mandatory disclosure for (J,L), When the micro-form is rendered without that disclosure, Then the Submit or Continue control remains disabled and an inline message lists the missing disclosure(s). Given a client-side bypass attempt, When a submission request is received server-side without required consents or disclosures, Then the API responds HTTP 400 with error code MISSING_MANDATORY_DISCLOSURE and no persisted state change occurs beyond draft. Given the block is triggered, When audit logs are reviewed, Then an event records the block, the missing text IDs, and the triggering jurisdiction context.
Rules Engine Mapping by Line of Business and Jurisdiction
Given admin-configured rules map LOB, jurisdiction, channel, and predicates (e.g., claim type, policy effective date) to required texts, When a context matches multiple rules, Then the rule with highest priority is applied; if tied, the most specific (greatest number of predicates) is applied; if still tied, the lowest rule ID is applied for determinism. Given a valid context, When rules are evaluated, Then the engine returns the complete set of required text IDs (disclosures, notices, consent language) with requirement flags (mandatory/optional) within 100 ms at p95. Given test mode, When an admin simulates a context, Then the engine returns the evaluated rule path and justification for each selected and omitted item. Given rules are edited, When a change is published, Then a new ruleset version is created with effective_from and optional effective_to and an audit entry logs editor, timestamp, and change summary.
Versioning and Effective Date Selection
Given multiple versions of a legal text exist for jurisdiction J and language X with effective dates, When content is selected at render time, Then the system chooses the latest Approved version with effective_from <= now < effective_to (or no effective_to) and records its versionId in the claim record. Given a future-dated version exists, When now is before its effective_from, Then that version is not used until its effective_from. Given a superseded version, When a previously captured consent is viewed, Then it references and displays the originally consented version without substitution. Given backdated contexts, When an admin opts to use incidentDate for effective-date evaluation, Then the system uses incidentDate instead of now and records which basis was used.
Language and Reading-Level Localization
Given the conversation indicates Spanish and a Basic reading level, When the disclosure and consent content are rendered, Then Spanish legal text is used and its readability score meets the configured target (e.g., CEFR A2–B1) verified by the readability check. Given no localized Spanish text exists for J, When rendering occurs, Then the system falls back to English and displays a localized notice indicating fallback, and a missing-translation event is logged. Given localization is applied, When dates, numbers, and units are displayed within the inserted texts, Then they follow the region-specific formats for J and language X (e.g., DD/MM/YYYY, metric vs. imperial). Given RTL languages, When content is rendered, Then directionality is correct and UI controls remain accessible per WCAG 2.1 AA.
Legal Content Review and Approval Workflow
Given a new disclosure is created, When it is saved, Then its status is Draft and it is not available for runtime selection. Given a Draft item, When it is submitted for review, Then its status moves to In Review and a Legal approver can Approve or Reject with a required comment. Given an item is Approved, When runtime selection occurs, Then only Approved items are eligible; editing an Approved item creates a new Draft version and the Approved version remains unchanged until explicitly Retired. Given workflow actions occur, When audit is queried, Then each transition records actor, role, timestamp, previous-to-new status, and comment, and only users with the Legal_Approver role can approve.
Multichannel Localized Micro-Forms
"As a claimant, I want to receive easy-to-complete, localized forms on my preferred channel so that I can finish the claim quickly without confusion."
Description

Deliver micro-forms and guidance via SMS, email, web, and in-thread chat in the claimant’s selected language and reading level, with consistent rendering and deep links that preserve claim context. Allow on-the-fly language switching without data loss, support right-to-left scripts, screen readers, and adjustable text size, and cache content for low-bandwidth scenarios. Enforce secure, expiring links and resume states to reduce drop-off and ensure data integrity.

Acceptance Criteria
Consistent Multichannel Delivery and Deep-Link Context
Given a claimant opens a micro-form from SMS, email, web portal, or in-thread chat on mobile or desktop When the form loads Then field order, labels, help text, and validation behavior are identical across channels and devices and CLS <= 0.1 Given a deep link targets step N for claim C When opened from any channel Then step N loads with claim C context and all previously entered answers pre-populated Given the same micro-form is open in two channels When a field is saved in one channel Then the other channel reflects the updated value upon refresh within 2 seconds Rule: Error messages for the same invalid input are textually identical across channels
Auto-Detected Language and Reading Level with User Override
Given conversation context infers language L with confidence >= 0.80 and reading level R When generating a micro-form Then default language is L and copy is rendered at reading level R Given the claimant changes language or reading level mid-form When confirmed Then all UI text, help, validation messages, and disclosures update within 500 ms without clearing any entered values Given a claimant returns via a different channel When the form loads Then the last selected language and reading level are applied automatically Given language detection confidence < 0.80 When the form loads Then the claimant is prompted to choose a language before fields are shown
Localized Units, Dates, and Jurisdictional Disclosures with Canonical Storage
Given locale is US When rendering measurement fields and dates Then units are imperial and dates use MM/DD/YYYY Given locale is non-US When rendering measurement fields and dates Then units are metric and dates use the locale’s standard (e.g., DD/MM/YYYY) Given jurisdiction J is determined from policy/claim data When rendering the form Then jurisdiction-specific disclosures for J are displayed and acceptance (checkbox/tap) is required before submission and timestamped Given localized values are submitted When persisting to the claim record Then values are converted to canonical units (SI) and ISO 8601 date format and the selected locale is stored alongside
Right-to-Left Script Layout and Mixed-Content Handling
Given selected language is RTL (e.g., Arabic, Hebrew) When the form renders Then layout direction is RTL, text is right-aligned, and UI components are mirrored appropriately Rule: Numeric inputs, email addresses, URLs, and code fields remain LTR within RTL layouts Rule: Punctuation and list markers are positioned correctly for RTL languages
Accessibility Compliance and Adjustable Text Size
Given a claimant uses a screen reader (VoiceOver, TalkBack) When navigating the form Then all interactive elements have descriptive labels, logical focus order, and role semantics; error messages are announced via aria-live Given the claimant increases system text size to 200% When viewing any step Then content reflows without horizontal scrolling and without loss of information or functionality Rule: Color contrast ratio for text and interactive elements is >= 4.5:1 and all functionality is operable via keyboard
Low-Bandwidth Optimization and Content Caching
Given network throughput <= 400 Kbps When the initial form step is requested Then time-to-first-interaction is <= 2.5 seconds and total initial payload is <= 200 KB Rule: Static assets (CSS/JS/translations) are cached for at least 72 hours and reused across form steps Given connectivity drops mid-step When the claimant resumes within 72 hours Then previously loaded content is available and entered answers are preserved locally and synced on reconnect
Secure Expiring Links and Resume State Integrity
Given a micro-form access link is issued When opened after its TTL (default 24 hours) Then access is denied with a generic message and no PII is revealed Rule: Each access link contains a signed, single-use token bound to claim ID and scope; token rotation occurs on resend and prior tokens are invalidated Given a claimant resumes an in-progress form with a valid token When the form loads Then the last saved state is restored and all field values are intact without duplication or corruption Given an access attempt with an altered or mismatched token-claim pair When validation occurs Then access is denied and the event is logged for audit
Localization Admin & Content Management Console
"As a localization admin, I want a console to configure and preview localized content so that I can safely roll out updates without breaking workflows."
Description

Provide an admin console to manage languages, dialects, translation memory, reading-level templates, and jurisdictional disclosure catalogs. Enable preview by locale, channel, and reading level; staged publishing and rollbacks; feature flags; and integration with translation vendors or in-house translators. Include validation checks for missing keys, placeholder mismatches, date/unit rules, and accessibility warnings before publish.

Acceptance Criteria
Manage Languages and Dialects Library
Given I am an Admin user in the Localization Console When I add a new locale with code "es-MX" and set fallback to "es" Then the locale appears in the locales list with status "Draft" and inherits untranslated keys from "es" in preview Given locale "fr-CA" exists and is not referenced by any published content When I delete "fr-CA" Then it is removed and no preview or publishing references remain Given locale "pt-BR" is referenced by a published version When I attempt to delete "pt-BR" Then the system blocks deletion and displays dependent assets count and links Given a locale is set to "Disabled" When a request resolves it in preview or publish Then content for that locale is not served and a fallback is used according to hierarchy
Translation Vendor Integration and In-House Workflow
Given a translation vendor API is configured with valid credentials When I submit 120 new/changed strings for locales ["es-MX","fr-FR"] Then a job is created per locale, job IDs are stored, and job status is updated at least every 5 minutes until "Complete" or "Failed" Given vendor jobs complete successfully When the system imports results Then the number of imported translations equals the number of submitted strings per locale and each key maps 1:1 with placeholders preserved Given an in-house translator "user@example.com" is assigned to locale "de-DE" When I create a translation task for 45 strings Then the assignee sees the task in their queue, can mark strings "Translated" or "Needs Clarification", and the task status updates to "In Review" when all strings are translated Given an XLIFF file is imported for "it-IT" When key conflicts are detected Then the system presents a diff, allows accept/reject per key, and records an audit log of decisions
Reading-Level Templates Management and Enforcement
Given a reading-level template "RL8" exists for "en-US" with max grade 8 When I run validator on a micro-form assigned to "RL8" Then any string exceeding grade 8 is flagged with location, score, and suggestion, and publish is blocked until flags are resolved or the reading-level is changed Given multiple reading-level templates exist (RL6, RL8, RL10) When I preview "en-US" content with RL6 Then simplified variants are shown where available and fallback to base text is indicated for missing simplified variants Given I clone template "RL8" to "RL8-Claims" When I edit guidelines and save Then a new template version is created with incremented semantic version and an impact report lists affected strings
Jurisdictional Disclosure Catalog and Rules
Given a disclosure "CA-Subrogation" is configured for jurisdiction "CA" with effective dates and placement "Footer" When I preview a micro-form for locale "en-CA" with jurisdiction "CA" Then the disclosure appears in the footer with the current effective version Given a form is targeted to multiple jurisdictions (e.g., TX, NY) When I publish Then all required jurisdictional disclosures are auto-inserted without duplication and each is traceable via a rule ID Given a disclosure's text is updated When I save Then the system creates a new version, retains the prior version for rollback, and updates the usage report of affected forms
Preview by Locale, Channel, and Reading Level
Given I select locale "es-MX", channel "SMS", and RL6 When I open preview for micro-form "LossDetails" Then text appears in Mexican Spanish, message length segments respect SMS limits, dates are formatted as "dd/mm/yyyy", units are metric, and jurisdictional disclosures render if applicable Given some keys are missing in "es-MX" When "Fallback" is enabled Then missing strings are filled from "es" and highlighted as fallback When "Fallback" is disabled Then missing strings are indicated as missing with counts Given I switch channel from "SMS" to "Web" When I refresh preview Then responsive web layout is shown and content wrapping and pagination reflect channel-specific constraints
Staged Publishing, Feature Flags, Versioning, and Rollback
Given there is a Draft configuration "v1.3.0" When I publish to "Staging" Then staging receives "v1.3.0" within 2 minutes and production remains on its prior version Given feature flag "AutoLocale_MicroForms_v1_3_0" is Off in Production When I enable it for 10% of users in locale "pt-BR" on channel "Web" Then only that cohort receives the new content and telemetry shows exposure within 10 minutes Given "v1.3.0" causes issues When I perform a rollback to "v1.2.4" in Production Then clients receive "v1.2.4" within 5 minutes and version history shows the rollback event with actor, timestamp, and reason
Pre-Publish Validation: Keys, Placeholders, Date/Unit Rules, Accessibility
Given a release candidate is ready When I run "Pre-Publish Validation" Then the report shows zero errors for missing keys, zero placeholder mismatches (e.g., {claim_id}, {date}), zero date/unit rule violations for selected locales, and any accessibility warnings list affected strings with guideline references Given any error is present When I attempt to publish Then the Publish action is disabled with links to resolve each error, and after fixes the validator re-runs automatically and enables publishing on pass Given placeholders are positional in some locales When a translation reorders placeholders Then ICU or positional syntax is required and validated to prevent runtime formatting errors
Audit Logging & Decision Traceability
"As a compliance auditor, I want traceable logs of localization and disclosure decisions so that I can verify regulatory adherence and investigate issues."
Description

Record a complete audit trail of locale resolution decisions, content versions served, disclosure variants, consent events, and user overrides, with timestamps and actor attribution. Expose searchable logs per claim and exportable reports for compliance audits, while redacting PII according to retention policies. Provide metrics hooks to correlate localization decisions with completion rates and follow-up reduction.

Acceptance Criteria
Locale Resolution Decision Logged
Given a claim intake session triggers AutoLocale When the system resolves preferred language and reading level from conversation context Then an immutable audit log entry is created containing: claim_id, session_id, decision_id (UUIDv4), timestamp (ISO-8601 UTC), actor="system", resolved_locale (BCP-47), reading_level_value, reading_level_scale (e.g., FKGL/CEFR), model_version, confidence_score (0–1), signal_types_used (e.g., message_language, geo_ip, prior_claim_locale), and source_message_ids referenced And the entry is queryable under the claim within 1 second of the decision And the entry includes prev_hash and entry_hash for tamper-evidence And duplicate decision_id writes are rejected with no duplicate log entries created
Content Version and Disclosure Variant Logging
Given localized micro-forms and guidance are rendered and jurisdiction-specific disclosures are auto-inserted When content is served to a claimant or adjuster Then an audit log entry records: claim_id, message_id, content_template_id, content_version_id, rendering_locale, unit_system (e.g., metric/imperial), date_format (e.g., DD/MM/YYYY), disclosure_variant_id, jurisdiction_code, effective_date, and the associated locale decision_id And if jurisdiction changes mid-claim, a new disclosure_variant_id is logged with supersedes_id referencing the prior disclosure event And all entries include actor, timestamp, and contain no raw PII beyond pseudonymous IDs And every served content entry can be joined back to its triggering decision_id in queries
Consent Events Capture with Actor Attribution
Given a disclosure is presented in a localized micro-form When a claimant explicitly gives, declines, or revokes consent Then a consent_event is logged with: claim_id, session_id, message_id, event_type in {consent_given, consent_declined, consent_revoked}, disclosure_variant_id, actor_type (claimant/adjuster/system), actor_id (pseudonymous), timestamp (ISO-8601 UTC), channel (web/sms/email), locale, and device_type And consent is only recorded upon explicit user action; no inferred consent events are logged And the current consent state per claim can be computed from the latest event and retrieved via query And exported consent logs exclude PII such as names, emails, and full IPs (store IP with last two octets redacted)
User Override Traceability and Rollback
Given an adjuster overrides the system-resolved locale or reading level When the override is submitted Then an audit entry is created linking to the prior decision_id, capturing new locale and/or reading level, reason_code (from a controlled list), actor_id, actor_role, timestamp, and override_id And the platform supports reverting to any prior decision_id; each revert creates a new audit entry with revert_of set to the target decision_id And all content served after an override references the override_id/decision_id that governed rendering And if the override affects disclosures, a re-disclosure_required flag is logged and the subsequent disclosure event is recorded before further content is served
Searchable Logs and Exportable Compliance Reports
Given a compliance user with the appropriate role accesses claim audit logs When filters (claim_id, date range, actor, event_type, locale, jurisdiction, decision_id) are applied Then the system returns matching results within 2 seconds for up to 10,000 records and supports pagination beyond that And exports to CSV and JSON are available with selectable fields, defaulting to PII-redacted outputs (emails hashed, phone masked, addresses removed) And each export includes the filter criteria, a generation timestamp, and a checksum for integrity And all search and export actions are themselves audit-logged with user, timestamp, and parameters (excluding any PII) And access is restricted to authorized roles and denied otherwise with no data leakage
PII Redaction and Retention Policy Enforcement
Given environment-configured retention policies (e.g., raw_message_content=30 days, audit_metadata=365 days) and legal_hold flags per claim When the nightly retention job runs Then records exceeding policy are purged or PII fields are irreversibly redacted according to policy while preserving structural metadata (event_type, timestamps, ids) And a retention_run event is logged with counts of purged vs redacted records and any errors And queries after retention confirm no PII is returned for out-of-policy records And claims on legal_hold are exempt from purge/redaction until hold is lifted, with hold_set and hold_released events logged
Metrics Hooks for Outcome Correlation
Given localization decisions and subsequent claimant interactions occur When events are emitted to the metrics pipeline Then the following events are produced with no PII: localization_decision_made, microform_viewed, microform_completed, followup_triggered, override_made, disclosure_presented, consent_event And each metrics event includes: decision_id, claim_id, locale, reading_level_value, reading_level_scale, jurisdiction_code, disclosure_variant_id, content_version_id, override_flag, timestamp, and channel And events are delivered to configured sinks within 60 seconds with at-least-once delivery; measured drop rate in staging soak tests is <0.1% And dashboards/queries can compute completion_rate and followup_rate segmented by locale, reading level, and jurisdiction using these events

TapSign

Built-in lightweight e-sign and attestations inside the micro-form. Claimants acknowledge statements with a tap or draw/typed signature; signatures are hashed and bound to the submission event for auditability. Eliminates separate e-sign flows, captures consent in context, and accelerates approvals.

Requirements

In-Form Multi-Mode Signature Capture
"As a claimant, I want to sign or acknowledge directly within the claim micro-form so that I can complete my submission without being redirected to a separate e-sign process."
Description

Provide embedded signature components within the micro-form that support tap-to-acknowledge, draw (handwritten), and typed name modes on mobile and desktop. Enforce completion rules (e.g., cannot submit until a selected signature mode is completed), auto-save progress, and gracefully handle resize, orientation changes, and low-bandwidth conditions. Capture signature artifacts (image/vector for draw, text and font metadata for typed, event record for tap) along with device, browser, and session metadata, while meeting accessibility standards (WCAG 2.2 AA) with keyboard navigation, screen reader labels, and sufficient touch targets.

Acceptance Criteria
Completion Rules: Block Submission Until Signature Completed
Given a required signature component is present and no signature mode is completed When the user attempts to submit via click, tap, or Enter Then the submission is blocked And a field-level error message is displayed and announced to assistive technologies And focus moves to the signature component Given a user selects a signature mode (Tap/Draw/Typed) When the selected mode is successfully completed Then the form marks the signature requirement as satisfied And the Submit button becomes enabled Given a signature is completed in one mode When the user switches to a different mode Then the system prompts to confirm discarding the prior signature And upon confirmation the prior artifact is cleared and the form returns to incomplete until the new mode is completed Given saved progress exists with a completed signature When the form is reloaded Then the completion state is restored and submission remains enabled
Tap-to-Acknowledge: Capture and Validation
Given a consent statement with a tap-to-acknowledge control is displayed When the user activates the control via click, tap, or Space/Enter Then the system records a signature event including statementId, controlId, timestamp (ISO-8601), and sessionId And the control reflects the acknowledged state Given the control is acknowledged When the user toggles it off before submission Then the form marks the signature as incomplete and displays a validation message on submit Given a tap acknowledgment is recorded When the user submits the form Then the tap event record is included in the submission payload and bound to the submissionId And a cryptographic hash of the event record and submissionId is generated and persisted
Drawn Signature: Capture, Export, and Persistence
Given Draw mode is selected When the user draws with mouse, touch, or stylus Then strokes are captured as vector paths and rendered in a preview Given drawing is completed When the user taps Confirm Then an image artifact (PNG) and a vector artifact (SVG or JSON) are generated with width, height, and devicePixelRatio metadata And the signature is marked as completed Given a drawn signature exists When the page is reloaded or the device orientation or viewport size changes Then the signature persists without distortion and maintains aspect ratio And the preview scales to fit while preserving stroke fidelity Given a drawn signature exists When the user selects Clear Then the canvas is reset and the completion state is cleared
Typed Signature: Capture and Font Metadata
Given Typed mode is selected When the user enters their name and selects a font from the allowed list Then the system renders a preview And captures the typed text, font family, font variant, and a font file hash or version identifier Given the name field is empty or contains unsupported characters outside letters, spaces, apostrophes, and hyphens When the user attempts to confirm Then a validation error is shown and confirmation is blocked Given a typed signature is confirmed When the user submits the form Then the text and font metadata are included in the submission payload and bound to the submissionId
Auditability: Hashing and Metadata Bound to Submission
Given any signature mode is completed When the user submits the micro-form Then a cryptographic hash is created over the signature artifact(s), consent statement identifier, and submissionId And the signature artifact(s), hash, and audit record are persisted server-side Given the submission is processed When the server responds Then the response contains a confirmationId and the audit hash And server logs include device, browser, and session metadata captured from the client Given a submitted record When any signature artifact is altered post-submission Then the stored hash no longer matches and the record is flagged as tampered
Resilience: Autosave, Low-Bandwidth, and Recovery
Given network conditions are degraded (<=150 kbps down, <=50 kbps up, ~400 ms RTT, 2% packet loss) When the user interacts with any signature mode Then autosave occurs at least every 10 seconds and on blur/confirm And on save failure, content is persisted locally and a non-blocking 'Saved offline' notice is shown Given connectivity is restored after an offline period When the form is reopened Then locally persisted signature artifacts and state are restored and synchronized to the server without user data loss Given a save or sync is in progress When the user continues interacting Then the UI remains responsive and no duplicate artifacts are created
Accessibility: WCAG 2.2 AA Compliance for Signature Components
Given a keyboard-only user When navigating the signature component Then all interactive elements are reachable in logical tab order with visible focus indicators And all actions (select mode, confirm, clear, submit) have keyboard equivalents Given a screen reader is active When focus enters the signature component Then the consent statement, mode selection, instructions, completion state, and errors are announced with appropriate roles and labels Given a touch user on mobile When interacting with controls Then all tap targets are at least 44x44 CSS pixels and meet WCAG 2.2 AA contrast requirements Given an error occurs When the error message is displayed Then it is programmatically associated with the field and announced via aria-live Given Draw mode is not operable by keyboard When keyboard-only users need to sign Then an equivalent alternative control path (e.g., Tap or Typed) is available and clearly discoverable
Signature Hashing & Submission Binding
"As a claims manager, I want each signature to be cryptographically bound to the exact content submitted so that I can verify it hasn’t been altered after signing."
Description

On submission, compute a tamper-evident SHA-256 hash over a canonicalized payload that includes the attestation text version, signature artifact, timestamp, claimant identifiers, and submitted form data subset required by compliance. Persist the hash, a unique signing ID, and a server-side timestamp synchronized via NTP. Expose a verification method to recompute and compare hashes for dispute resolution and audit, and prevent re-use via idempotency tokens.

Acceptance Criteria
Canonical Payload Construction on Submission
- Given a claimant completes the micro-form and taps to sign, When the submission is initiated server-side, Then the system constructs a canonical JSON payload that includes only: attestation_text_version, signature_artifact (type, normalized_base64), server_submission_timestamp_utc, claimant_identifiers (policy_number, claimant_guid), and compliance_required_form_fields, and excludes all other fields. - And the canonicalization rules are: UTF-8 encoding; keys sorted lexicographically; arrays preserve order; numbers serialized without insignificant trailing zeros; timestamps in RFC3339 UTC with millisecond precision; no extraneous whitespace outside string values; boolean and null preserved. - And recomputing the canonical payload for the same input yields a byte-for-byte identical string across runs and servers.
SHA-256 Digest Generation & Format
- Given a canonical payload is produced, When hashing is performed, Then a SHA-256 digest is computed over the exact canonical payload bytes using a FIPS-validated cryptographic library and stored in lowercase hexadecimal format of length 64. - And hashing the same payload twice yields the same digest; changing any single byte in the payload yields a different digest. - And the signing record captures digest_value, canonical_payload_version, and hashing_library_version.
Persistence with Unique Signing ID and NTP-Synced Timestamp
- Given a successful submission, When the signing event is persisted, Then the record contains: signing_id (ULID), sha256_digest, canonical_payload_snapshot, server_timestamp_utc, ntp_offset_ms, and environment. - And signing_id is globally unique and non-sequential; And server_timestamp_utc is derived from an NTP-synchronized clock with absolute ntp_offset_ms ≤ 1000 at the time of write; If the offset exceeds the threshold, the write is rejected with error code SIGNING_CLOCK_UNSYNCED. - And all persisted fields are immutable; any attempt to update them results in HTTP 409 CONFLICT and no mutation.
Verification Endpoint for Dispute Resolution
- Given an authorized auditor provides a signing_id, When the verification endpoint /tapSign/verify is called, Then the service returns stored canonical_payload_snapshot, stored_digest, recomputed_digest, and a verdict field with values MATCH or NO_MATCH with HTTP 200. - And recomputation uses the same canonicalization rules and version recorded at signing time; for unaltered inputs the verdict is MATCH. - And when an auditor supplies an alternative payload in the request, the endpoint compares against that payload and returns NO_MATCH with a list of differing top-level fields.
Idempotency Token Enforcement on Retries
- Given the client includes an Idempotency-Token header and resubmits the identical payload within 24 hours, When the submission is received, Then the API returns HTTP 200 containing the original signing_id, digest, and server_timestamp_utc, and does not create a new record. - And if the same token is reused with any payload that differs after canonicalization, Then the API returns HTTP 409 with error code IDEMPOTENCY_PAYLOAD_MISMATCH and no new or updated signing record is created. - And idempotency tokens expire after 24 hours; submissions after expiry are processed as new requests.
Signature Artifact Normalization & Inclusion
- Given a drawn, typed, or tap-ack signature is captured, When the canonical payload is built, Then signature_artifact includes: type (drawn|typed|tap_ack), normalized_representation (base64 of deterministic PNG for drawn; UTF-8 string for typed; boolean true for tap_ack), and sha256 of the normalized representation. - And normalizing the same raw signature input yields identical normalized bytes across runs; altering any pixel or character changes the sha256 and thus the overall payload digest. - And the raw signature artifact is stored securely and linked by signing_id; the canonical payload includes only the normalized_representation (or its hash) and not the raw blob.
Attestation Text Management & Localization
"As a compliance admin, I want to manage attestation language by jurisdiction and line of business so that claimants see the correct legal text when they sign."
Description

Enable administrators to create and version attestation templates with variables (policy number, loss date, jurisdiction) and rules by product line, claim type, and geography. Support localization with pluralization and right-to-left scripts, preview before publish, effective-dating of changes, and safe rollbacks. Automatically select the correct text at runtime and record the exact version and locale presented at signing.

Acceptance Criteria
Admin Creates Versioned Attestation Template with Variables
Given I am an administrator on the Attestation Templates screen When I create a new template with variables {policy_number}, {loss_date}, and {jurisdiction} Then the system validates variables against the allowed set and rejects any unknown placeholders with inline errors And when I save the template Then a template record is created in Draft state with version 1.0 and a timestamp And when I add rules by product line, claim type, and geography Then the rules are saved and validated to have deterministic priority with no unresolvable conflicts
Localized Rendering with Pluralization and RTL Support
Given localized strings exist for en-US, es-ES, and ar-SA with defined plural forms When the template is rendered for ar-SA with count=1 and count=5 Then the correct singular and plural strings are selected for each count And the rendered attestation container uses RTL directionality and right-aligned layout for ar-SA And no unresolved placeholders or layout overflow occurs in any of the three locales at standard viewport widths
Admin Previews Template with Sample Data Before Publishing
Given a Draft template with variables and rules defined When I click Preview, select a locale, provide sample values for all variables, and choose claim attributes to simulate rule selection Then the preview renders exactly as runtime would, with all variables substituted and correct rule- and locale-specific text And when I attempt to Publish without having completed at least one successful preview on the current draft version Then Publish is blocked with a message indicating Preview is required And when I have a successful preview and set a future effective start date Then Publish succeeds and the template transitions to Active with that effective date
Effective-Dated Changes and Safe Rollback
Given version 1.0 of a template is Active When I publish version 1.1 with an effective start of 2025-10-15T00:00:00Z Then runtime uses version 1.0 for signings with timestamps before the effective start and version 1.1 for signings on or after the effective start And when I initiate a rollback from version 1.1 to version 1.0 Then version 1.0 becomes Active with a new effective start of now, version 1.1 is marked Superseded, and the full version history is preserved And historical signing records continue to reference the original version and locale used at the time of signing
Automatic Runtime Selection by Product Line, Claim Type, and Geography
Given rules map product line=Auto, claim type=Bodily Injury, geography=QC to template T1 (fr-CA) and geography=CA (non-QC) to template T1 (en-CA) When a claim with product line=Auto, claim type=Bodily Injury, geography=QC renders an attestation Then the system selects template T1 with locale fr-CA And when multiple rules match Then the highest-priority rule is applied deterministically And when no rules match Then the system uses the configured default template/locale; if none exist, it returns a 4xx error with code ATT_TEXT_RULE_NOT_FOUND and logs the event
Record Presented Attestation Text Version and Locale at Signing
Given an attestation is presented to a claimant When the claimant signs Then the signature event stores templateId, templateVersion, locale, ruleId, effectiveStart, effectiveEnd (if any), claimId, timestamp, and renderedTextHash (SHA-256 of the exact rendered text) And the event is immutable and retrievable via the Audit API by claimId and time range And recomputing the hash from the archived rendered text matches the stored renderedTextHash
Localization Completeness and Variable Parity Validation
Given a template with multiple locales When I attempt to Publish Then the system validates that every localized variant includes all required variables present in the base template and that variable names match exactly And if any locale is missing a variable or contains an unknown variable Then Publish is blocked with a per-locale error list until corrected
Evidence Package & Audit Trail Export
"As an auditor, I want an exportable evidence package for each signed submission so that I can validate consent and trace the signing event for audits or disputes."
Description

Generate an immutable evidence record per signing event including signature method, artifact, hash, timestamps, IP address, user agent, optional geolocation (with consent), presented attestation text/version, and workflow identifiers. Provide secure retrieval inside the claim record and export as digitally signed PDF and structured JSON. Implement retention policies, access controls, and a chain-of-custody log for any access or export actions.

Acceptance Criteria
Immutable Evidence Record Generated on TapSign Submission
Given a claimant completes a TapSign action in ClaimFlow When the submission event is finalized Then the system creates an evidence record bound to the submission event containing: signature_method, signature_artifact, signature_hash (SHA-256), server_timestamp (UTC ISO 8601), client_timestamp (if available), ip_address, user_agent, attestation_text, attestation_version, claim_id, workflow_id, step_id, submission_id And the evidence record is immutably stored (append-only); any update attempt is rejected and a new record requires a new signing event And the signature_hash is deterministically derived from the exact stored artifact bytes and is reproducible on re-hash And the evidence record has a unique identifier and a content-integrity checksum of the full record blob
Geolocation Captured Only With Explicit Consent
Given the signer is presented with a clear geolocation consent prompt before signing When the signer grants consent and the device provides location data Then latitude, longitude, accuracy_meters, and geo_timestamp are captured and stored in the evidence record with consent=true And when the signer declines or the device denies location access Then no location coordinates are stored, consent=false is recorded, and the signing flow proceeds without error And if geolocation collection fails after consent Then an error_code and message are recorded in the evidence record and no coordinates are stored
Secure In-Claim Retrieval Restricted by Role-Based Access
Given a user is viewing a claim record in ClaimFlow When the user attempts to open the Evidence & Audit section for a signing event Then access is permitted only to users with roles in the authorized list (Claims Manager, Adjuster, Auditor, System Admin) and denied to others with an access_denied event recorded And the evidence payload is transmitted only over TLS 1.2+ with HSTS enabled And every successful or failed retrieval is logged in the chain-of-custody with actor_id, role, timestamp (UTC), action=view_evidence, outcome=success|denied, ip_address, and user_agent
Digitally Signed PDF Evidence Export
Given an authorized user selects "Export Evidence (PDF)" for a signing event When the export completes Then a PDF is generated that includes all evidence fields, the full attestation text, and a visual representation of the signature artifact And the PDF is digitally signed using an X.509 certificate with SHA-256 and shows as "Signature valid" in standard PDF signature verification tools (e.g., Adobe Acrobat) And the PDF embeds the evidence record's signature_hash and a document-level hash for traceability And the export action is recorded in the chain-of-custody with file_hash (SHA-256) and download timestamp
Structured JSON Evidence Export
Given an authorized user selects "Export Evidence (JSON)" for a signing event or calls the export API When the export completes Then a JSON file conforming to schema version v1 is produced containing all required fields: signature_method, artifact_hash, timestamps (server_utc, client_local), ip_address, user_agent, geolocation (fields or null with consent flag), attestation_text, attestation_version, claim_id, workflow_id, step_id, submission_id And the JSON validates against the published JSON Schema and includes schema_version and record_id And fields that are unavailable are present with null values rather than omitted (except optional arrays which may be empty) And the export action is recorded in the chain-of-custody with file_hash (SHA-256) and caller identity
Comprehensive Chain-of-Custody Logging for Access and Export
Given any user or system process accesses, exports, or attempts to access an evidence record When the action occurs Then a chain-of-custody entry is appended containing: event_id, action (view|export_pdf|export_json|deny), actor_id, actor_role, timestamp (UTC ISO 8601), claim_id, submission_id, outcome (success|denied|error), ip_address, user_agent, and related file_hash if applicable And the log is append-only and tamper-evident via hash chaining (each entry stores previous_entry_hash and entry_hash) And any alteration to a past entry invalidates the chain verification check And chain-of-custody entries are searchable by claim_id and date range
Retention Policy Enforcement with Legal Hold
Given retention policies are configured per line of business and jurisdiction When an evidence record reaches its retention end date Then the system purges the evidence record and associated export artifacts unless a legal hold is active And a purge event is appended to the chain-of-custody with actor=system, timestamp, and purge_reason=retention_expired And when a legal hold is applied before expiry Then the evidence record is preserved until the hold is released, and any attempt to purge is blocked and logged And configuring, applying, or releasing a legal hold requires Admin role and captures justification text in the log
Compliance Disclosures & Consent Capture
"As a compliance officer, I want standardized electronic consent flows so that our signatures meet legal and regulatory requirements across regions."
Description

Present ESIGN/UETA/eIDAS-compliant disclosures and obtain explicit consent to electronic records before signature capture. Record consent text, version, and timestamp, and support additional controls for high-risk scenarios (re-authentication, OTP, or KBA where configured). Provide fallbacks to alternate signing methods when electronic consent is declined, while logging declinations and routing the claim accordingly.

Acceptance Criteria
Consent Gate Before Signature Capture
Given a claimant opens a TapSign-enabled micro-form and has not previously consented for this submission When ESIGN/UETA/eIDAS disclosures are displayed Then the signature input UI remains disabled until the claimant explicitly checks a consent box and taps "Agree" And the consent control is not pre-checked and requires an explicit action And upon agreement the system records: disclosureText, disclosureTextVersionId, disclosureTextHash (SHA-256), locale, claimId, submissionId, userId (or anonymous sessionId), deviceId, clientIp, displayTimestamp, acceptanceTimestamp (UTC, ms precision) And the consent record is bound to the submissionId and formVersion and is write-once (immutable) And if the claimant navigates away without consenting, the system prevents signature capture and logs an incomplete-consent event
Evidence Capture and Audit Binding
Given the claimant has consented and provides a signature in TapSign When the submission is completed Then the system creates an immutable audit record linking consentEventId and signatureEventId using a bindingId And computes and stores signatureHash and documentDigest (SHA-256) And generates an evidence package (JSON and downloadable PDF) containing: claimant identifiers (as available), disclosureText/version/hash, framework (ESIGN/UETA/eIDAS), timestamps (display/accept/sign/submit in UTC), IP/device metadata, riskLevel, applied controls and outcomes, signature image/type (draw/typed/tap) and hash, documentDigest, bindingId, submissionId, claimId, locale And exposes the evidence package via UI in the claim timeline and via GET /claims/{claimId}/evidence returning 200 with the JSON payload And audit records are immutable and retained per retentionPolicy >= 7 years
High-Risk Additional Controls (OTP/KBA/Re-auth)
Given a claim is evaluated as HIGH risk or the product configuration requires additional identity controls When the claimant proceeds after consenting but before signature Then the system enforces the configured control(s): - OTP: sends a 6-digit code via configured channel, expires in 5 minutes, max 3 attempts, rate-limited to 5 sends/hour; success required before enabling signature - Re-auth: prompts for SSO/password re-auth; success required before enabling signature - KBA: presents 3 questions; passing threshold >= 2 correct; success required before enabling signature And all control outcomes (success/failure, timestamps, delivery channel, attempt counts) are logged in the audit record And on control failure (exhausted attempts), signature capture is blocked and the claim is auto-routed to the "High-Risk Review" queue with reason "ControlFailed"
Declined Electronic Consent Fallback Routing
Given the claimant selects "Decline" or dismisses disclosures without consenting When the system processes the decision Then TapSign signature UI remains inaccessible and e-sign is disabled for this submission And the system displays configured alternate signing options (e.g., wet signature, mail, in-person) with clear instructions and contact/CTA And a task is created and the claim is routed to the "Alt-Signature" queue with SLA as configured And a declination record is stored with disclosureTextVersionId, locale, timestamp (UTC), reason (Declined/NoConsent), and any provided feedback And if the claimant later revisits and chooses to consent, a new consent event is captured and the e-sign flow is re-enabled
Re-consent on Disclosure Version Change
Given a claimant previously consented to disclosure version V for this claim When a newer required disclosure version V+1 becomes effective for the claimant’s jurisdiction/product Then the system presents the updated disclosures and blocks signature until V+1 is accepted And the audit preserves both V and V+1 consent events without overwriting prior records And if configuration marks the change as non-material, the system informs the claimant but does not block signature And version selection logic uses effectiveDate, product, and jurisdiction mappings and is logged for traceability
Regional Compliance Selection (ESIGN/UETA/eIDAS)
Given the claimant’s jurisdiction is resolved from policy data, user selection, or geolocation with user override When disclosures are presented Then the system selects and renders the correct framework template (ESIGN/UETA for US, eIDAS for EU/EEA) with required statements (scope, hardware/software requirements, withdrawal rights, paper copy request) And the selected framework and jurisdiction are recorded in the consent record and evidence package And for eIDAS configurations that require additional identity assurance, the system enforces the configured step (e.g., OTP) prior to signature And automated tests validate template selection across a jurisdiction matrix (US, EU/EEA, Other -> default ESIGN/UETA or configured local template)
Accessibility and Localization of Disclosures
Given any claimant, including assistive technology users When the disclosure and consent UI renders Then it meets WCAG 2.1 AA: contrast ratio >= 4.5:1, visible focus, logical focus order, labels/roles for screen readers, keyboard operability for all interactive elements, touch targets >= 44x44 px And disclosures are available in supported locales; the correct locale is auto-selected with user override; if a locale is missing, English is shown with a notice And localized content includes jurisdiction-specific withdrawal and paper-copy instructions And time-to-interactive for the disclosure view is <= 2 seconds on a 3G profile and disclosure payload size <= 200KB And i18n/l10n unit tests and accessibility audits (automated + manual) pass
Workflow Gates & API Events
"As a claims operations lead, I want workflows to automatically progress when a valid signature is captured so that approvals are accelerated without manual checks."
Description

Gate downstream workflow steps until a valid signature is present and verified. Emit webhooks and internal events (signature.captured, signature.verified, signature.invalidated) and expose APIs to query signature status by claim or submission ID. Provide UI indicators in queues and detail views, configurable routing rules on signature outcomes, and idempotent, retryable event delivery with observability metrics.

Acceptance Criteria
Gate Downstream Steps Until Signature Verified
- Given a claim submission without a verified signature, When the workflow engine evaluates a step marked signature_required, Then the step remains in Pending state with block_reason=signature_missing. - Given a claim submission with a captured but unverified signature, When the gate is evaluated, Then dependent steps remain Pending with block_reason=signature_unverified. - Given a claim submission with a verified signature, When the gate is evaluated, Then all previously blocked signature_required steps transition to Ready within 5 seconds and become eligible to run. - Given a verified signature is later invalidated, When the gate is re-evaluated, Then no new signature_required steps start and a signature_invalidated event is recorded with affected step IDs. - Given any gate decision, When audit logs are queried, Then an entry exists containing claimId, submissionId, decision, evaluatedAt, and actor=workflow-engine.
Emit Signature Lifecycle Events
- Given a signature is captured, When the submission is saved, Then an internal event signature.captured and an outbound webhook are emitted with payload fields: claimId, submissionId, signatureId, captureMethod, hash, capturedAt, schemaVersion. - Given a signature passes verification, When verification completes, Then signature.verified events are emitted with verifiedAt and verifier fields. - Given a signature is invalidated, When invalidation occurs, Then signature.invalidated events are emitted with reason_code and invalidatedAt fields. - Given any lifecycle event is emitted, When multiple deliveries occur, Then the idempotencyKey remains stable per event and duplicates are acceptable downstream. - Given a webhook consumer receives an event, When the X-Signature header is verified using HMAC-SHA256 and the shared secret, Then the payload authenticity can be validated.
Signature Status Query API
- Given a valid claimId, When GET /api/v1/signatures/status?claimId={id} is called with an authorized token, Then the API returns 200 with status in {none,captured,verified,invalidated}, signatureId (if any), and timestamps for last transition. - Given a valid submissionId, When GET /api/v1/signatures/status?submissionId={id} is called with an authorized token, Then the same contract applies. - Given both claimId and submissionId are provided but do not map to the same record, When the API is called, Then 400 is returned with error_code=argument_conflict. - Given the caller lacks required scope (signatures.read or claims.read), When the API is called, Then 401 or 403 is returned appropriately. - Given an unknown claimId or submissionId, When the API is called, Then 404 is returned with error_code=not_found. - Given nominal load, When the API is exercised, Then p95 latency is <= 250 ms and each response includes requestId for traceability.
UI Indicators for Signature Status
- Given a work queue item, When the signature status is none, captured, verified, or invalidated, Then a status pill displays the corresponding label and color, is screen-reader accessible (aria-label includes status and timestamp), and updates within 5 seconds of an event. - Given a claim detail view, When signature status is verified, Then signature-dependent actions (e.g., Approve, Route) are enabled; otherwise they are disabled with a tooltip explaining "Requires verified signature". - Given a claim with an invalidated signature, When the detail view is opened, Then an alert banner is shown with the invalidation reason and invalidatedAt timestamp.
Configurable Routing on Signature Outcomes
- Given a rule that routes on signature.verified to queue "FastTrack", When a signature.verified event occurs for a claim, Then the claim's task is routed to FastTrack within 10 seconds and a rule_evaluation log entry is recorded with ruleId and outcome=matched. - Given a rule that on signature.invalidated creates a follow-up task "Request re-signature", When such an event occurs, Then the task is created, assigned to the default queue, and SLA set to 24h. - Given multiple rules match, When evaluation runs, Then rules execute in priority order and outcomes are deterministic per configured precedence; non-idempotent side effects are guarded by the event idempotencyKey. - Given rules are updated, When a new event arrives, Then the new rules apply and previously processed events are unaffected.
Idempotent, Retryable Webhook Delivery with Observability
- Given a webhook delivery fails with non-2xx or times out after 10 seconds, When the delivery job runs, Then retries occur with exponential backoff up to 15 attempts over 24 hours. - Given a consumer eventually returns 2xx, When a retry occurs, Then no additional deliveries are attempted for that event endpoint and a success is recorded. - Given duplicate deliveries happen, When the consumer inspects headers, Then X-Idempotency-Key is present and stable per event allowing safe deduplication. - Given event deliveries are processed, When metrics are scraped, Then counters exist for events_emitted_total by type, deliveries_succeeded_total, deliveries_failed_total, retries_total, and delivery_latency_seconds, with dashboards showing p50/p95. - Given max retries are exhausted, When the event cannot be delivered, Then the event is moved to a dead-letter queue with reason and is available for operator replay via API or console.
Amendment & Re-Sign Flow
"As a claimant, I want to review changes and re-sign when my claim details are updated so that my consent clearly matches the final submitted information."
Description

Detect post-signature changes to attested fields and automatically invalidate the prior signature, notify the claimant, and request re-signing with a diff view of changed fields. Maintain a versioned signature chain with timestamps and hashes for each iteration, enforce expiration windows, and ensure audit continuity across amendments.

Acceptance Criteria
Invalidate Signature on Attested Field Change
Given a submission with a valid signature S1 When any field marked attested=true is edited and saved Then S1 is set to status=invalidated with reason=attested_field_changed And the submission status changes to Requires Re‑Sign And approval/submit actions are blocked until a new signature is captured And an audit entry records the changed field paths, old/new values snapshot, editor identity, and timestamp
Notify Claimant and Request Re‑Sign
Given a signature has been invalidated due to attested field changes When the change is saved Then a re‑sign notification is sent to the claimant’s configured channel(s) (email/SMS/in‑app) within 60 seconds And the notification contains a single‑use, signed link bound to the submission ID and amendment version And the link is valid only for the configured expiration window And the submission shows status Awaiting Re‑Sign with the requested-by timestamp
Display Diff of Changed Attested Fields
Given the claimant opens the re‑sign link When the attestation step renders Then a diff view lists only changed attested fields with field labels and before/after values And unchanged attested fields are collapsed by default with an option to expand And changes are highlighted and accessible (screen‑reader labels, keyboard navigation) And an explicit Acknowledge changes control must be checked before the Sign action is enabled
Versioned Signature Chain and Hash Integrity
Given a prior signature S1 exists and a re‑sign is completed When signature S2 is captured Then a new version record v2 is created with signatureId, signerId, method (tap/draw/type), UTC timestamp, IP, device fingerprint (if available), and contentHash And v2.priorSignatureId references S1 to form a forward‑only immutable chain And the contentHash equals the recomputed hash of the attested field snapshot at sign time And an API endpoint returns the complete ordered chain (S1..Sn) with hashes for verification
Expiration Window Enforcement and Renewal
Given a re‑sign link is issued with a 72‑hour expiration window When the claimant attempts to use the link after expiry Then access is denied with an expiration message and no signature can be captured And the system allows issuing a fresh re‑sign request per configuration And reminder notifications are sent at configured intervals before expiry And expired requests are marked expired in audit logs with timestamps
Audit Continuity and Export
Given multiple amendments and re‑sign iterations have occurred When an auditor requests an export Then the export includes a chronological event log of change, invalidation, notification, and signature events with timestamps, actor, channel, reason, and hashes And the export bundles the versioned signature chain with diffs per iteration And a top‑level checksum is provided to verify export integrity And all timestamps are normalized to UTC with timezone metadata
Non‑Attested Changes Do Not Invalidate Signature
Given a signed submission When a field not marked attested=true is edited and saved Then the existing signature remains valid And no re‑sign notification is sent And an audit entry records a non‑attested change without modifying the signature chain

Nudge Cadence

Behavior-smart reminders that adapt to claimant response patterns. Sends gentle nudges via SMS/email/WhatsApp, respects quiet hours, offers snooze/‘I’ll do it later’ options, and highlights time-to-complete. Escalates to an agent only when risk of delay is high. Increases completion without adding agent workload.

Requirements

Adaptive Send-Time & Frequency Optimization
"As a claims manager, I want nudges to be sent when each claimant is most likely to respond so that tasks complete faster without over-messaging."
Description

A behavior-smart scheduling engine that learns from claimant response patterns, message opens/clicks, completion events, and channel performance to choose optimal send times and cadence per claimant and per task. Applies guardrails (minimum/maximum nudges per day/week), decays frequency after non-responses, accelerates as deadlines approach, and pauses while the claimant is active in the portal or after a human exchange. Integrates with ClaimFlow’s workflow engine via event hooks (task_created, reminder_needed, task_completed) and writes decisions to an audit log for explainability. Stores engagement features in a claimant profile, supports A/B testing of cadence policies, and exposes configuration per line of business and claim severity. Supports both heuristic policies and a pluggable ML model with safe fallback to rules when model confidence is low.

Acceptance Criteria
Send-Time Optimization Learns From Engagement and Persists Features
Given a task_created event for claimant C with at least N historical engagement events, When the engine computes the next send time for channel X, Then it selects a send time within the next H hours that maximizes predicted response probability using engagement features (opens, clicks, replies, completions, response latency, channel and time-of-day/day-of-week effects). Given an ML policy is enabled with confidence threshold T, When the model confidence for the recommended send time is below T, Then the engine falls back to the configured heuristic policy for this claimant-task. Given multiple active tasks for claimant C, When computing schedules, Then optimization is performed per task and does not schedule overlapping nudges for C within the minimum spacing window.
Cadence Guardrails and Quiet Hours Compliance
Given configured min_spacing_minutes S_min, max_nudges_per_day D_max, max_nudges_per_week W_max, and quiet_hours [Q_start, Q_end] in the claimant's local time zone, When scheduling nudges over any rolling 24-hour and 7-day windows, Then no more than D_max nudges are scheduled per day and no more than W_max per week, and at least S_min minutes separate consecutive nudges. Given quiet hours are configured, When a computed send time falls within [Q_start, Q_end], Then the send is moved to the next allowed slot outside quiet hours while still respecting S_min, D_max, and W_max. Given claimant local time zone and DST transitions, When computing allowed windows, Then all guardrails are evaluated in the claimant's current local time.
Non-Response Frequency Decay With Engagement Reset
Given a non-response is defined as no open/reply/completion within R hours after a nudge, When claimant C accumulates K consecutive non-responses, Then the next inter-nudge interval is increased by a decay multiplier M^K up to a maximum interval I_max. Given claimant C subsequently engages (open/reply/complete), When computing the next schedule, Then the inter-nudge interval resets to the baseline interval B and the consecutive non-response counter resets to 0. Given I_max would push the next send beyond the task deadline, When computing the schedule, Then deadline-aware acceleration rules apply while still honoring guardrails.
Deadline-Aware Acceleration With Caps
Given a task deadline D and configured acceleration thresholds A1 and A2 (A2 < A1) with corresponding accelerated intervals I1 and I2, When now is within A1 hours of D, Then the engine reduces the inter-nudge interval to I1 subject to guardrails. Given now is within A2 hours of D, When scheduling, Then the engine reduces the inter-nudge interval to I2 subject to guardrails. Given a deadline guard time G, When scheduling the final reminder, Then the final reminder is no later than D - G and no reminders are scheduled after D.
Activity-Aware Pausing: Portal and Human Exchanges
Given claimant C has an active portal session with last activity within P_active_window minutes, When a nudge is due, Then the engine pauses sending and reschedules to the first allowed time at least P_cooldown minutes after the last activity while honoring guardrails. Given a human exchange event (agent message/call log) occurs at time H, When a nudge is due within [H, H + H_cooldown], Then the nudge is skipped or rescheduled to the first allowed time after H_cooldown while honoring guardrails. Given multiple nudges are queued during a pause window, When the pause ends, Then only the next eligible nudge is scheduled and duplicates are not sent.
Workflow Event Hook Integration and Idempotency
Given a task_created event with idempotency key K, When processed, Then an initial schedule is created and returned with schedule_id S, and reprocessing the same event with key K does not create duplicate schedules. Given a reminder_needed event, When processed, Then the engine evaluates current state and returns the next send decision consistent with policy, guardrails, and pauses. Given a task_completed event, When processed, Then all pending nudges for the task are canceled and no further nudges are scheduled. Given out-of-order events (e.g., task_completed before reminder_needed), When processed, Then the engine ensures no nudges are sent after completion and state remains consistent. Given a service restart, When the engine resumes, Then previously persisted schedules are reloaded and honored without sending duplicates.
Policy Configuration, Experiments, and Auditability
Given line of business L and claim severity S, When computing scheduling decisions, Then the engine applies the configuration scoped to L and S and returns the policy_id used. Given an active A/B experiment with experiment_id E and variants {A, B} and a 50/50 split, When an eligible task is evaluated, Then the assignment is deterministic per configured unit (claimant or task), remains stable for the task lifetime, and is recorded with E and variant. Given any scheduling decision is produced, When writing the audit log, Then the entry includes decision_id, task_id, claimant_id, timestamp, policy_id, policy_type (ML or heuristic), model_version (if ML), model_confidence, selected_send_time, applied_constraints/adjustments, reason_codes, and a reference to the feature snapshot used. Given new engagement signals are observed, When updating the claimant profile, Then aggregated engagement features required by the scheduler (e.g., response latency statistics, channel open rates, best hour-of-day by channel) are persisted with versioning and timestamps. Given a configuration change via API/console, When validated, Then it is applied atomically and becomes effective within T_propagation minutes; invalid configurations are rejected with descriptive errors and no partial updates occur.
Multi-Channel Messaging Orchestration & Fallback
"As an adjuster, I want ClaimFlow to choose the best channel and seamlessly switch if delivery fails so that claimants reliably receive reminders."
Description

Unified orchestration of SMS, email, and WhatsApp under a single conversation thread. Selects a primary channel based on claimant preference and deliverability history and falls back to secondary channels on bounce/undelivered events or after configurable non-response intervals. Deduplicates content across channels, maintains a unified message history linked to the claim record, and preserves conversation context when switching channels. Supports templating with dynamic variables, localized content, tracked short links, and per-channel rate limits. Handles delivery receipts and inbound replies via webhooks, applies WhatsApp template approvals/senders, and integrates with existing ClaimFlow communications adapters. Provides admin configuration for channel priority, retry thresholds, and failover rules.

Acceptance Criteria
Primary Channel Selection by Preference and Deliverability History
Given a claimant with a recorded channel preference and 30-day deliverability metrics for SMS, Email, and WhatsApp When the system initiates a nudge send Then it selects the preferred channel if its 30-day delivery success rate is ≥ 95% and there are no ≥ 2 consecutive failures in the last 30 days And if the preferred channel does not meet the threshold, it selects the channel with the highest 30-day delivery success rate (tie-breaker: most recent reply timestamp) And the selection decision, metrics, and tie-breakers are logged with timestamp and claim ID And the chosen channel is stored on the message record for audit and analytics
Immediate Fallback on Bounce/Undelivered Event
Given a message is sent on the selected primary channel And provider webhooks are configured When a bounce or undelivered status is received within 120 seconds of send Then the message attempt is marked Failed with provider code and reason And the same content is sent on the next-priority channel within 5 minutes, preserving conversation context (claim ID, conversation ID) And per-channel rate limits are checked before sending; if limits would be exceeded, the send is queued and executed when allowed And no duplicate content is re-sent to the failed channel within a 24-hour window
Non-Response Failover After Configured Interval
Given a message requires claimant action and has an associated non-response interval configured for the workflow step When no reply or click is recorded on the primary channel before the interval elapses Then the system sends the same prompt on the next-priority channel with a non-duplicative variant indicator (e.g., "Following up via Email") And the failover event, original send timestamp, and interval used are recorded on the claim timeline And only one secondary-channel follow-up is sent per configured interval window to avoid spam And subsequent replies from any channel are correlated back to the original request and close the non-response timer
Unified Conversation Threading and Cross-Channel Deduplication
Given a claimant may receive/sent messages across SMS, Email, and WhatsApp for the same claim When messages are sent or received on any supported channel Then a single unified thread is maintained and displayed in chronological UTC order linked to the claim record And content deduplication prevents the same logical message from appearing more than once across channels within a 15-minute dedup window (by message ID or content hash + template ID) And thread entries display channel, status, and context-switch markers when a channel change occurs And exporting the thread returns a single transcript with message IDs, channels, timestamps, and statuses
Template Rendering, Localization, Tracked Links, and WhatsApp Compliance
Given a templated message with dynamic variables and localized variants exists When preparing to send on a specific channel and locale Then all required variables are resolved from the claim and claimant profile; if any are missing, the send is blocked with a validation error logged And the localized template variant matching claimant locale is used; if unavailable, the default locale is used And all URLs are replaced with per-channel, per-message tracked short links; link clicks are attributed to the channel and message ID And if the channel is WhatsApp, only pre-approved templates and registered senders are used; if no approved template for the locale exists, the system falls back to the next-priority channel per configuration
Webhook Processing for Delivery Receipts and Inbound Replies
Given delivery and inbound reply webhooks are received from SMS, Email, and WhatsApp providers When a webhook is received Then the request signature is validated; invalid signatures are rejected with no state change and an audit event recorded And delivery/read statuses update the corresponding message record within 5 seconds of receipt with provider status and timestamp And inbound replies are parsed (including email reply body extraction and SMS/WhatsApp media handling), associated with the correct claim and thread via idempotency keys, and deduplicated on repeated events And a "claimant_replied" event is emitted for workflow routing with channel, message ID, and claim ID
Admin Configuration of Priorities, Retry Thresholds, Non-Response, and Rate Limits
Given an administrator edits Messaging Orchestration settings in the console When saving changes to channel priority, retry thresholds, non-response intervals, and per-channel rate limits Then inputs are validated (e.g., non-negative integers, limits within provider caps, priorities unique per channel) And changes are versioned with actor, timestamp, and a diff, and are applied to new sends within 5 minutes And the orchestration engine uses the updated configuration for subsequent sends and failovers And a read-only audit log entry is created and visible in the system audit trail
Quiet Hours, Timezone & Consent Compliance
"As a compliance officer, I want all reminders to respect quiet hours and consent so that we reduce legal risk and protect customer trust."
Description

Policy enforcement that respects local time, quiet hours, and consent requirements for each claimant and jurisdiction. Resolves timezone from profile, device signals, or area code and defaults conservatively when unknown. Blocks nudges during configured quiet hours, weekends, and holidays; automatically schedules the next allowed window. Honors opt-in/opt-out and keyword commands (e.g., STOP, PAUSE, HELP) and maintains consent records with timestamp and source for auditability. Applies regulatory rules (e.g., TCPA, GDPR) via a policy engine, including daily/weekly touch caps and purpose-specific consent. Performs pre-send compliance checks with reason codes for any blocks and exposes an admin UI to configure policies by region and line of business. Integrates with ClaimFlow’s preference store and legal audit trails.

Acceptance Criteria
Timezone Resolution and Conservative Default
Given a claimant profile contains a timezone When a nudge is queued Then the resolved timezone equals the profile timezone and is used for all compliance checks Given the profile lacks a timezone and a device timezone is available When a nudge is queued Then the resolved timezone equals the device timezone Given neither profile nor device timezone is available and the phone area code maps to a region When a nudge is queued Then the resolved timezone equals the area-code-derived timezone Given no timezone signals are available and no fallback is configured in policy When a nudge is evaluated Then the decision is Block with reason_code=TZ_UNRESOLVED and no send is attempted Given a fallback_timezone and send_window are configured When timezone is unresolved and current time is outside the fallback window Then the decision is Defer with reason_code=TZ_FALLBACK and next_allowed_time is set to the next window start Given a DST transition occurs for the resolved timezone When scheduling a deferred send Then the time is computed with timezone-aware logic and adjusted to the next valid minute if the local time is invalid or duplicated Given any timezone decision is made When the evaluation completes Then the audit trail includes input signals, chosen timezone, decision, and reason_code
Quiet Hours, Weekends, and Holidays Enforcement
Given quiet hours 20:00–08:00 local are configured for Region=US and LOB=Auto When a nudge is due at 21:30 local Then the decision is Defer with reason_code=QUIET_HOURS and it is scheduled to 08:05 next business day local Given a regional holiday is on the policy calendar When a nudge is due on that date Then the decision is Defer with reason_code=HOLIDAY and it is scheduled to the next allowed business window Given WeekendBlocking is enabled When a nudge is due on Saturday or Sunday local Then the decision is Defer with reason_code=WEEKEND and it is scheduled to the next weekday window Given a multi-channel campaign across SMS, Email, and WhatsApp When compliance is evaluated Then the same quiet-hour, weekend, and holiday rules apply uniformly to all channels Given no allowed window remains within the next 7 days and SLA requires contact within 7 days When evaluation runs Then the decision is Defer with reason_code=NO_ALLOWED_WINDOW and an alert is raised; no message is sent Given a block or defer occurs When logging the decision Then the audit record includes claimant_id, resolved_timezone, local_time, policy_id, and reason_code
Consent Keywords and Immediate Enforcement
Given a claimant sends the keyword STOP via SMS When the system processes the inbound message Then the claimant is marked opted-out for the specific purpose and SMS channel in the preference store, a TCPA-compliant confirmation is sent, and future sends for that purpose/channel are Blocked with reason_code=OPTED_OUT Given a claimant sends the keyword PAUSE via any supported channel When the system processes the inbound message Then a pause_until timestamp is set per policy (e.g., now+72h), future nudges are Deferred with reason_code=PAUSED until expiry, and a confirmation message is returned Given a claimant sends the keyword HELP When the system processes the inbound message Then a HELP response is sent containing business name, support contact, and opt-out instructions; consent status is unchanged Given an email unsubscribe link is clicked When the webhook is received Then the preference store records opt-out for purpose on Email with timestamp and source=Email, and further emails are Blocked with reason_code=OPTED_OUT Given an opt-in keyword START is received on a previously opted-out channel When the policy requires purpose-specific consent Then the preference store records purpose-specific opt-in with timestamp and source, and messaging resumes only after all pre-send checks Pass
Daily/Weekly Touch Caps and Purpose-Specific Consent
Given daily_touch_cap=2 and weekly_touch_cap=5 for Region=US, LOB=Property When a third nudge for the same purpose is attempted within the same local day Then the decision is Block with reason_code=TOUCH_CAP_DAILY and no send occurs Given five nudges have been sent in the current local week for the same purpose When another attempt is evaluated Then the decision is Block with reason_code=TOUCH_CAP_WEEKLY until Monday 00:00 local time Given a nudge for Purpose=Billing and consent exists for Billing only When a nudge for Purpose=Marketing is attempted Then the decision is Block with reason_code=PURPOSE_MISMATCH unless explicit consent for Marketing exists Given day and week boundaries occur in the claimant’s timezone When counters reset at midnight and week start Then caps reset based on the resolved timezone and correctly handle DST transitions Given cap evaluation occurs When the decision is logged Then the audit record includes purpose, channel, remaining_quota, window_start, window_end, and policy_version_id
Pre-Send Compliance Check API and Reason Codes
Given a message candidate with claimant_id, purpose, channel, and content metadata When the pre-send compliance API is called Then the response includes decision in {Pass, Block, Defer}, reason_codes[], evaluated_policy_ids[], resolved_timezone, and next_allowed_time when applicable, plus an audit_id Given the decision is Block When the API responds Then no downstream delivery request is created and reason_codes is a subset of {QUIET_HOURS, WEEKEND, HOLIDAY, NO_CONSENT, OPTED_OUT, PAUSED, TOUCH_CAP_DAILY, TOUCH_CAP_WEEKLY, TZ_UNRESOLVED, TZ_FALLBACK, PURPOSE_MISMATCH, NO_ALLOWED_WINDOW, POLICY_ERROR} Given the decision is Defer When the API responds Then an idempotent scheduled job is created for next_allowed_time keyed by audit_id and only one job exists per candidate Given the decision is Pass When the API responds Then the delivery request is created and the compliance snapshot (inputs, policies, decision) is persisted Given typical load of 100 RPS in staging When the API is exercised Then p95 latency is <= 150ms and responses are deterministic for identical inputs
Admin Policy Configuration and Audit Trails Integration
Given an authorized Admin opens the Compliance settings When configuring by Region and Line of Business Then they can set quiet hours, weekend/holiday calendars, touch caps, consent requirements, and timezone fallback strategy with input validation and RBAC enforcement Given a policy change is saved When propagation occurs Then the change is versioned with before/after diff, actor, timestamp, and is active in the policy engine within 5 minutes; evaluations reference policy_version_id Given the Admin uses Preview next send time for a specific claimant When the system evaluates policies Then the UI shows resolved_timezone, current local time, next_allowed_time, active caps, and blocking reason_codes that match the API Given any consent or policy decision is made When audit logging occurs Then records are written to ClaimFlow’s preference store and legal audit trails as immutable append-only entries containing timestamp, source, purpose, channel, policy_version_id, and actor, and are exportable as CSV within 1 hour of request
Snooze and "I’ll Do It Later" Deferrals
"As a claimant, I want to snooze a reminder to a better time so that I can respond when it’s convenient without being pestered."
Description

In-message options that let claimants snooze reminders or indicate "I’ll do it later" with selectable durations (e.g., 2 hours, tomorrow, next week). Accepts quick-reply keywords/buttons across channels and via the self-service portal, updates the cadence schedule accordingly, pauses escalation timers, and reflects deferral status on the claim task timeline for agents. Persists deferral preferences per task and claimant, enforces limits on consecutive deferrals, and optionally requests a preferred time. Sends confirmation and provides a brief undo window. Integrates with the workflow engine to reschedule reminder jobs and with the scheduler to compute the next send window while honoring compliance policies.

Acceptance Criteria
SMS Snooze Deferral Adjusts Cadence and Honors Quiet Hours
Given an active claim task reminder is sent via SMS with snooze options When the claimant replies with a valid snooze keyword (e.g., "SNOOZE 2H") in the same thread Then the system acknowledges with a confirmation including the computed next reminder date/time in the claimant’s local time and an Undo option valid for the configured undo window And the workflow engine cancels the outstanding reminder job and schedules a new one at the next allowable send window computed by the scheduler honoring configured quiet hours and regulatory send caps And all escalation timers for the task are paused until the new nextSendAt And the claim task timeline shows an entry with action="Snooze", duration="2h", channel="SMS", requestedAt, nextSendAt, pausedEscalations=true And the deferral selection and nextSendAt persist on the task and claimant context so subsequent reminders for this task respect the new schedule across channels
Portal 'I'll Do It Later' With Preferred Time Selection
Given a claimant views a pending task in the self-service portal with an "I’ll do it later" option and time picker When they select a preferred date/time and confirm Then the system validates the selection against allowed send windows; if outside, it snaps to the next compliant window and communicates the adjusted time in the confirmation And a confirmation is sent via the original outreach channel with an Undo option for the configured undo window And the task record stores requestedTime and normalized nextSendAt, and the agent timeline reflects the deferral with details And all escalation timers for the task are paused until nextSendAt And the workflow engine reschedules the reminder job accordingly with a single scheduled job active
Cross-Channel Quick-Reply Deferrals (WhatsApp and Email)
Given an outbound reminder is delivered via WhatsApp (interactive buttons) or Email (keyword instructions) When the claimant taps a valid deferral button (e.g., "Snooze 2 hours") in WhatsApp or replies to Email with a valid keyword phrase (e.g., "later next week") Then the system parses the input to a valid deferral value using the configured keyword/button map and locale And for invalid/ambiguous inputs the system replies with a clarification prompt and does not schedule a deferral until a valid choice is received And upon a valid choice the system sends a confirmation with Undo, pauses escalation timers, reschedules via the workflow engine, and updates the agent timeline with the originating channel And duplicate deferral inputs received within 60 seconds are handled idempotently resulting in a single scheduled job and single timeline entry
Consecutive Deferral Limits Enforced
Given a consecutive deferral limit per task is configured to N When the claimant submits the Nth valid deferral Then it is accepted and scheduled normally When the claimant attempts an (N+1)th deferral before task completion Then the system declines the request with a courteous message explaining the limit and offers alternatives (e.g., proceed now or contact an agent) And no rescheduling occurs and escalation timers resume per policy And the agent timeline records the declined attempt with reason="Limit reached" and current deferral count
Agent Timeline Reflects Deferral Status and History
Given an agent opens the claim task timeline When any deferral is created, undone, or declined Then within 5 seconds the timeline shows an event with type (Snooze/Later/Declined/Undone), channel, actor="Claimant", timestamp, selected option or requested time, computed nextSendAt, and escalationPaused flag And the current task header displays a status badge "Deferred" with time remaining until nextSendAt And audit logs persist before/after schedule identifiers and the user/channel that initiated the change
Deferral Confirmation and Undo Window
Given a deferral is accepted When the system sends the confirmation message containing an "Undo" control Then if the claimant invokes Undo within the configured undo window (default 2 minutes) the original schedule and escalation timers are restored, the rescheduled job is canceled, and the agent timeline records "Deferral undone" And if Undo is attempted after the window expires the system informs the claimant the window has expired and the deferral remains in effect And all actions are idempotent if duplicate Undo requests are received
Compliance-Aware Scheduling via Workflow Engine and Scheduler
Given compliance policies are configured (quiet hours, daily send caps, regional rules) and the claimant’s time zone is known When a deferral is accepted Then the workflow engine requests the scheduler to compute nextSendAt compliant with all active policies and the claimant’s local time And the scheduled job does not fire during quiet hours; if policies change before send, the scheduler adjusts to the next compliant window and logs the adjustment And integration telemetry shows a single cancel-and-schedule pair per deferral and zero duplicate reminder sends
Dynamic Time-to-Complete Indicator
"As a claimant, I want to know how long a task will take so that I can decide to complete it now or plan for it."
Description

Estimated time-to-complete displayed within reminder content and the portal for each requested action, derived from task metadata and historical completion durations. Updates in real time as items are fulfilled and supports per-locale phrasing and confidence ranges. When estimates are high, presents suggestions for partial completion or a checklist to reduce friction. Provides an API endpoint to compute estimates, template tokens for communications, and analytics to attribute completion lift to the indicator. Pulls data from ClaimFlow’s task definitions and analytics warehouse and caches results for fast rendering.

Acceptance Criteria
Portal and Reminder Display of Time-to-Complete Indicator
Given a requested action with sufficient historical data and a known locale When a reminder (SMS/email/WhatsApp) is generated or the portal task list is rendered Then the action displays a numeric time-to-complete estimate with an appropriate unit (seconds/minutes/hours) And the text is localized to the recipient's locale preferences And a confidence range is shown when variance exceeds the configured threshold And the estimate source (historical vs. metadata default) is captured for analytics
Real-Time Indicator Update
Given a claimant has multiple outstanding actions and the indicator is visible When the claimant completes one action in the portal Then the remaining time-to-complete estimate recomputes and updates within 3 seconds And when all actions are completed the indicator is hidden in the portal and removed from subsequent reminders And cached values for the affected tasks are invalidated immediately
High Estimate Suggestions or Checklist
Given the computed estimate for an action exceeds the configured high_estimate_threshold When the indicator is rendered Then a suggestions CTA or checklist is displayed inline with no more than two taps to access And selecting a suggestion presents partial-completion options or a step-by-step checklist And dismissing the suggestion is remembered and not re-shown for 24 hours unless the estimate decreases below the threshold and later exceeds it again
Estimate Computation API Endpoint
Given an authenticated client with permission estimate.read When the client POSTs to /v1/estimates with task_id and locale Then the response is 200 JSON containing estimate_seconds, confidence_low, confidence_high, locale_string, cached (boolean), and updated_at (ISO8601) And P95 latency is <= 300 ms for cached responses and <= 700 ms for uncached responses And invalid task_id returns 404; missing/invalid params return 422; unauthorized/forbidden returns 401/403 And responses include Cache-Control headers reflecting the configured TTL
Template Tokens Rendering in Communications
Given a message template includes {{time_to_complete_phrase}} and/or {{time_to_complete_range}} When the message is sent via SMS, email, or WhatsApp Then tokens render to localized phrases with correct pluralization and units for the recipient's locale And no unreplaced token placeholders remain in the delivered content And when an estimate is unavailable, {{time_to_complete_phrase}} renders a localized fallback phrase and {{time_to_complete_range}} is omitted without breaking template syntax
Analytics Attribution for Completion Lift
Given an experiment or flag differentiates indicator_enabled versus control When reminders are sent or portal views occur Then events indicator_shown, estimate_value_exposed, and checklist_shown (if applicable) are logged with task_id, estimate_seconds, confidence_band, locale, and variant And completion events are logged with task_id and completed_at timestamp And the join rate between exposure and completion events is >= 95% over a 24-hour window And a metric definition computes completion lift (difference in completion rate within 7 days) by variant and is populated daily
Data Source Fallback and Caching Behavior
Given the analytics warehouse is unavailable or returns an error When an estimate is requested Then the system computes the estimate from task metadata defaults and marks confidence as low And if both historical data and metadata defaults are unavailable, the API returns estimate_unavailable and the UI renders a localized fallback phrase without a numeric value And cache TTL is 15 minutes and is invalidated on task completion or task definition change And production cache hit rate is >= 90% measured over a rolling 24-hour period
Risk-Based Escalation to Agent
"As a team lead, I want only high-risk cases to escalate to agents so that we maximize completion without increasing workload."
Description

A scoring mechanism that predicts delay or abandonment risk for each in-flight task and triggers agent escalation only when risk exceeds a configurable threshold. Combines signals such as time since last interaction, number of nudges sent, channel deliverability, claim complexity/severity, and claimant behavior patterns. On escalation, opens a contextual task in the agent queue with rationale, recent message history, and suggested outreach, throttles escalations to prevent load spikes, and auto-resolves the escalation if the claimant completes the task. Includes dashboards for false positives/negatives and allows per-workflow tuning. Operates with rules-based fallback when the model is unavailable and supports A/B testing to measure impact on agent workload and completion rates.

Acceptance Criteria
Threshold-Based Risk Escalation Trigger (Per-Workflow Config)
Given workflow W has escalation_threshold T = 0.72 And a claimant task in W has computed risk_score = 0.76 When the risk evaluator runs Then an agent escalation task is created for that claimant task And no escalation task is created when risk_score = 0.71 And when T is updated to 0.80 in W, the same 0.76 score does not trigger escalation And the workflow-level threshold overrides the global default threshold
Contextual Agent Task Payload on Escalation
Given an escalation task is created Then the task payload includes: risk_score, threshold_used, top_3_risk_factors with weights, time_since_last_interaction, nudges_sent_count, deliverability_status, claim_complexity/severity, last_10_messages, suggested_outreach_template_id, claimant_preferred_channel, recommended_time_window, and SLA_due_at And each payload field is populated and traceable to its data source in audit logs And no claimant-facing message is sent as part of the escalation And if current time is within claimant quiet_hours, the recommended_time_window begins at the next allowed window
Escalation Throttling to Prevent Agent Load Spikes
Given caps are configured as per_agent_per_hour = 5 and queue_per_minute = 30 And 100 eligible escalations occur in the same minute for a queue with 10 agents When the system enqueues escalations Then no agent receives more than 5 escalations within that hour And no more than 30 escalations are enqueued to the queue in that minute And remaining eligible escalations are deferred and retried within 15 minutes And escalations are prioritized by highest risk_score then oldest last_interaction timestamp And metrics for enqueued, deferred, and dropped (if any) are emitted with timestamps And throttle caps are configurable per queue and auditable
Auto-Resolve Escalation on Claimant Completion
Given an escalation task exists for task X And the claimant completes task X via any supported channel When completion is recorded Then the escalation task status changes to Resolved within 2 minutes And the resolution includes completion_time and completion_channel And if the agent has not opened the task, no notification is sent And if the agent has accepted the task, it is marked Resolved with reason = "Completed by claimant"
Rules-Based Fallback When Model Unavailable
Given the model endpoint errors or times out > 1s for 3 consecutive evaluations When computing risk for a task Then the rules engine is used with: escalate if time_since_last_interaction > 48h OR undelivered_nudges >= 2 OR deliverability_status = "hard_bounce" And the escalation payload sets decision_source = "rules_fallback" And a health alert is emitted once per hour while on fallback And after 5 consecutive successful model responses, the system returns to model-based decisions automatically
A/B Test Assignment and Impact Measurement
Given experiment risk_escalation_v1 is enabled with 50/50 split at claimant level and sticky assignment When eligible tasks are evaluated Then Control uses rules-only and Treatment uses model + threshold And the system records per-variant metrics: task_completion_rate, median_time_to_completion, escalations_per_claim, agent_handle_time, claimant_message_volume And the experiment can be enabled/disabled per workflow without redeploying code And assignment and metrics are queryable with experiment_id and workflow_id
False Positive/Negative Review Dashboard
Given an escalated task that an agent marks "Not needed" before claimant completion Then it is logged as a false_positive with reason and timestamp And a non-escalated task that breaches SLA before completion is logged as a false_negative When a user views the dashboard for a date range and workflow Then FP rate, FN rate, precision, recall, and top contributing risk factors are displayed And clicking a metric drills down to example decisions with decision_source and recent message history

Seamless Handoff

Cross-device continuity for longer tasks. Start from an SMS link on mobile and continue on desktop with a QR or magic link—no restart required. Saves progress, supports drag-and-drop on desktop and camera capture on mobile, and syncs instantly. Improves completion on complex uploads and reduces abandonment.

Requirements

Magic Link & QR Handoff
"As a claimant, I want to scan a QR code from my phone to continue my claim on my laptop so that I don’t have to restart long uploads or re-enter details."
Description

Enable users to seamlessly transfer an in-progress claim intake session from mobile to desktop (and vice versa) using a secure magic link in SMS and a scannable QR code displayed in-app. The system generates short-lived, scope-limited tokens that encapsulate the current session context (claim ID, user role, step index, partial form data pointer) without exposing PII. When activated, the target device restores the exact step, attachments list, and any unsent inputs, eliminating restarts. Integrates with ClaimFlow’s comms service (SMS/email), routing, and identity layers to support authenticated and guest flows, and logs handoff events for auditability. Supports single-use and multi-use modes, deep-linking to specific tasks (e.g., "Upload damage photos"), and gracefully falls back to manual code entry if camera or link handlers are unavailable.

Acceptance Criteria
Mobile-to-Desktop Magic Link Restore
Given an in-progress claim intake on mobile at step index N with unsent inputs and an attachments list When the user opens the SMS magic link on a desktop browser within 15 minutes of issuance Then the desktop session restores to step index N with the same attachments list and unsent inputs pre-populated without repeating prior steps And the restore completes in 2 seconds or less after link activation And the mobile session shows the session is active on desktop to avoid duplicate edits
Desktop-to-Mobile QR Scan Restore
Given an in-progress claim intake on desktop at step index N When the user selects "Continue on mobile" to display a QR code and scans it with a mobile camera or QR app Then the mobile session opens to step index N with the same attachments list and unsent inputs restored And the restore completes in 3 seconds or less after scan And the QR image contains only an opaque token and no PII
Token Security, TTL, and Mode Behavior
Given a handoff token is generated When inspecting the URL and QR payload Then no PII (e.g., name, phone, email, address) is present; only an opaque token is exposed And the token is signed and encrypted and encodes only: opaque claim ID, user role, step index, partial form data pointer, issuance timestamp, expiry timestamp, mode (single|multi) And the token expires 15 minutes after issuance (TTL = 15 minutes) And in single-use mode, the first successful activation invalidates the token; subsequent activations return 401 and offer to generate a new link And in multi-use mode, up to 3 successful activations are allowed within TTL; the 4th attempt returns 429 and offers to generate a new link And attempts with mismatched claim or role are blocked with 403 and do not reveal additional details
Deep Link to Specific Task
Given a magic link or QR encodes the target task "Upload damage photos" within claim C When the user activates the handoff on the target device Then the session opens directly to the "Upload damage photos" UI for claim C regardless of previous step And previously added attachments are visible and not duplicated And if the task is already complete, the user is redirected to the next incomplete step with a notice that the task is complete
Manual Code Fallback
Given the user cannot scan the QR or open the magic link When the user chooses "Enter code manually" and inputs a valid 8-character alphanumeric code within TTL Then the session restores to the same step index and data context as the original device And on invalid or expired code, an error "Code invalid or expired" is displayed with options to resend/regenerate And after 5 consecutive invalid attempts, code entry is rate-limited for 5 minutes and the event is logged
Authenticated and Guest Flows
Given an authenticated user with role R or a guest claimant without an account initiates a handoff When the handoff is activated on the target device Then access control enforces restoration only for the same claim and role context And authenticated users are seamlessly signed in on the target device via the token without password re-entry And guest users are granted a scoped guest session to the claim without requiring account creation And if the active identity does not match the token's role or claim scope, the handoff is blocked with 403 and guidance to switch accounts or request a new link
Audit Logging and Observability
Given handoff token creation, delivery (SMS/email), activation, failure, or expiry events occur When these events are processed Then an audit log entry is recorded for each with timestamp, opaque claim ID, role, device type, delivery channel, event type, correlation ID, and outcome, with no PII values stored And delivery receipts from the comms service are captured and linked to the correlation ID And audit events are visible in the admin feed within 10 seconds of occurrence And metrics report end-to-end handoff duration and success/failure rates and are exported to the analytics pipeline
Autosave & State Restoration
"As an independent adjuster, I want my partially completed intake to be saved automatically so that I can resume on another device exactly where I left off."
Description

Continuously persist claim intake progress—including form fields, checklists, and attachment metadata—so users can resume on any device without data loss. Implement debounced autosave for text inputs, step-level commits, and resumable upload manifests for large media. Store state server-side keyed by claim session token and versioned to enable safe restoration. On resume, prefill all fields, restore navigation position, rehydrate pending uploads, and display a clear “Resumed from last save” indicator. Integrates with ClaimFlow’s workflow engine to maintain task state and with the document store for chunked, resumable uploads.

Acceptance Criteria
Debounced Autosave on Text Inputs
Given a user is editing a text field in the claim intake form When the user stops typing for 800 ms or the input loses focus Then the current value is persisted server-side under the claim session token and the client receives an acknowledgment within 2 seconds And no more than one save is sent per field per debounce window And if the value has not changed since the last save, no new write occurs
Step Commit on Navigation and Restoration
Given a user completes or navigates away from a step (Next, Back, or route change) When navigation is triggered Then all fields and checklist states in the current step are committed atomically with an incremented version number And upon returning or resuming on any device, the user is landed on the last committed step with the previous scroll position restored within 1 second And a dismissible banner "Resumed from last save" with the last-saved timestamp is displayed
Resumable Upload Manifest and Rehydration
Given a user uploads a media file larger than 10 MB When the upload starts Then a resumable manifest (file hash, size, chunk size, chunk count) is created and chunks up to 5 MB are uploaded with up to 3 retries per chunk and exponential backoff starting at 500 ms And if the session ends before completion When the user resumes on any device Then already uploaded chunks are detected from the manifest and only missing chunks are uploaded And upon completion, attachment metadata (filename, size, mimeType, hash, upload status, document id) is persisted and visible in the attachments list
Cross-Device Resume with Indicator
Given a user starts on mobile via SMS link and continues on desktop via QR or magic link within the session validity window (up to 7 days) When the desktop session opens Then all previously saved fields, checklist states, and attachment metadata are prefilled within 2 seconds And any in-flight uploads are rehydrated and resumed automatically And a banner "Resumed from last save at [timestamp]" is displayed for at least 5 seconds and can be dismissed
Versioned State and Conflict Handling
Given server-side state is versioned per claim session token When a save is attempted with a stale version Then the server returns a 409 Conflict without overwriting newer data And the client informs the user that newer changes exist and reloads the latest state within 2 seconds of acknowledgment And after reload, the latest values are shown and any unsynced local edits are reapplied field-by-field where possible; otherwise the user is prompted to resolve
Offline Autosave Queue and Sync on Reconnect
Given the device loses network connectivity during intake When the user continues editing fields or capturing attachments Then autosave operations are queued locally with unique request IDs and visible "Pending save" status And upon reconnection, queued operations are sent in order, deduplicated by ID, and acknowledged by the server within 10 seconds for up to 50 queued operations And the UI reflects transition from "Pending save" to "Saved" without data loss
Workflow Engine and Document Store Integration
Given an intake session tied to a workflow task When autosave or restoration occurs Then the workflow engine receives an event updating task progress and active step within 2 seconds of the save And resumable uploads use the document store’s chunked API and, upon completion, the task is updated with attachment metadata and document IDs And resuming the session does not create duplicate tasks; the same task ID remains active
Real-time Cross-Device Sync
"As a claims manager, I want updates I make on desktop to appear instantly on my phone so that I can verify details and capture photos without duplicating work."
Description

Provide bi-directional, near real-time synchronization of form fields, checklist completion, and upload progress across active devices using WebSockets or HTTP/2 server push. Changes made on one device propagate within seconds to others viewing the same session, including status of chunked uploads and validation results. Implement message diffing, throttling, and reconnect logic for reliability. Integrate with ClaimFlow’s validation and rules engine so server-side validations trigger UI updates across devices. Include presence indicators ("Also open on: iPhone") and gracefully degrade to periodic polling if sockets are unavailable.

Acceptance Criteria
Field Edits Sync Across Devices
Given two authenticated devices are viewing the same ClaimFlow intake session via an active real-time channel When a user edits any form field (text, number, date, select, radio, checkbox) on Device A Then Device B displays the updated value within 2 seconds and the server confirms a single authoritative value And conflicting concurrent edits are resolved deterministically using server timestamp last-write-wins, with both devices showing the same final value within 2 seconds And the change event includes field identifier, previous value, new value, and server version so clients can reconcile without full refresh
Checklist State Synchronization
Given a checklist is visible on two devices in the same session When a checklist item is marked complete or incomplete on one device Then the other device reflects the new state and recalculated progress within 2 seconds And the order of items and any dependency rules remain consistent across devices And no duplicate completion events are created on the server (idempotent updates verified by checklist item ID and version)
Chunked Upload Progress Mirroring
Given a large file upload using chunked transfer has started on Device A When Device B is viewing the same session Then Device B shows the file entry with filename, size, and progress percentage that updates at least every 2 seconds And if the upload completes, fails, or is canceled on either device, the status change is reflected on all devices within 2 seconds And resuming a paused or failed upload on one device updates progress accurately on the other without duplicating the file on the server
Server-Side Validation Broadcast
Given ClaimFlow’s validation and rules engine evaluates a submitted field set When the server returns validation results (errors or passes) for any field Then all devices in the session display the same validation state and messages for the affected fields within 2 seconds And clearing the error by fixing the input on one device removes the error on all devices after server revalidation within 2 seconds And validation messages include field identifiers and codes so clients render consistent UI without ambiguity
Presence Indicators Across Sessions
Given a user has the same session open on multiple devices When a device joins or leaves the session Then each active device updates the presence indicator (e.g., “Also open on: iPhone, Chrome on Mac”) within 3 seconds And presence displays distinct device labels and does not show the current device in the list And presence remains accurate through reconnects or network blips (no ghost sessions beyond 10 seconds)
Resilience and Fallback (Sockets to Polling)
Given a device loses its WebSocket connection or sockets are blocked When the client detects the issue Then it switches to HTTP/2 or HTTP polling at a 10-second interval within 5 seconds and continues syncing changes And when sockets become available, the client resumes the WebSocket and stops polling without duplicating events And locally queued changes are retried with exponential backoff (up to 30 seconds) and applied in order with no loss or duplication
New Device Join State Snapshot
Given a session is active on Device A with unsaved form changes and running uploads When Device B joins the same session via QR or magic link Then Device B receives an authoritative state snapshot (fields, checklist states, validation states, and in-flight upload statuses) within 2 seconds And subsequent changes are received as diffs without requiring a full page reload And both devices remain in sync for all subsequent edits and events within the stated latency thresholds
Device-Optimized Uploads
"As a claimant, I want to snap photos on my phone and then drag additional files from my desktop so that I can provide all required evidence with minimal hassle."
Description

Deliver device-specific media capture and file handling: camera capture and document scan intents on mobile; drag-and-drop, multi-select, and clipboard paste support on desktop. Implement resumable, chunked uploads with pause/resume, client-side compression for images/video, and automatic retry on flaky networks. Enforce file type, size, and count constraints from ClaimFlow’s policy configuration. Provide clear progress UI and background upload support on mobile. Normalize metadata (EXIF timestamps, GPS) and attach to claim entities for downstream NLP extraction.

Acceptance Criteria
Mobile Camera and Document Scan Capture
Given a supported iOS/Android device and user taps "Capture Photo", when permission is granted, then the native camera intent opens and the captured image is returned to the upload queue. Given a supported iOS/Android device and user taps "Scan Document", when the OS document scanner is available, then a multi-page scan flow opens and produces a PDF (or images) added to the upload queue. Given camera permission is denied, when the user taps "Capture Photo", then the app prompts for permission and offers a "Choose from Library" fallback without blocking the flow. Given an image or scanned document is captured, when the user taps Accept, then the file is validated against policy before being queued and a preview thumbnail is displayed.
Desktop Drag-and-Drop, Multi-Select, and Clipboard Paste
Given a desktop browser on the upload step, when the user drags 1..N files onto the drop zone, then all supported files are queued and unsupported files are rejected with an inline error stating the reason. Given the user opens the file picker, when they multi-select files, then all selected files are queued respecting policy limits. Given an image or file is on the system clipboard, when the user presses Ctrl/Cmd+V over the uploader, then the pasted content is added to the queue with correct MIME type and filename (or a generated name if none).
Resumable Chunked Uploads with Pause/Resume and Auto-Retry
Given a file >= 1 MB is uploading, when transfer begins, then the client sends the file in chunks no larger than 5 MB with a per-chunk checksum and a final file hash. Given a network interruption occurs mid-upload, when connectivity returns, then the client automatically retries failed chunks up to 5 times per chunk using exponential backoff (1s, 2s, 4s, 8s, 16s) before marking the file Failed. Given the user presses Pause on an in-progress file, when they press Resume, then upload continues from the last confirmed chunk without re-uploading previously completed chunks. Given the app or page is refreshed, when it reloads, then any in-progress uploads restore state and continue without restarting completed chunks.
Client-Side Media Compression
Given an image larger than 4 MB is added, when queued, then the client compresses it to target <= 2 MB with a maximum long edge of 2560 px, preserving orientation and copying EXIF/GPS to metadata storage. Given a video larger than 20 MB is added, when queued, then the client transcodes to MP4 (H.264/AAC) at 720p with target bitrate <= 4 Mbps; if the source is already <= 720p and <= 4 Mbps, then it is not transcoded. Given compression is applied, when QA compares the compressed image to the original, then objective quality is SSIM >= 0.95; if not achievable under policy size, the upload is blocked with an error explaining the size constraint.
Policy-Driven File Validation (Type, Size, Count)
Given a policy for claim type Auto allows MIME types [image/jpeg, image/png, application/pdf, video/mp4], per-file max size 25 MB, max file count 20, and total size 500 MB, when the user adds files, then only allowed types are accepted and all limits are enforced. Given a user attempts to add a disallowed type or a file exceeding 25 MB, when they drop or select it, then the file is rejected and an inline error states which constraint failed (type or size) and the configured limit. Given the user exceeds max file count or total size, when adding more files, then additional files are blocked and the UI displays remaining capacity (e.g., files left, MB remaining) based on policy. Given the policy configuration updates on the server, when the uploader is open, then the client fetches and applies the new policy within 5 seconds and validates subsequent additions against the updated rules.
Progress UI and Background Uploads on Mobile
Given one or more files are queued, when uploads start, then each file displays an individual progress indicator (0–100%), state (Queued, Uploading, Paused, Retrying with attempt count, Completed, Failed), and an overall progress bar is shown. Given the app is sent to background on iOS or Android during uploads, when background execution is permitted, then uploads continue for at least 10 minutes or until completion; if the OS suspends/kills the app, uploads automatically resume within 5 seconds of returning to foreground. Given a file completes uploading, when the user navigates away and returns to the uploader, then the Completed status, timestamp, and server-confirmed size persist and are shown without re-uploading.
Metadata Normalization and Claim Attachment
Given a photo with EXIF DateTimeOriginal and GPS is uploaded, when processing completes, then timestamp is normalized to UTC ISO 8601 and GPS is stored as decimal degrees (WGS84) with 6 decimal places; device make/model and orientation are captured and attached to the claim entity. Given a file lacks EXIF metadata, when uploaded, then the system derives timestamp from server receive time and sets metadata.source = "derived" on the claim entity. Given normalized metadata is stored, when the NLP engine is invoked, then the metadata is included in the extraction payload and available via API within 5 seconds of upload completion.
Secure Link Governance & Compliance
"As a security-conscious admin, I want handoff links to be short-lived and revocable so that claim data remains protected during cross-device use."
Description

Implement robust security for handoff links and tokens: short expiration, optional single-use, role-scoped permissions, domain binding, and device fingerprint checks. Add PIN/SMS verification for sensitive steps when resuming unauthenticated sessions. Protect PII by storing only references in tokens; all data retrieved server-side with access checks. Log all handoff access attempts for audit trails, integrate with SIEM, and expose admin controls for policy (TTL, reuse, throttling). Ensure compliance with HIPAA-adjacent privacy practices and state insurance regulations by supporting data minimization, revocation, and consent banners.

Acceptance Criteria
Handoff Token TTL, Single-Use, and Throttling Enforcement
- Given a handoff link with default policy TTL of 15 minutes, When the link is opened after 15 minutes from issuance, Then the request is rejected with 401 LINK_EXPIRED, no PII is returned, and the attempt is logged. - Given an admin-configured TTL between 5 and 60 minutes, When a link is issued with a custom TTL, Then the link expires exactly at the configured TTL and cannot exceed 60 minutes. - Given a link issued with single-use enabled, When it is accessed successfully once, Then any subsequent access returns 410 LINK_CONSUMED, the token remains invalid, and events are logged. - Given rate-limit policy of max 5 validation attempts per 10 minutes per token and per IP, When attempts exceed the threshold, Then subsequent attempts receive 429 RATE_LIMIT and the token is not consumed. - Given expected clock skew of up to 2 minutes, When requests arrive within TTL+2 minutes, Then they are accepted; beyond that window they are rejected as expired.
Role-Scoped Permissions and Domain Binding
- Given a token scoped to role "Claimant Upload", When the token is used to call an endpoint outside this scope, Then return 403 ROLE_SCOPE_VIOLATION and no action is performed. - Given a token bound to allowed domain(s) [e.g., claims.insurer.com], When the link is resolved from a non-allowed origin, Then return 403 DOMAIN_MISMATCH and log the origin. - Given correct role scope and domain, When the user accesses the permitted resources, Then only resources within the scope are returned and all out-of-scope requests are denied with 403. - Given cross-claim access, When a token for Claim A is used to access Claim B, Then return 403 CLAIM_SCOPE_VIOLATION and log the attempt.
Device Fingerprint Continuity Verification
- Given an initial access establishing a device fingerprint, When a resume attempt occurs from a device with similarity score ≥ 0.80 within a 24-hour window, Then the session resumes without step-up. - Given a resume attempt with similarity score < 0.80 or from a new device, When accessing any protected step, Then require step-up verification before proceeding. - Given the device fingerprint includes user-agent, OS, viewport, IP /24, and signed cookie, When any single attribute changes slightly, Then similarity scoring tolerates minor changes without false denials. - Given fingerprint signals are unavailable (e.g., blocked cookies), When resuming, Then step-up verification is required before sensitive steps.
Step-Up Verification via PIN/SMS for Sensitive Steps
- Given an unauthenticated resume to a step marked Sensitive, When the user requests verification, Then send a 6-digit SMS OTP to the phone number on record and mask it in UI. - Given an OTP is issued, When the correct code is entered within 5 minutes, Then access is granted and the sensitive step is unlocked. - Given OTP entry, When 5 consecutive invalid attempts occur, Then lock verification for 15 minutes, return 423 VERIFICATION_LOCKED, and log the event. - Given resend controls, When the user requests resends beyond 3 times within 10 minutes, Then block additional resends with 429 and log throttling. - Given number mismatch, When the phone number on record is unavailable or invalid, Then block step-up, display a support escalation path, and log the failure without exposing PII.
PII Minimization and Server-Side Access Controls
- Given a handoff token, When inspected, Then it contains only an opaque identifier, scope, expiry, policy version, and domain binding—no PII fields (e.g., name, SSN, address). - Given client-side requests, When attempting to retrieve PII using only the token, Then the API returns 403 and requires server-side authorization tied to claim and role. - Given server-side retrieval, When authorization checks pass (claim association + role scope), Then necessary PII is returned to client; otherwise 403 and no data leakage. - Given token format, When analyzed, Then it is at least 32 bytes of entropy and cannot be decoded to reveal PII. - Given cross-tenant isolation, When a token from Tenant A is used against Tenant B endpoints, Then return 403 TENANT_SCOPE_VIOLATION and log the event.
Audit Logging and SIEM Integration
- Given any handoff access attempt (success or failure), When it occurs, Then an immutable audit event is written with: token_id, claim_id, tenant_id, role, timestamp (UTC), IP, user-agent hash, device score, outcome, reason code, and policy version. - Given audit events, When exported to SIEM via HTTPS/syslog, Then 95th percentile delivery latency is ≤ 60 seconds and end-to-end drop rate is < 0.1% over a 24-hour period. - Given transient SIEM outages, When delivery fails, Then events are buffered and retried with exponential backoff up to 24 hours, without data loss. - Given audit retention policy, When queried, Then events are available for at least 1 year and are append-only (no edits; corrections recorded as new events).
Admin Policy Controls, Revocation, and Consent Banner
- Given an admin updates policy (TTL 5–60 min, single-use toggle, device similarity threshold 0.60–0.90, OTP retry/resend limits, rate limits, allowed domains), When saved, Then the new version is active within 5 minutes and recorded in policy history. - Given an active token, When an admin revokes it by ID or claim, Then further access attempts fail within 60 seconds with 401 LINK_REVOKED and are logged. - Given a first-time open of a handoff link, When the consent banner is displayed, Then the user must explicitly consent (checkbox + Continue) before any data processing; consent decision and policy text version are captured in audit. - Given a user declines consent, When proceeding is attempted, Then the session is terminated, no PII is processed, and guidance to contact support is shown. - Given jurisdictional privacy messaging requirements, When the user locale/state is detected, Then the banner displays the appropriate notice text variant configured by admins.
Concurrency & Conflict Resolution
"As an adjuster, I want the system to prevent conflicting edits and show me what changed so that our team doesn’t lose or overwrite important details."
Description

Handle simultaneous edits from multiple devices or users on the same claim intake. Implement optimistic concurrency with per-field versioning and last-writer-wins defaults, plus soft-locking for high-risk steps (e.g., bank details). Provide non-blocking conflict prompts that show what changed and allow accept/override, and ensure attachments are merged safely. Record an immutable change log for traceability. Integrates with the real-time sync layer and ClaimFlow’s workflow permissions to respect roles and step ownership.

Acceptance Criteria
Concurrent edit on same field across mobile and desktop
Given a claim intake is open on Mobile (User A) and Desktop (User B) at the same step and the "Loss Description" field version is v12 on both clients When User B saves an edit at T0 and User A saves a different edit at T0+1s without refreshing Then the server detects a per-field version mismatch and responds with a conflict payload including fieldId, previousValue, serverValue, clientValue, serverVersion, clientVersion And Mobile displays a non-blocking conflict prompt within 300 ms showing a clear diff of serverValue vs clientValue And the default selection is Last-Writer-Wins (serverValue) And User A can choose Accept server value, Overwrite with my value, or Merge (for multi-line text fields) and confirm in a single action And upon resolution the field version increments to v13 and both clients reflect the final value within 500 ms p95, 2 s max And no unrelated fields are modified And both attempted saves and the chosen resolution are recorded in the immutable change log with timestamps and actor IDs
Soft-lock enforcement on high-risk Bank Details step
Given a user with permission to edit the Bank Details step focuses any editable field in that step When the first keystroke occurs Then a soft-lock for that step is created with owner userId and timestamp and broadcast to all connected clients within 1 s p95 And other users see the step in read-only with a banner "Soft-locked by <name>" and Save actions disabled And any API save attempt by non-owners while the lock is active returns HTTP 423 Locked And the lock auto-expires after 5 minutes of inactivity (no keystroke/paste or heartbeat) or on explicit exit/submit by the owner And the client sends a heartbeat every 20 s while the owner is active; lack of heartbeat leads to lock expiry at 5 minutes And only the step owner or an Admin can take over the lock via explicit Override action with confirmation; the takeover is logged And lock state changes (acquire, release, override) are recorded immutably
Safe attachment merge from mobile capture and desktop upload
Given attachments are being added concurrently from Mobile (camera) and Desktop (drag-and-drop) When files are uploaded in parallel Then all successfully uploaded attachments appear in a single consolidated list ordered by server receive time And duplicates are deduplicated by SHA-256 content hash (primary) and filename+size heuristic (secondary) with only one retained and a "Deduplicated" note in metadata And chunked uploads support automatic resume; partial/incomplete chunks do not create visible items And concurrent delete and add events for the same content hash resolve via Last-Writer-Wins by server timestamp; both events are logged And no successfully uploaded attachment is lost due to concurrency And each attachment shows uploader, device type, timestamp, and content hash in metadata And preview and download remain functional after merges
Immutable change log for concurrent updates
Given any field or attachment is created, updated, deleted, or conflict-resolved When the operation is accepted by the server Then an append-only audit entry is created containing: uniqueId, claimId, stepId, fieldId or attachmentId, action, oldValue (redacted for secrets), newValue (redacted), actor userId or deviceId, role, serverTimestamp (ISO 8601 UTC), clientTimestamp, preVersion, postVersion, and conflictResolution (if applicable) And entries are chained via SHA-256 (hash_n = SHA256(hash_{n-1} || entry_n)) to provide tamper evidence And any attempt to modify or delete an existing entry is rejected with HTTP 403 and logged as a security event And an API allows paginated retrieval and export (CSV/JSON) ordered by serverTimestamp; responses for up to 1,000 entries return within 800 ms p95 And a verification endpoint returns the latest chain hash and verifies integrity over a requested range
Real-time sync propagation and per-field versioning with LWW default
Given two or more clients are connected to the same claim When any client saves a change to a field Then all connected clients receive the updated value and version within 500 ms p95, 2 s max And if two changes target different fields, both persist without prompts and versions increment independently And if two changes target the same field, passive clients temporarily reflect Last-Writer-Wins while the active editor is prompted to resolve the conflict non-blockingly And per-field version numbers increment monotonically starting from v1 and never skip more than +1 per accepted write And clients include the last known version on save; the server rejects stale writes with a conflict payload rather than overwriting silently
Role and step ownership enforcement during conflicts
Given workflow permissions assign step ownership to Adjuster A for the current step When a non-owner attempts to resolve a conflict or override another user’s change in that step Then the UI does not present Override options to the non-owner and any direct API attempt returns HTTP 403 Forbidden And the step owner and Admin roles see full Accept/Overwrite/Merge options in conflict prompts; other roles can view diffs but cannot force-apply changes on protected fields And soft-lock acquisition on high-risk steps is restricted to the owner or Admin; non-owners see read-only state And all permission denials, attempted overrides, and successful owner/Admin resolutions are logged with role context
Offline edits reconciliation on reconnect
Given a client goes offline while editing multiple fields and adding attachments When the client reconnects to the network Then it fetches the latest per-field versions and attachment index within 1 s and compares them to local pending changes And non-conflicting changes are applied automatically and synced to the server within 5 s of reconnect And for each conflicting field, a non-blocking prompt shows a diff with options to Accept server, Overwrite with mine, or Merge (where supported); the user can resolve each separately And queued attachment uploads resume automatically with deduplication by content hash; no duplicate items are created And if the user dismisses a conflict prompt without action, Last-Writer-Wins (server) remains in effect and the local change is retained in undo history but not sent And all reconciliations and decisions are recorded in the immutable change log
Handoff Analytics & Telemetry
"As a product owner, I want visibility into handoff usage and drop-off points so that we can improve completion rates and reduce abandonment."
Description

Track and report key funnel metrics for cross-device handoffs: link/QR generation, scan/click, resume success, time-to-resume, step completion, abandonment points, and upload success rates by device. Emit structured events with session identifiers and roles to the analytics pipeline. Provide dashboards and alerts for anomalies (e.g., elevated resume failures, slow upload completion) to guide optimization. Expose per-carrier and per-workflow breakdowns to inform configuration changes. Respect user consent and privacy settings and redact sensitive fields from telemetry.

Acceptance Criteria
Emit Structured Handoff Funnel Events
Given a cross-device handoff session is initiated When any of the following actions occurs: link_qr_generated, link_clicked_or_qr_scanned, resume_attempted, resume_succeeded, resume_failed, step_completed, upload_started, upload_succeeded, upload_failed, session_abandoned Then emit a structured analytics event within 5 seconds containing required fields: event_name, session_id (UUIDv4), idempotency_key, handoff_method (qr|magic_link|sms_link), user_role (claimant|adjuster|manager), carrier_id, workflow_id, device_type (mobile|desktop), os, browser, timestamp (ISO-8601 UTC), privacy_consent (true|false|unknown), schema_version And redact or omit any sensitive content (free text, images, PII) from the payload And guarantee at-least-once delivery with downstream de-duplication by idempotency_key And deliver ≥99.5% of events to the analytics pipeline within 60 seconds of action
Correlate Sessions Across Devices
Given a user starts on mobile from an SMS link and resumes on desktop via QR or magic link When both clients use the same handoff token Then attribute both device streams to a single session_id and capture device_type for each event And compute time_to_resume as desktop_resume_timestamp minus initial_mobile_start_timestamp And increment resume_attempt_count for each resume_attempted event And mark resume_success boolean on the latest resume outcome with error_code on failures And ensure no duplicate sessions are created for repeated scans/clicks within 5 minutes
Compute Funnel KPIs
Given handoff events are available in the analytics store When streaming aggregations run every 5 minutes and a daily batch runs at 00:15 UTC Then compute, per carrier_id, workflow_id, device_type, and date, the following metrics: resume_success_rate, median_time_to_resume, step_completion_rate per step, abandonment_rate per step, upload_success_rate, median_upload_completion_time And make aggregates queryable with data freshness SLA ≤15 minutes for streaming and ≤2 hours for daily And exclude events with privacy_consent=false from behavioral rate metrics when carrier setting requires opt-in
Dashboards With Per-Carrier/Workflow Breakdown
Given an authorized user opens the Handoff Analytics dashboard When they apply filters for date range, carrier_id, workflow_id, device_type, and user_role Then display charts/tables for resume_success_rate, time_to_resume, step completion and abandonment by step, and upload success by device And allow drilldown from carrier to workflow to session-level samples without exposing PII And support CSV export of aggregated tables for the applied filters And load initial dashboard in ≤3 seconds from cache with data age banner showing last refresh time
Anomaly Alerts for Resume Failures and Slow Uploads
Given alerting is configured with default thresholds When any carrier_id+workflow_id has resume_success_rate below 95% for 15 consecutive minutes or median_upload_completion_time increases by ≥100% over its 14-day moving baseline for 15 minutes Then send a single deduplicated alert to Slack and Email within 5 minutes of detection including metric, threshold, scope, and dashboard link And auto-resolve the alert when the metric is back within threshold for 15 minutes And allow per-carrier/workflow overrides of thresholds and channels
Privacy, Consent, and Redaction
Given a user has not granted analytics consent or the carrier has disabled analytics When telemetry would be emitted Then set privacy_consent=false and suppress optional identifiers (device fingerprint, IP-derived geo) while still emitting strictly necessary operational events And never include PII, message text, or image contents in any event; store only hashed media IDs and size/type metadata And honor the browser Do Not Track signal by treating consent as not granted And enforce data retention of 90 days for raw events with deletion upon carrier request within 7 days

Cluster Explorer

Interactive heatmaps and timeline drilldowns that reveal related-claim clusters by shared entities (phone, VIN, address, IP, repairer) and behaviors. Click any cluster to see its footprint, shared attributes, and growth over time to quickly spot organized schemes and focus SIU effort where it matters most, reducing investigation time and leakage.

Requirements

Unified Entity Graph
"As a claims investigator, I want related claims and entities to be automatically linked into a single view so that I can quickly identify organized activity without manually reconciling records."
Description

Build and maintain a canonical graph of claims and shared entities (phone numbers, VINs, addresses, IPs, repairers), normalizing formats, deduplicating records, and resolving fuzzy matches to unify related items. The graph must update incrementally as new claims and artifacts are ingested by ClaimFlow’s NLP engine, exposing a query layer that powers clustering by shared attributes. Include confidence scores for linkages, explainability metadata (e.g., which tokens matched), and safeguards for PII handling. Provide APIs for read-optimized retrieval to the Cluster Explorer and batch jobs for backfills and re-indexing.

Acceptance Criteria
Incremental Graph Update on New Claim Ingestion
Given a new claim with extracted artifacts (phone, VIN, address, IP, repairer) is published by the NLP engine When the graph ingestion pipeline processes the event Then new nodes are created only for unseen normalized entities and a claim node if not existing And edges between the claim and entities are created with confidence, source, and timestamp metadata And re-ingesting the same claim/artifacts (same claim_id and artifact_id) does not create duplicate nodes or edges (idempotent) And p95 end-to-end latency from event publish to availability via the query API is ≤ 120 seconds; p99 ≤ 300 seconds under nominal load (≥ 50 events/sec) And transient failures are retried with exponential backoff up to 5 attempts; after which an alert is emitted and the event is placed on a dead-letter queue
Canonical Normalization and Deduplication of Entities
Given raw entity values in varied formats for phone, VIN, address, IP, and repairer When normalization runs Then phone numbers are stored in E.164 format with country code; invalid phones are flagged and not linked And VINs are 17-character uppercase, ISO 3779 check digit validated; invalid VINs are flagged and not linked And US addresses are CASS-standardized; non-US addresses are normalized via libpostal-equivalent rules with country recorded; components are structured (street, city, region, postal_code, country) And IPs are normalized to canonical text for IPv4/IPv6; private/reserved ranges are flagged And repairers are resolved to canonical legal entities using available IDs (e.g., FEIN/Tax ID) and normalized names; duplicates are merged And deduplication merges entities with identical canonical keys; a merge history record is retained with prior identifiers And a golden test set of 500 examples per entity type passes 100% for expected normalized values and merge behavior
Fuzzy Resolution with Confidence Scores and Explainability
Given pairs of near-duplicate or partially matching entities When fuzzy resolution evaluates linkage Then each resulting edge includes a confidence score in [0,1] with at least two-decimal precision And on a labeled validation set of 5,000 pairs per entity type, the operating threshold yields precision ≥ 0.98 and recall ≥ 0.92 And each edge includes explainability metadata: matched_tokens, token_weights, normalization_steps, and distance_metrics And the query API returns confidence and explainability fields for ≥ 99.9% of edges; missing fields are treated as errors in logs and metrics And the linkage threshold is configurable at runtime (no redeploy) and takes effect within 5 minutes of change
Read-Optimized Query Layer for Cluster Explorer
Given a request to retrieve related claims by shared attributes (claim_id or entity value/type) When the query API is called with typical filters Then p50 latency ≤ 150 ms, p95 ≤ 500 ms, and p99 ≤ 1,500 ms for result sets ≤ 1,000 nodes on a dataset ≥ 10M nodes / 50M edges And the API supports filters for entity_types, min_confidence, date_range, and jurisdiction, and returns stable pagination via an opaque cursor And results are ordered by confidence desc then recency; truncation due to payload limits is indicated with a next_cursor And each node and edge includes required fields: ids, types, normalized_value (for nodes), confidence, explainability, source, timestamps, and schema_version And rate limiting supports at least 100 QPS sustained with ≥ 99% success; excess requests receive HTTP 429 with retry-after
PII Safeguards and Auditability
Given production roles and access policies are configured When APIs and jobs process claims and entities Then all PII is encrypted at rest (AES-256) and in transit (TLS 1.2+); keys are managed by KMS with rotation ≤ 90 days And access to raw PII via APIs is restricted to authorized roles (e.g., SIU_Analyst, Admin); other roles receive masked values (phone last-4 only, address city+region only) And application logs, traces, and metrics never contain raw PII; automated scanners run hourly and report 0 violations over a 24-hour soak test And every PII read is audit-logged immutably with user_id, role, purpose, fields_accessed, timestamp, and request_id; audit records are queryable within 5 minutes And right-to-be-forgotten requests remove or detach PII from graph and edges within 24 hours; subsequent queries return no PII for the subject and an audit entry confirms completion
Batch Backfill and Re-indexing Idempotency
Given a historical corpus of claims and artifacts When the backfill job runs Then the job is idempotent: re-running on the same inputs produces identical node/edge counts and checksum hashes of adjacency lists And processing throughput is ≥ 5,000 claims/min and ≥ 50,000 edges/min on the reference environment, with progress metrics exported And failures support checkpoint/resume with ≤ 5 minutes time-to-resume; partial outputs are consistent And during backfill or re-index, query API success rate remains ≥ 99.9% and p95 latency degrades by < 20% from baseline And re-indexing can be performed online, recalculating confidences and refreshing indexes without downtime
Data Contract Compliance with Cluster Explorer
Given Cluster Explorer consumes the graph via the query API When requesting clusters for fixture claims and entities Then responses conform to schema version v1 with required fields (node_id, node_type, normalized_value, edge_confidence, explainability.tokens, timestamps) And contract tests in CI pass 100% against mock and staging instances And additive changes are backward-compatible; unknown fields are ignored by the client; breaking changes require a version bump and ≥ 30-day deprecation notice And five golden snapshot responses match expected shape and key values (excluding dynamic timestamps)
Interactive Cluster Heatmap
"As an SIU analyst, I want to see hotspots of related claims on an interactive map so that I can prioritize investigations where suspicious activity is most concentrated."
Description

Provide an interactive geographic heatmap and entity-density view that visualizes concentrations of related-claim clusters across regions and configurable grids. Support pan/zoom, dynamic binning, and color scaling for different claim volumes. Enable filtering by entity type (phone, VIN, address, IP, repairer), LOB, claim status, and date range, with real-time updates and tooltips showing key metrics (cluster size, recent growth, risk score). Clicking a hotspot selects the cluster and opens details. Ensure performant rendering on large datasets via aggregation, tiling, and server-side caching.

Acceptance Criteria
Render and Navigate Heatmap at Scale
Given a dataset of ≥5,000,000 claims and ≥100,000 related-claim links, when the user opens Cluster Explorer, then the geographic heatmap renders the initial view within ≤2,000 ms and displays density using the default grid. Given the heatmap is visible, when the user pans or zooms, then tiles load progressively with p95 tile fetch time ≤300 ms and no main-thread block >100 ms. Given the user changes zoom level, when aggregation recalculates, then total visible counts are preserved within ±1% compared to the previous level aggregated to the new bins. Given typical analyst hardware (≥4 vCPU, 16 GB RAM) and a ≥50 Mbps connection, when continuously panning for 10 seconds, then the UI remains responsive with input latency ≤100 ms p95 and no crashes or memory leaks.
Dynamic Binning and Color Scaling
Given the viewport and zoom level, when the user zooms in or out, then bin size auto-adjusts so that 80–200 bins are visible in the viewport and the legend updates accordingly. Given the current filtered dataset, when the heatmap renders, then the color scale domain is derived from the in-view data (min, median, max) and no more than 1% of bins are clipped at either end. Given the user toggles color scale mode, when switching between linear and logarithmic, then the map updates in ≤200 ms and the legend reflects the new scale with correct tick labels. Given WCAG 2.1 AA requirements, when the legend is displayed, then legend text has ≥4.5:1 contrast against its background and selected palette is colorblind-friendly (no red–green ambiguities).
Real-Time Filter Application
Given filters for entity type (phone, VIN, address, IP, repairer), LOB, claim status, and date range, when the user applies any single filter, then the heatmap, legend, and counts update to the intersection of filters and reflect only filtered data. Given tile re-aggregation is required, when filters change, then the visible map updates in ≤1,200 ms p95 with a non-blocking loading indicator; if only color rescaling is needed, updates occur in ≤500 ms. Given multiple filters are combined, when the intersection yields zero results, then the map shows an empty-state message and legend/tooltip indicate zero without errors. Given a shareable URL, when the user copies the link, then reopening it restores the same filters, viewport, zoom, and color scale mode.
Tooltip Metrics Accuracy
Given the pointer hovers a hotspot (or keyboard focus lands on it), when a tooltip is requested, then it appears within ≤150 ms and shows cluster size, recent growth (last 30 days), and risk score (0–100) for that hotspot. Given the same bin is queried via API, when comparing values, then tooltip metrics match backend values within ±1 claim for counts and ±0.1 for risk score. Given locale settings, when numbers render, then counts include thousands separators and growth shows +/−% with one decimal. Given accessibility requirements, when the tooltip is focused, then it is reachable by keyboard, announced via ARIA with metric labels, and does not obscure the hovered bin; pressing Esc dismisses it.
Hotspot Selection Opens Cluster Details
Given the heatmap is visible, when the user clicks a hotspot, then that cluster becomes selected (distinct visual state) and a details panel opens within ≤300 ms. Given the details panel is open, when rendered, then it displays cluster footprint (geographic extent), shared attributes (phone, VIN, address, IP, repairer), cluster size, risk score, and a growth-over-time timeline covering at least the last 12 months. Given the user pans/zooms or adjusts filters, when a cluster is selected, then the selection persists until explicitly cleared; a Clear Selection control is visible and returns the map to unselected state. Given keyboard-only navigation, when the user tabs through hotspots, then Enter selects a hotspot and opens the same details panel; Esc closes it and returns focus to the previously focused hotspot.
Server-Side Aggregation, Tiling, and Caching
Given tile endpoints (/tiles/{z}/{x}/{y}?filters), when the client requests tiles, then responses are aggregated server-side and compressed (gzip/br) with ETag and Cache-Control: max-age=300, stale-while-revalidate=600. Given a warm cache, when requesting in-view tiles at common zoom levels (Z=4–10), then p95 server response time is ≤250 ms; with a cold cache, p95 is ≤700 ms for continental coverage. Given filters change, when new tiles are requested, then cache keys incorporate a stable filter hash and outdated tiles are invalidated within ≤60 s; data freshness lag is ≤5 minutes from ingestion. Given transient server errors, when a tile request fails, then the client retries up to 2 times with exponential backoff and renders a non-blocking error state without blocking other tiles.
Configurable Grid and Density Mode Toggle
Given grid configuration controls, when the user selects a grid size (e.g., 1 km, 5 km, 10 km) or switches between square and hex bins, then the map re-renders within ≤1,000 ms and the legend updates to reflect the new bin definition. Given the same filtered dataset, when switching grid sizes, then the sum of counts across all visible bins remains within ±1% of the total filtered claim count. Given a density vs. count toggle, when the user switches to density mode, then values normalize by bin area and units are clearly labeled in the legend and tooltips; switching back restores raw counts. Given a saved view, when reloading, then the previously chosen grid size, bin shape, and density/count mode are restored.
Temporal Growth Drilldown
"As a fraud lead, I want to analyze how a cluster grows over time so that I can detect emerging schemes early and intervene before losses escalate."
Description

Enable timeline drilldowns for any selected cluster to show growth over time with daily/weekly/monthly rollups, first/last seen dates, and trend indicators. Include playback to animate cluster evolution across the chosen window, highlighting surges and dormant periods, and statistical change detection to flag anomalous spikes. Provide time-based filters that propagate to all views and support cohort comparisons between clusters. Expose export of time series for offline analysis.

Acceptance Criteria
Timeline Drilldown with Rollups and Trend Indicators
Given a selected cluster C, a time window W, and rollup G in {daily, weekly, monthly} When the user opens the Temporal Growth Drilldown Then a time series renders with one bucket per G across W within 2 seconds And first_seen and last_seen dates for C within W are displayed and match the min and max event timestamps respectively And empty time buckets are rendered with count 0 (not omitted) And the trend indicator for the last completed bucket compares its count to the previous bucket and displays: Up if change >= +5% and >= +1 absolute, Down if change <= -5% and <= -1 absolute, Flat otherwise, with the absolute and percent deltas shown in the tooltip
Playback Animation of Cluster Evolution
Given W and rollup G are set on a selected cluster When the user clicks Play on the timeline Then the active bucket advances sequentially at 1x speed (2 buckets per second) and can be paused/resumed And users can adjust speed to 0.5x and 2x And buckets with a surge (count increase vs previous bucket >= 50% or +10 absolute) are highlighted in red during playback And dormant periods (>= 3 consecutive zero-count buckets) are shaded gray during playback And scrubbing the timeline updates the active frame within 200 ms and respects W and G
Anomalous Spike Detection on Time Series
Given a selected cluster with at least 8 prior buckets for baseline at rollup G When change detection runs on the series Then any bucket B is flagged as an anomaly if count(B) >= mean(prior K) + 3*std(prior K) and count(B) - mean(prior K) >= 5, where K = 28 (daily), 12 (weekly), 12 (monthly) And flagged buckets display an anomaly marker and tooltip with baseline_mean, baseline_std, z_score, and delta And the anomaly overlay can be toggled on/off (default On) And if baseline length < 8 buckets, detection is disabled and an informative tooltip explains the requirement
Time-Based Filter Propagation Across Views
Given the user applies a time range W via the date/time picker in the drilldown When they navigate to heatmaps, cluster list, and entity detail views Then the same W is applied to those views within 300 ms and reflected in a global filter chip And clearing W in any view removes the filter globally and restores unfiltered data And W persists across intra-feature navigation until explicitly cleared And all time computations use the selected timezone and align bucket boundaries consistently across views
Cohort Comparison Between Clusters Over Time
Given the user multi-selects 2 to 5 clusters and chooses rollup G and time window W When Compare is enabled Then the drilldown overlays one series per cluster aligned to the same bucket boundaries and legend shows cluster name, color, and total count in W And a toggle allows viewing Absolute counts or Normalized index (each series rebased to 100 at its first non-zero bucket) And hovering a bucket shows per-cluster counts and the active bucket timestamp And any cluster with no events in W is shown as a flat zero series and labeled accordingly
Export Time Series for Offline Analysis
Given at least one series is displayed (single cluster or cohort) with rollup G and window W When the user clicks Export Then the user can choose CSV or JSON format and the download starts within 2 seconds And the file includes metadata (cluster_ids, rollup, timezone, start_iso, end_iso) and rows with bucket_start_iso, bucket_end_iso, cluster_id, cluster_name, count, anomaly_flag, delta_from_prev And exports for cohorts include one row per cluster per bucket (long format) And exports covering up to 24 months at daily granularity for up to 5 clusters complete within 5 seconds
Performance and Data Integrity for Temporal Views
Given clusters up to 10k events and window W up to 24 months When loading the drilldown or changing rollup G, filters, or cohorts Then initial render completes within 2 seconds and subsequent interactions update within 300 ms And the sum of bucket counts equals the backend total for W within max(1, 0.5%) difference And first_seen and last_seen equal the min and max event timestamps in W And bucket boundaries respect daylight saving transitions in the selected timezone
Cluster Details Drawer
"As a claims manager, I want a concise cluster summary with shared attributes and example claims so that I can quickly assess severity and decide next steps."
Description

When a user selects a cluster, display a details panel showing its footprint (claims count, affected jurisdictions, involved entities), shared attributes (common phone/VIN/address/IP/repairer), exemplar claims, and a mini-network graph of relationships. Include an explainability section listing the rules and similarity signals that formed the cluster with their weights. Provide quick actions to pivot (e.g., from phone to repairer), save the cluster as a watchlist, and export evidence (CSV/PDF) with audit metadata. Ensure responsive layout and accessibility compliance.

Acceptance Criteria
Footprint and Shared Attributes Display on Cluster Selection
Given a user selects a cluster in Cluster Explorer When the Cluster Details Drawer opens Then it opens within 2000 ms And it displays the cluster footprint including total claims count, affected jurisdictions with per-jurisdiction claim counts, and involved entities grouped by type (phone, VIN, address, IP, repairer) with counts And only categories with at least one value are shown and empty categories are hidden And all counts and labels match the API response for that cluster snapshot
Exemplar Claims Panel
Given a user has opened the Cluster Details Drawer for a cluster When the Exemplar Claims section loads Then it lists up to 5 exemplar claims returned by the API ordered by exemplarScore descending And each item shows claimId, lossDate, jurisdiction, and badges for shared attributes that drove clustering And clicking an exemplar claim opens the claim detail in a new tab with the clusterId in the context/query And a "View all claims" control opens the claims list filtered to the cluster And if the cluster contains fewer than 5 claims, all available claims are shown And the section displays within 2000 ms, showing a loading skeleton until data is ready
Mini-Network Graph and Explainability Signals
Given a user has opened the Cluster Details Drawer When the visualization area renders Then a mini-network graph renders within 1500 ms showing nodes for claims and shared entities with edges for relationships And users can pan and zoom via mouse, touch, and keyboard without keyboard traps And hovering or focusing a node shows a tooltip with entity type/name and degree And clicking a node highlights its immediate neighbors and dims others And an Explainability section lists all rules and similarity signals with their weights as percentages that sum to 100% ±1% And selecting a signal filters/highlights corresponding nodes/edges in the graph and updates the legend And all signal names, descriptions, and weights match the API response for the cluster snapshot
Pivot Actions Between Shared Attributes
Given the Cluster Details Drawer shows shared attributes for a selected cluster When the user clicks a Pivot control on a specific attribute value (e.g., a phone number or repairer) Then the explorer context pivots to that attribute type and loads clusters centered on the selected value And the details drawer updates to the new focal cluster for that value And a Back to previous context control restores the prior clusters view and selection And the pivot completes within 2000 ms and preserves the current time window and any applied filters And the pivot action is recorded to analytics/audit with userId, previousContext, newContext, and timestamp
Save Cluster to Watchlist
Given a user is viewing a selected cluster in the details drawer When the user clicks "Save to Watchlist" Then a modal prompts for a required Watchlist name and optional description/tags And attempting to save a duplicate name within the same scope prompts the user to overwrite or rename And on Save, the system creates/updates the watchlist entry via API and shows a success toast and a Watchlisted badge in the drawer And the saved watchlist entry is retrievable on the Watchlists page with matching clusterId and attributes And API failures display actionable error messages without losing user input And a successful save completes within 2000 ms
Export Evidence (CSV/PDF) with Audit Metadata
Given a user is viewing a selected cluster When the user chooses Export and selects CSV or PDF Then the file is generated and download starts within 5000 ms for clusters up to 5000 claims And both formats include audit metadata: clusterId, generatedAt (UTC ISO 8601), userId, orgId, dataVersion/hash, and applied filters/time window And both formats include: claims table (claimId, lossDate, jurisdiction, sharedAttributes, exemplarFlag), involved entities, and explainability signals with weights; PDF additionally includes a mini-network snapshot And filenames follow the pattern: cluster-{clusterId}-{yyyyMMdd-HHmmssZ}.{csv|pdf} And an export event with checksum and file size is written to the audit log
Responsive Layout and Accessibility Compliance
Given a user opens the Cluster Details Drawer on devices of varying sizes and with assistive technologies When viewed at widths 320, 768, 1024, and 1440 px Then content reflows without horizontal scrolling; on ≤768 px the drawer presents as a full-screen sheet with collapsible sections And all interactive controls are reachable via keyboard (Tab/Shift+Tab), operable via Enter/Space, and have visible focus indicators And ARIA roles/labels provide accessible names for sections, the graph, and controls; the graph has a textual summary for screen readers And color contrast meets WCAG 2.1 AA (≥4.5:1 for text); there are no keyboard traps and focus order is logical And automated accessibility checks (e.g., axe/pa11y) report no critical or severe violations
Behavioral Similarity Modeling
"As a data analyst, I want behavior-based linking in addition to shared identifiers so that I can uncover coordinated schemes that avoid reusing the same entities."
Description

Implement a similarity engine that augments shared-entity links with behavioral signals extracted by ClaimFlow’s NLP and vision pipelines (message phrasing, document templates, photo EXIF/device hints, submission timing patterns). Generate vector embeddings and rule-based features, compute weighted edges between claims, and run clustering (e.g., community detection) with tunable thresholds. Provide model monitoring, backtesting on labeled SIU cases, and human-readable rationales for each linkage to support defensibility.

Acceptance Criteria
Similarity Edge Computation with Behavioral Signals
Given two claims with available behavioral signals (phrasing embeddings, document templates, EXIF/device hints, submission timing), When the similarity engine processes the candidate pair, Then it produces a normalized edge score in [0,1] combining embedding-based and rule-based features per the configured weights. Given a candidate pair is missing one or more behavioral signals, When scored, Then the engine substitutes neutral defaults for missing features, records which features were absent, and completes without error. Given identical inputs and a fixed random seed, When scoring is re-run, Then the edge score is identical to the previous run. Given 1,000,000 candidate pairs in a batch job, When processed on the standard scoring cluster, Then the p95 per-pair scoring time is <= 10 ms and the job completes within 3 hours, with job metrics logged. Given feature contributions are computed, When requested via API, Then the engine returns each feature’s raw value, normalized value, and weighted contribution for the pair.
Configurable Feature Weights and Thresholds
Given an authorized admin updates feature weights and similarity/cluster thresholds, When the configuration is saved, Then the change is validated, versioned with user and timestamp, and takes effect on the next run without code deployment. Given a scoring or clustering run executes, When outputs are written, Then the effective config version ID is attached to all edges and clusters and is queryable. Given invalid configuration values (e.g., negative weight, threshold outside [0,1]), When save is attempted, Then the system blocks the change and returns field-level error messages. Given thresholds are changed, When the next clustering run completes, Then a change report shows deltas in cluster counts, sizes, and membership versus the prior version. Given a request to compare two config versions on a sample dataset, When the A/B run is executed, Then both outputs and their summary metrics are produced in a single report.
Community Detection and Cluster Formation
Given a weighted graph of claims and similarity edges, When community detection (Leiden or Louvain) is run, Then clusters are produced such that all intra-cluster edges meet or exceed the configured minimum edge score and cluster IDs are stable within a run. Given a benchmark graph with known communities, When clustering is evaluated, Then normalized mutual information (NMI) is >= 0.85. Given a maximum cluster size policy is configured (e.g., 500), When a community exceeds the limit, Then it is split or flagged according to policy and surfaced in the run report. Given a graph with 100k nodes and 2M edges, When clustering runs on the standard hardware profile, Then it completes in <= 10 minutes and uses <= 16 GB RAM, with resource usage logged. Given incremental updates are enabled, When a new claim arrives, Then it is assigned to an existing cluster or flagged for review within 30 seconds.
Human-Readable Linkage Rationales
Given an investigator opens an edge between two claims, When the rationale is requested, Then the UI/API returns the top 3 contributing features with their weights, normalized scores, and human-readable evidence (e.g., text snippet, template hash, EXIF fields) plus links to source artifacts. Given a user exports a cluster detail report, When the export completes, Then each edge rationale and each claim’s cluster membership rationale is included in plain language without internal jargon. Given PII redaction policies, When rationales are displayed or exported, Then only permitted fields are shown or redacted per policy, and access is audit-logged with user, time, and purpose. Given an audit API request with an edge ID, When executed, Then the response includes config version, feature contributions, and data lineage identifiers within 200 ms at p95.
Backtesting Against Labeled SIU Cases
Given a labeled dataset of positive (linked ring) and negative pairs, When cross-validated scoring and clustering are run, Then pairwise ROC-AUC is >= 0.90 and ring-level F1 is >= 0.80 on the holdout set. Given an operating threshold is selected, When applied to the holdout set, Then precision@100 ranked edges is >= 0.75 and false positive rate is <= 10%. Given a model or configuration change, When backtests complete, Then results are persisted with dataset version, config version, and timestamps; deviations exceeding ±3% from the last accepted run require explicit approval to promote. Given reproducibility requirements, When a backtest is re-run with the same seeds and dataset version, Then all reported metrics match within ±0.5%.
Model Monitoring and Drift Alerting
Given daily production scoring, When monitoring runs, Then population stability (PSI) or KL divergence is computed for the top 20 features and embedding norms, and results are posted to dashboards. Given a drift threshold (e.g., PSI > 0.25) is exceeded for two consecutive runs, When detected, Then an alert is sent to the SIU analytics channel and an incident ticket is opened with impacted features and sample records. Given post-deployment outcomes from SIU investigations, When ingested weekly, Then online precision and recall are recomputed with confidence intervals and trendlines are updated. Given monitoring job SLAs, When evaluated over 30 days, Then p95 runtime is <= 15 minutes and job success rate is >= 99%.
Performance and Scalability Targets
Given a daily intake of 25,000 new claims and up to 50 candidate pairs per claim, When batch scoring runs on the standard compute profile, Then it completes within 2 hours with run metrics logged. Given a user opens a claim in Cluster Explorer, When on-demand scoring is triggered for that claim’s new data, Then updated edges and cluster assignment are available in the UI within 1 second at p95. Given 50 concurrent SIU users viewing cluster details and rationales, When load-tested, Then median response time is <= 1 second and p95 <= 2 seconds with error rate <= 1%. Given 6 months of edges and rationales for 10M claims, When stored, Then total storage consumed is <= 3 TB and p95 retrieval latency for edge lookups by claim ID is <= 500 ms.
SIU Case Routing & Export
"As an SIU supervisor, I want to route suspicious clusters directly into our investigation workflow so that my team can act immediately with all supporting evidence attached."
Description

Integrate Cluster Explorer with ClaimFlow’s workflow engine to allow users to convert a cluster into an SIU case, auto-assign to queues based on rules, and attach evidence packets. Include status sync back to clusters (e.g., under investigation, closed) and one-click exports (CSV/PDF/JSON) and APIs for downstream SIU tools. Maintain full audit trails of actions taken on clusters and enforce role-based access controls for cluster visibility and exports.

Acceptance Criteria
Convert Cluster to SIU Case from Cluster Explorer
Given a user with role SIU Analyst or Claims Manager has CanCreateSIUCase permission and is viewing a cluster they can access, When they click Create SIU Case, Then a new SIU case is created within 2 seconds with a unique Case ID, linked Cluster ID, all related Claim IDs, shared attributes summary, risk score, creator, and timestamp, and the user is navigated to the new case. Given an SIU case already exists for the same Cluster ID, When a user attempts to create another case from that cluster, Then the system blocks duplication and presents a link to the existing case. Given required case metadata (title, priority, queue assignment placeholder) is missing, When the user submits, Then validation prevents creation and displays inline errors identifying missing fields. Given the case is created, When viewed in the workflow engine, Then it appears with status New and initial activity log entry "Case created from Cluster Explorer".
Auto-Assignment to SIU Queues via Routing Rules
Given routing rules are configured with priorities and conditions, When an SIU case is created from a cluster, Then the rules engine assigns the case to the highest-priority matching queue within 1 second and records the matched rule ID and reason. Given no rules match, When the case is created, Then it is assigned to the Default SIU queue. Given case attributes change to satisfy a higher-priority rule, When the rules engine reevaluates, Then the case is automatically re-routed and the reassignment is logged. Given multiple rules match with equal priority, When assignment occurs, Then deterministic tie-breaker by rule order is applied.
Evidence Packet Assembly and Attachment
Given a user with CanGenerateEvidence permission views a cluster or its SIU case, When they click Generate Evidence Packet, Then a PDF summary and a ZIP archive are generated within 10 seconds containing cluster footprint, shared entities (phone, VIN, address, IP, repairer), related claim summaries, timeline growth chart, tagged loss details, and source references. Given evidence packet generation completes, When the SIU case is opened, Then the packet is attached as version 1 with checksum, size, creator, and timestamp metadata. Given the cluster changes after initial packet, When Generate Evidence Packet is run again, Then a new version is attached and previous versions remain accessible and immutable. Given the user lacks permission to view PII fields, When a packet is generated, Then protected fields are redacted consistently in both PDF and ZIP.
Status Sync Between SIU Case and Cluster
Given an SIU case linked to a cluster, When the case status is updated to Under Investigation, Then the corresponding cluster displays a status badge Under Investigation within 5 seconds. Given the case is updated to Closed—Confirmed Fraud or Closed—No Action, When the update is saved, Then the cluster status badge reflects the mapped status and the closed timestamp is shown on the cluster. Given the cluster has multiple linked cases, When any linked case is Under Investigation, Then the cluster shows Under Investigation; When all linked cases are closed, Then the cluster shows the most severe closed state based on configured precedence. Given a status sync occurs, When viewing the audit log, Then an entry shows the source system, old value, new value, actor, and timestamp.
One-Click Export of Cluster and Case Data (CSV/PDF/JSON)
Given a user with CanExport permission views a cluster or its SIU case, When they click Export CSV, Then a CSV downloads within 5 seconds containing one row per related claim and columns for cluster ID, claim ID, policy ID, shared entities, risk score, and status with ISO-8601 timestamps. Given the same context, When they click Export PDF, Then a PDF summary downloads within 5 seconds matching the on-screen summary content. Given the same context, When they click Export JSON, Then a JSON file downloads within 5 seconds conforming to the documented schema version and including evidence packet references. Given the user lacks CanExport, When they attempt any export, Then the UI disables export actions and API returns 403.
SIU Integration API for Downstream Tools
Given an external SIU tool with valid OAuth2 client credentials, When it requests GET /api/siu/cases/{id}, Then the API returns 200 with the case JSON including linked cluster ID, queue, status, and evidence links. Given the tool subscribes a webhook URL, When an SIU case status changes, Then a webhook POST is delivered within 10 seconds with signed payload and retry with exponential backoff on failures up to 24 hours. Given pagination parameters, When requesting GET /api/siu/cases?updated_since=..., Then results are paginated with next/prev cursors and stable ordering. Given a request exceeds rate limits, When 100 requests/minute per client is exceeded, Then the API returns 429 with Retry-After header.
Audit Trail and Role-Based Access Control Enforcement
Given any action on a cluster or linked SIU case (create case, assignment, status change, export, evidence generation), When the action occurs, Then an immutable audit record is written with actor, role, action, entity IDs, before/after values, channel (UI/API), and timestamp and is retrievable via UI and API. Given a user without permission attempts restricted actions (view hidden cluster, export, create case), When they try, Then the UI hides or disables controls and the API returns 403 while logging the denied attempt. Given an auditor role with CanViewAudit permission, When they filter audit logs by entity or actor and export, Then results return within 5 seconds and the export matches the on-screen records.

Signal Lens

Clear, human-readable explanations of why a claim scored as anomalous. Surfaces top contributing signals with weights, examples, and data lineage, plus one-tap controls to mute noisy indicators or tweak thresholds. Builds trust in the model, cuts false positives, and speeds SIU screening without black-box guesswork.

Requirements

Top Signal Explanations
"As a claims manager, I want to see the top factors that made a claim anomalous, with plain-language explanations and evidence, so that I can quickly decide whether to escalate or clear it."
Description

Display the top contributing signals behind an anomaly score with weights, directionality (risk up/down), confidence, and concise plain-language explanations tied to evidence snippets (e.g., extracted text, photo regions, form fields). Support model-agnostic contribution methods (e.g., SHAP/feature importance) with configurable top-N. Embed within the ClaimFlow claim detail view and triage queue. Provide quick links from each signal to its originating data and to remediation actions (mute, threshold tweak). Cache per-claim explanation snapshots to ensure consistency across sessions and exports, and fall back gracefully if model metadata is missing. Optimize for sub-300ms render from precomputed contributions to keep intake flows fast.

Acceptance Criteria
Top Signals Content, Directionality, Confidence, and Top-N
Given a claim with precomputed contribution data and a configured topN value k When the explanations module loads in the claim view Then exactly k signals are displayed sorted by absolute contribution descending And each signal shows: signal name, weight (numeric with two decimal places), directionality label as either "risk up" or "risk down", confidence as a percentage (0–100% with one decimal place max), and a plain-language explanation not exceeding 200 characters And the contribution method shown in a tooltip reflects the provider in metadata (e.g., "SHAP", "FeatureImportance"), and formatting is identical regardless of provider
Embedding in Claim Detail and Triage Queue
Given a claim appears both in the triage queue and in the claim detail view When the explanations module renders in each context Then the same set of top signals, in the same order, with identical values and explanations, is shown in both contexts And navigating from a triage item to the claim detail view preserves the selected signal focus
Evidence Snippets and Data Lineage Links
Given a top signal references evidence (text, photo region, or form field) When the user selects "View source" for that signal Then for text evidence, a snippet up to 160 characters is displayed with the matched fragment highlighted and a link to the original document/message identifier And for photo evidence, the referenced image opens with the bounding box region highlighted and zoom applied to center the region And for form evidence, the field label and value are shown with a link to the form and field identifiers And a lineage tooltip/link includes source system, record ID, and field/region identifiers for verification
Remediation Quick Actions (Mute and Threshold Tweak)
Given a top signal is visible to a user with configuration permissions When the user taps "Mute" Then a confirmation appears with the signal identifier and model context pre-populated, and upon confirm the signal is muted for this claim and an audit log entry is recorded Given a top signal supports threshold configuration When the user taps "Tweak threshold" Then a control opens with the current threshold pre-populated; upon save, the update is persisted and a success confirmation is shown And users without permissions do not see remediation controls
Snapshot Caching and Export Consistency
Given an explanation snapshot exists for a claim and model version V at timestamp T When any authorized user opens the claim in any session Then the same snapshot (same signals, order, weights, confidence, explanations) is rendered consistently until a refresh is explicitly requested or the model version changes And exporting the claim (PDF/CSV) includes exactly the snapshot content with timestamp T and model version V And when a refresh is requested and a new snapshot is created, the UI clearly indicates the new timestamp and version
Graceful Fallback Without Model Metadata
Given model metadata or contribution data is missing, stale, or malformed When the explanations module attempts to render Then a non-blocking message states that explanations are unavailable for this claim, the rest of the claim UI remains fully functional, and remediation/evidence actions are hidden And an error event with claim ID and model context is logged to telemetry for investigation
Performance: Sub-300ms Render from Precomputed Contributions
Given precomputed contribution snapshots are available for a claim When the explanations module mounts Then the time from receiving the snapshot payload to first content render is <= 300 ms at P95 across a representative sample in the target environment And no additional blocking network calls are made during render beyond fetching the cached snapshot And opening an evidence preview from a signal occurs in <= 150 ms at P95
Data Lineage Traceback
"As an SIU analyst, I want to trace each signal back to its original data source and transformation steps so that I can verify accuracy and defend decisions during audits."
Description

Enable drill-down from any signal to its full data lineage: source artifact (photo, message, document, form), timestamps, extractor versions (NLP/OCR), feature engineering steps, normalization, and any imputations. Present a clickable chain with preview of the raw snippet or annotated image region and show transformation metadata. Record lineage as part of model scoring so explanations remain reproducible over time. Integrate with ClaimFlow’s storage and event bus to fetch artifacts on-demand with access controls. Provide clear error states when upstream artifacts are unavailable and maintain a tamper-evident record of lineage for audit.

Acceptance Criteria
Clickable Lineage Chain Navigation
- Given a user views a signal's explanation in Signal Lens, When they click the Lineage icon, Then an ordered chain from source artifact to final feature renders with step labels. - Given the chain is displayed, When a user selects any step, Then the details panel shows step type (extraction, feature engineering, normalization, imputation), parameters, timestamp, upstream and downstream references. - Given the chain contains more than 10 steps, When rendered, Then the UI supports vertical scrolling, maintains step indexing, and initial render completes within 2 seconds for 95th percentile traces up to 100 steps. - Given a step contains an external reference ID, When displayed, Then the ID is a deep link that opens the referenced artifact or log entry in a new tab.
Artifact Preview and Annotations
- Given a lineage step points to a photo, When opened, Then an image preview renders with bounding boxes and labels for extracted regions and a legend mapping labels to features. - Given a lineage step points to a text artifact (message, document, or form), When opened, Then the preview highlights exact character offsets of the extracted snippet and shows 100 characters of surrounding context on both sides when available. - Given an artifact preview fails to load, When the error is detected, Then a metadata-only view is shown with retry control and a copyable artifact ID. - Given an artifact size is 10 MB or less, When preview is requested under normal network conditions, Then the preview loads within 2 seconds for 95th percentile requests.
Versioned Extractors and Transformations
- Given a signal has been scored, When lineage is displayed, Then extractor versions (NLP/OCR), feature engineering library versions, transformation parameters, and normalization schemas used at scoring time are visible and immutable. - Given the platform is upgraded after scoring, When the same claim is reopened, Then lineage continues to show the original versions used at scoring time. - Given a step is missing a version tag, When lineage is queried, Then the UI flags the step as incomplete and an audit event lineage_version_gap with the step ID is emitted.
On-Demand Fetch with Access Control
- Given an adjuster with permission to the claim opens lineage, When artifacts are requested, Then they are fetched via storage and event bus using signed URLs within the current user's permissions. - Given a user lacks permission to a source artifact, When they request its preview, Then access is denied with a clear explanation and a Request Access action that emits an access_request event. - Given network latency up to 300 ms at the 95th percentile, When fetching artifacts of 10 MB or less, Then retrieval completes within 1.5 seconds at the 95th percentile or a non-blocking loader is displayed until completion. - Given an artifact has been previewed within the last 10 minutes, When it is reopened, Then it loads from cache without a round-trip to storage and displays a cached indicator.
Reproducible Scoring Snapshot
- Given a signal explanation is saved at scoring time, When lineage is opened later, Then feature values, imputations, normalization parameters, and weights match the original scoring snapshot exactly. - Given a user clicks Recompute, When the system recomputes using current pipelines, Then the UI distinguishes Original (timestamp) versus Recomputed (timestamp) and shows value diffs per step. - Given the recomputed signal weight differs from the original by more than 0.1, When results are shown, Then a warning badge is displayed with any detected cause (version drift, missing artifact, parameter change).
Tamper-Evident Audit Trail and Error States
- Given lineage records are written, When integrity metadata is persisted, Then each record includes a SHA-256 hash, previous-hash pointer, and nonce, and the aggregate hash is stored in the audit log. - Given any lineage record is modified after write, When daily verification runs, Then the integrity check fails, an audit event lineage_tamper_detected with affected claim IDs is emitted, and the UI shows a banner on impacted claims. - Given an upstream artifact is unavailable (deleted, permission revoked, offline), When lineage is opened, Then the UI displays the unavailability reason, last known metadata (artifact ID, timestamp, size), and a Retry control, and an alert is logged with correlation ID. - Given fetching from the event bus fails, When three retries with exponential backoff are exhausted, Then a failure state is shown with correlation ID and support contact link.
One-Tap Signal Mute & Scope Controls
"As a claims supervisor, I want to mute noisy indicators for my team or a specific claim so that we reduce false positives without changing the global model."
Description

Provide UI controls to mute or downgrade specific indicators from the explanation panel with immediate, scoped effects: this claim only, user session, user profile, team, or workflow template. Allow duration settings (e.g., 1 day, 2 weeks, until revoked) and automatic reactivation reminders. When applied, trigger on-the-fly rescoring and update routing while logging an auditable event with actor, scope, reason, and rollback link. Respect role permissions and display the effective configuration stack. Persist muted signal configurations as versioned policy objects with conflict resolution and change history.

Acceptance Criteria
One-tap mute on a single claim triggers immediate rescoring and routing update
Given a user with Manage Signals permission at claim scope is viewing a claim’s explanation panel showing indicator I with weight W When the user taps Mute on indicator I, selects scope This claim only, provides a reason, and confirms Then the system recalculates the claim’s anomaly score excluding indicator I within 3 seconds And any workflow routing dependent on the score is recalculated and applied within 5 seconds And the explanation panel marks indicator I as Muted (claim) and excludes it from contributing signals And an audit event is recorded with actor, claim ID, indicator ID, scope=claim, reason, timestamp, and rollback link And the effective configuration stack displays a top entry Claim override: indicator I muted
Session-scoped mute auto-expires at session end with reactivation
Given a user selects scope User session for indicator I from the explanation panel When the user applies the mute during an active authenticated session Then the mute takes effect across all claims viewed by that user within 3 seconds And on logout or a 30-minute inactivity timeout the mute automatically deactivates And on next login the indicator is unmuted unless re-applied And audit events are recorded for activation and auto-reactivation with deactivation reason Session ended
Role-based scope permissions and UI option availability enforcement
Given organizational roles define permissions for Claim, Session, Profile, Team, and Workflow Template scopes When a user without Team policy: write permission opens the scope selector Then Team and Workflow template scopes are disabled with a tooltip describing required permission And submitting a change to a disallowed scope returns HTTP 403 and an inline error message And users with appropriate permissions can apply those scopes successfully And all scope permission checks are enforced server-side and logged
Time-bound mutes with reminders and automatic reactivation
Given a user sets a mute with scope S and duration D (e.g., 1 hour, 1 day, 2 weeks, custom) for indicator I When the mute is created Then the system schedules automatic reactivation at D and shows a countdown timer in the configuration panel And an in-app reminder is sent 15 minutes before expiry and an email is sent if notifications are enabled And at expiry the indicator is unmuted, the score is recalculated within 5 seconds, and routing updates are applied And the audit log records creation and auto-reactivation with duration and notification delivery status
Versioned policy persistence with precedence and effective stack display
Given multiple policies exist for indicator I across scopes Claim, Session, Profile, Team, and Workflow Template When conflicting settings are active Then precedence is applied in order Claim > Session > Profile > Team > Workflow Template And the effective configuration stack lists each contributing policy with scope, version, author, timestamp, and decision outcome And saving a change creates a new immutable policy version with a diff of changed fields And concurrent edits are detected; a later save must resolve conflicts before commit And policies are persisted and retrievable via API with version/ETag headers
Downgrade weight and threshold tweaks with instant impact and validation
Given indicator I supports Downgrade and Threshold adjustments with displayed allowed ranges When a user reduces weight by a specified percentage or adjusts a threshold value within allowed bounds Then input validation prevents out-of-range values and prevents total mute unless Mute is explicitly chosen And upon confirmation rescoring completes within 3 seconds and the explanation shows updated weight/threshold with scope badge And changes can be reverted via rollback link to the prior version And an audit event records before/after values, scope, actor, timestamp, and reason
Auditable events and one-click rollback for scope changes
Given any mute, downgrade, or threshold change has been applied When a user with rollback permission clicks the rollback link from the audit log or panel Then the system reverts to the referenced policy version within 3 seconds and triggers rescoring and routing updates within 5 seconds And a new audit record is created referencing the rolled-back event ID with actor and reason And rollback is blocked with a clear error if the user lacks permission or a higher-precedence override supersedes the target version
Threshold Tuning with Impact Preview
"As a product owner, I want to tune anomaly thresholds and preview the historical impact so that we balance fraud catch-rate with investigation workload."
Description

Offer interactive threshold controls per workflow segment (LOB, geography, severity) with sandbox-to-production promotion. Provide instant previews using backtests on recent claims to estimate changes to precision, recall, false-positive rate, and SIU referral volume, plus capacity impact. Require dual-approval and change notes for production changes, with automatic versioning and rollback. Expose a policy API for CI/CD and feature-flag integration. Ensure recalculation is idempotent and queued to avoid routing thrash, and emit events for downstream analytics.

Acceptance Criteria
Per-Segment Threshold Controls and Sandbox Promotion
- Given a user with role "Fraud Analyst" or higher, When they open Threshold Tuner for a workflow, Then they can view and edit anomaly thresholds independently per segment key: LOB, geography, and severity. - Given a segment selection, When a threshold value outside [0.00, 1.00] is entered, Then the control blocks save and displays a validation error specifying the valid range. - Given edits are made, When the user clicks Save, Then changes persist to a Sandbox configuration version without altering production scoring. - Given a Sandbox version exists, When the user compares with production, Then the UI shows per-segment diffs (old vs new values) and highlights changed segments.
Instant Impact Preview via Backtest on Recent Claims
- Given a saved Sandbox threshold set, When the user clicks "Preview Impact", Then the system runs a backtest over the last 90 calendar days of claims for the selected workflow segments (or all available if fewer than 90 days) and completes in ≤ 5 seconds for datasets up to 100,000 claims. - Then the preview returns the following metrics vs current production: precision, recall, false-positive rate, SIU referral volume, and net change in SIU capacity hours (based on configured per-referral handling time). - Then the preview displays the claim count used, time window, and data snapshot timestamp. - Then no production routes or scores are modified by running a preview.
Dual-Approval, Change Notes, and Production Promotion Guardrails
- Given a Sandbox configuration, When a user submits for production, Then they must enter a change note of at least 10 characters and select a target environment. - Then promotion requires two distinct approvers; the requester cannot approve their own change; only users with "Admin" or "Compliance" roles can approve. - Then the system blocks promotion until both approvals are recorded and stores approver IDs, timestamps, and the change note in an immutable audit log. - When an approval is rejected, Then the requester is notified and the promotion state returns to "Draft".
Automatic Versioning and One-Click Rollback
- Given a successful promotion, Then the system creates an immutable version identifier with author, change note, and diff metadata. - When a user invokes "Rollback" on the current production version, Then the previous version is reinstated within 2 minutes and a new version entry recording the rollback action is created. - Then all downstream scoring services read the reinstated version atomically, without serving mixed versions during rollout. - Then the audit log contains before/after version IDs, initiator, timestamp, and reason.
Idempotent Recalculation with Queueing to Prevent Routing Thrash
- Given a production version change, When recalculation is triggered, Then each affected claim is enqueued once using an idempotency key (claimId + versionId), and duplicate enqueue attempts are deduplicated. - Then each claim is re-scored at most once per version, and route updates are coalesced to a single update event per claim. - Then claims currently locked in SIU review are not auto-removed from that queue by recalculation; updates apply only to new routing decisions. - Then processing retries are safe (no duplicate side effects), and queue depth and lag metrics are emitted.
Policy API for CI/CD and Feature-Flag Integration
- Given an authenticated client, When calling the Policy API, Then endpoints exist to: validate policy, create/update Sandbox thresholds, submit for approval, approve/reject, promote, list versions, and rollback. - Then all write operations are atomic and return version IDs; GET endpoints are strongly consistent for the latest committed version. - Then the API exposes environment scoping (dev, staging, prod) and supports dry-run promotion for CI pipelines. - Then an OpenAPI 3.0 specification is published and includes field-level schema for segments and thresholds.
Event Emission for Downstream Analytics
- Given a preview run, promotion, rollback, or recalculation completion, Then the system emits an event to the configured event bus with fields: eventType, correlationId, actorId (if applicable), environment, versionId, segment keys, old/new thresholds (when applicable), backtest window, claimCount, and timestamp (ISO-8601). - Then events are delivered at-least-once and are key-partitioned to preserve order per versionId or claimId respectively. - Then event schemas are registered and versioned; incompatible changes are not introduced without a new schema version. - Then events become available to subscribers within 10 seconds (p95) of the triggering action.
Explanation Export & Audit Trail
"As a compliance officer, I want explanation snapshots and changes to be exportable and immutable so that we satisfy audit and regulatory requirements."
Description

Capture an immutable snapshot of each claim’s explanation (signals, weights, lineage references, user overrides) at decision time and enable export to claim file as PDF and JSON via UI and API. Store snapshots in write-once, hash-verifiable storage with timestamps and signer identity, and associate them to claim events. Include a chronological audit log of configuration changes (mutes, threshold edits) and their approvers. Support bulk export for audits and SIU case packages with configurable redaction. Ensure exports render consistently across environments and are accessible based on RBAC.

Acceptance Criteria
Immutable Snapshot at Decision Time
Given a claim receives an anomaly decision When the decision is finalized Then an explanation snapshot is created exactly once per decision and linked to the claim event ID And the snapshot JSON conforms to schema "explanationSnapshot.v1" including: signals[], weights, lineageRefs[], userOverrides[], decisionTimestamp (UTC ISO 8601), signerIdentity, and contentHash (SHA-256) And the snapshot is stored with a WORM flag and a unique immutable snapshotId And retrieving by claimId + eventId returns the same snapshotId
Hash-Verifiable Write-Once Storage
Given a stored snapshot When its SHA-256 hash is recomputed Then it matches contentHash and the stored hash in metadata When any attempt is made to modify or delete the snapshot payload Then the system rejects the operation with 409 Conflict and logs an immutable audit entry And only retention-policy governed purge is allowed; purge leaves a tombstone with snapshotId, purgeReason, purgedBy, and timestamp And snapshot metadata includes createdAt (UTC) and signerIdentity, and the digital signature verifies against the configured public key
Single Snapshot Export via UI and API
Given a user with permission "explanation.export" When they export from the claim view selecting PDF or JSON Then a file downloads with name pattern claim-<claimId>-snapshot-<snapshotId>.<ext> And the JSON export equals the stored snapshot JSON (byte-for-byte) And the PDF export renders all required fields and passes accessibility tags (PDF/UA basic tags present) And 95th percentile latency for single snapshot export is <= 2s for JSON and <= 4s for PDF When a user without permission attempts export Then the UI hides export controls and API returns 403 with error code RBAC_DENIED When an invalid snapshotId is requested Then API returns 404 NOT_FOUND
Bulk Export with Configurable Redaction
Given an authorized auditor or SIU user submits a bulk export job with criteria (date range or list of claimIds) and a named redaction profile When the job is accepted Then status transitions Pending -> Running -> Succeeded/Failed and is queryable via UI and API And the result is a ZIP containing per-snapshot PDF and JSON files with redactions applied per profile; redactions are irreversible in outputs And PII fields specified by the profile (e.g., SSN, phone, email, policy number) are fully masked in both PDF and JSON exports And for a job of 1,000 snapshots and a 1 GB total uncompressed size cap, 95th percentile completion time is <= 15 minutes And a manifest.json includes jobId, parameters, counts, and per-file SHA-256 checksums When an unauthorized user submits a bulk export Then the request is rejected with 403 and no job is created
Audit Log of Configuration Changes and Approvals
Given a user mutes a signal or edits a threshold When the change is submitted Then an audit event is created capturing changeType, scope, beforeValue, afterValue, reason, requesterId, requesterTimestamp When an approver approves or rejects Then the audit event is updated with approverId, decision, approverTimestamp, and effectiveFrom And the change does not take effect until approved; once effective, subsequent explanation snapshots include the override under userOverrides with the auditEventId reference And the audit log is immutable, paginated, and filterable by claimId, changeType, userId, and date range, and exportable as CSV and JSON
Data Lineage Completeness in Snapshots and Exports
Given a snapshot contains top contributing signals Then each signal includes lineageRefs with sourceArtifactId(s), artifactType (photo, message, document), extractionModelVersion, and transformationStepIds And exports (PDF and JSON) render lineage in human-readable form and preserve IDs for trace-back And lineageRefs resolve to existing artifacts via API, returning 200; missing references are flagged with lineageStatus: "broken" And the snapshot fails validation if any top contributing signal is missing a lineageRef
Cross-Environment Export Consistency
Given the same snapshot exists in staging and production with identical templateVersion When exported as PDF and JSON Then the JSON SHA-256 hashes are identical across environments And the PDF visual content is identical and the binary SHA-256 hash is identical (or the normalized hash after stripping non-content metadata matches) And numeric, date, and locale formatting are consistent across environments And templateVersion and rendererVersion are recorded in the export metadata
Role-Based Visibility & Redaction
"As an administrator, I want to control who can see specific signals and sensitive details in explanations so that we protect customer privacy and comply with regulations."
Description

Enforce role- and tenant-based access to signals and underlying data, masking PII and sensitive attributes in explanations by default with click-to-reveal for authorized roles. Provide configurable redaction rules (e.g., policy number, SSN, GPS) and per-tenant overrides. Ensure lineage previews respect the same policies, including blurred image regions and truncated text. Log all sensitive data reveals. Integrate with ClaimFlow’s existing RBAC and SSO, and provide an admin console to test visibility scenarios and audit effective permissions.

Acceptance Criteria
Default PII Masking & Authorized Reveal
1) Given a user without the PII.View permission, when viewing Signal Lens explanations, then all configured PII/sensitive fields (e.g., policy number, SSN, GPS coordinates, phone, email) are masked with standardized placeholders and no reveal control is shown. 2) Given a user with the PII.View permission, when clicking Reveal on a masked field, then the true value is displayed for the current session and the field re-masks on page reload or after 15 minutes of inactivity. 3) Given a user with the PII.View permission, when attempting to reveal a field from a different tenant, then access is denied and the value remains masked. 4) Given any user, when exporting or printing the explanation, then masked fields remain masked unless the user has Export.Unredacted permission and explicitly selects an Unredacted export option.
Configurable Redaction Rules & Per-Tenant Overrides
1) Given global redaction rules for policy number patterns, SSN formats, and GPS coordinates, when explanations and messages render, then all matches are masked in both structured fields and free text. 2) Given a tenant-level override that unmasks policy number for role Adjuster, when an Adjuster of that tenant views explanations, then policy number is unmasked while SSN and GPS remain masked. 3) Given conflicting rules between global and tenant levels, when evaluating redaction, then tenant rules take precedence for that tenant only and do not affect other tenants. 4) Given an admin updates a tenant override in the admin console, when saving the change, then the new rule takes effect within 60 seconds and the change is audit logged with before/after details.
Lineage Preview Redaction Parity (Images & Text)
1) Given lineage previews include images containing PII (e.g., faces, license plates), when viewed by a user without PII.View, then those regions are blurred and no unblur control is available. 2) Given lineage previews include long text with PII tokens, when rendered, then masked segments are truncated per configuration (e.g., first/last 2 characters) with a placeholder. 3) Given a user with PII.View clicks Reveal in lineage, when the specific region or token is revealed, then the action is logged with claim ID, artifact ID, field path, and bounding box coordinates (if applicable). 4) Given the same content is requested via API, when returned, then the response enforces identical redaction behavior (masked by default; reveal requires authorized scope) as the UI.
Sensitive Reveal Audit Logging
1) Given any reveal action on a masked value, when performed, then an immutable audit record is written including timestamp (UTC), tenant ID, user ID, roles, IdP session ID, claim ID, field path, previous masked state, client IP, and user agent. 2) Given audit logs, when queried in the admin console by tenant admins, then results can be filtered by date range, user ID, claim ID, field path, and outcome, returning within 2 seconds for up to 50,000 records. 3) Given an unauthorized reveal attempt, when denied, then a denial event is logged with reason Unauthorized and without exposing the sensitive value. 4) Given a configured retention policy, when log records exceed the retention window, then older records are purged automatically and the purge is itself logged.
RBAC & SSO Enforcement
1) Given a successful SSO login, when RBAC roles are resolved, then only users with PII.View may reveal masked values; all others see masked content with no reveal controls. 2) Given the RBAC service is unavailable, when a user accesses explanations, then the system fails closed by masking all sensitive data and hiding reveal controls. 3) Given a user belongs to multiple tenants, when switching tenants, then effective permissions and redaction rules update immediately and cross-tenant data remains inaccessible. 4) Given session termination (logout or IdP revocation), when the user returns to the page, then previously revealed fields are re-masked and require re-authorization.
Admin Console — Visibility Testing & Effective Permissions Audit
1) Given an admin opens Visibility Test, when selecting a tenant, user or role, and a sample claim, then the console shows a preview of mask/reveal outcomes with the redaction rule IDs responsible for each masking decision. 2) Given the Effective Permissions view, when a user is selected, then the console displays computed permissions (e.g., PII.View, Export.Unredacted) and applicable redaction overrides, highlighting any conflicts. 3) Given an admin runs a visibility test, when exporting results, then a report (CSV and JSON) is generated listing each field, its mask/reveal state, and the governing rule or permission. 4) Given redaction rules are modified, when the admin clicks Validate, then batch checks run against a selected claim set and return pass/fail with counts of impacted fields and a list of discrepancies.

Ring Radar

Continuous graph monitoring that auto-expands suspected fraud rings as new claims arrive. Highlights emerging connections, suggests watchlists, and can place configurable holds on payouts when ring risk crosses a threshold. Enables earlier intervention, preventing losses before they escalate.

Requirements

Streaming Entity Graph Builder
"As a claims operations engineer, I want an always up-to-date entity graph of all claim-related participants and linkages so that Ring Radar can evaluate ring risk on the freshest, most accurate data."
Description

Continuously ingests claims, policy, communication, payment, and device metadata as events to construct and maintain a normalized, deduplicated entity graph (people, organizations, addresses, phone/email, bank accounts, plates/VINs, devices). Performs deterministic and probabilistic entity resolution, creates timestamped nodes/edges with provenance, and updates within defined SLOs (e.g., <2 minutes from claim receipt). Supports idempotency, backfill of historical data, retry-able error handling, and schema versioning. Integrates with ClaimFlow’s NLP extraction outputs and event bus, exposes APIs for graph lookups, and emits metrics/traces for observability. Ensures PII handling and data governance alignment while preserving performance at scale.

Acceptance Criteria
Real-time Ingestion and Update SLO Compliance and Observability
Given the event bus is operational and the builder is running When a new claim, policy, communication, payment, or device metadata event is published with a valid schema and idempotency key Then the corresponding nodes/edges are created or updated in the entity graph within 120 seconds at p95 and within 180 seconds at p99 measured from event publish timestamp to graph commit timestamp And p95 end-to-end latency is reported via metric entity_graph.update_latency_ms tagged by event_type, schema_version, and tenant And the builder emits a trace spanning event consume to graph write with a consistent trace_id propagated from the event And the system sustains 200 events/second for 15 minutes with error rate < 0.5% while meeting the above SLOs And NLP extraction events are consumed and applied within the same SLOs with extracted fields stored with confidence scores
Entity Resolution Quality and Merge Rules
Given deterministic matching rules are configured for entity types (e.g., policy_number+full_name+DOB for persons; VIN for vehicles; routing_number+account_number for bank accounts) When events for the same real-world entity arrive from different sources Then the builder merges them into a single entity node and records all source provenances And deterministic matches always merge (confidence=1.0) and probabilistic matches merge only when confidence >= 0.92; when 0.75 <= confidence < 0.92 the record is linked as a candidate without merge And on a labeled validation set of at least 10,000 entity pairs per type, resolution achieves precision >= 97% and recall >= 93% for persons and organizations, and precision >= 99% and recall >= 98% for unique identifiers (VIN, bank account) And every merge/split action is timestamped, reversible, and logged with before/after snapshots
Idempotent Event Processing and Exactly-Once Semantics
Given events include an idempotency_key and source_event_id When the same event is delivered multiple times (up to 3 replays within 24 hours) or the stream is reprocessed from a checkpoint Then the graph state after processing duplicates is identical to processing a single instance, with no duplicate nodes/edges or repeated side effects And provenance retains a single entry per source_event_id And in a test of 1,000,000 event replays, duplicate node/edge creation rate is 0 And API acknowledgments are issued only after durable write, ensuring at-least-once delivery with idempotent processing
Historical Backfill with Schema Versioning
Given historical datasets spanning 5 years with schema versions v1–v3 are available When backfill is initiated with a checkpoint and throttle of 10,000 records/minute Then all records are normalized to the current schema with original schema_version and source preserved in provenance And backfill may be safely re-run without creating duplicates or conflicting merges And during backfill, real-time p95 update latency degrades by no more than 10% versus baseline and remains within SLO And minimum sustained backfill throughput is >= 600,000 records/hour until completion, with resumable checkpoints on restart
Retryable Error Handling and Dead-Letter Processing
Given transient failures (e.g., timeouts, 5xx) and permanent validation errors can occur When a transient failure happens during event processing Then the system retries with exponential backoff up to 5 attempts and succeeds without operator intervention if the dependency recovers And when a permanent validation error occurs, the event is routed to a dead-letter queue (DLQ) with machine-readable reason_code and payload snapshot And operators can reprocess DLQ items after correction, preserving original idempotency semantics And in load tests at 200 events/second, DLQ rate remains < 0.5%; an alert triggers if DLQ rate >= 1% for 5 consecutive minutes
Graph Lookup APIs with Provenance and Access Controls
Given authorized clients request entity and relationship data via REST/GraphQL When querying by keys (e.g., policy_number, VIN, phone, email, bank_account) or by node_id Then the API returns normalized node(s) with attributes, confidence scores, provenance list (source_event_id, schema_version, timestamps), and adjacent edges up to depth=2 And p95 latency is <= 200 ms for single-entity queries and <= 500 ms for neighbor queries returning up to 100 nodes And responses include ETag and last_updated for caching; empty results return 200 with empty payload And access controls mask PII fields unless the caller has the appropriate role; all accesses are audited
PII Handling and Data Governance Alignment
Given tenant-level data governance policies and PII classification rules are configured When PII is stored or retrieved (e.g., SSN, bank account, email, phone, address) Then PII is encrypted at rest and in transit, field-level masking is applied by role, and data access is restricted to the tenant of origin And retention policies are enforced (e.g., purge or anonymize PII after policy-defined TTL) with auditable logs of deletions And data lineage for every attribute includes source system, source_event_id, and processing steps And privacy tests and access audits show 0 unauthorized PII exposures under role-based access tests across 100 sampled queries
Auto-Expand Suspicious Rings
"As a fraud analyst, I want Ring Radar to automatically build and grow clusters around suspicious claims and entities so that I can identify organized activity early and prioritize investigation."
Description

Implements continuous monitoring jobs that detect seeds of potential fraud (e.g., high-risk entities, rules/model hits) and automatically expand clusters using configurable graph algorithms (k-hop traversal with constraints, community detection, shared-attribute similarity). Applies explosion controls (edge caps, time windows, LoB filters), deduplicates clusters, versions cluster snapshots, and calculates cluster-level risk scores. Triggers on new events and runs scheduled backfills. Persists cluster membership with explainable linkage rationale and produces events for downstream workflows and alerts.

Acceptance Criteria
Real-Time and Scheduled Triggers Execute Expansion
Given a new claim arrives with riskSignal=true or modelScore >= 0.80 or rulesHit contains any of ["known_fraud_entity","multi_claim_same_phone"], When the event is ingested, Then a monitoring job is queued within 5 seconds and cluster expansion completes within 60 seconds (p95) using the active configuration. Given the nightly schedule at 02:00 UTC, When backfill runs, Then all seeds created or updated in the last 30 days are evaluated and expanded with the same logic, and no duplicate jobs are created for seeds processed in the prior 24 hours. Given a transient failure of the expansion job, When retried up to 3 times with exponential backoff, Then exactly-once persistence is maintained (no duplicate clusters or versions).
Algorithm Selection and Parameter Enforcement
Given configuration selects k-hop traversal with k=2 and allowedEdgeTypes=["phone","address","paymentAccount"] and minSharedAttributes=1, When expansion runs on a seed, Then only nodes reachable within 2 hops via allowedEdgeTypes are included and each included node shares >= 1 attribute with the seed or existing members. Given configuration selects community detection (Louvain) with resolution=1.0 and timeWindowDays=365, When expansion runs, Then resulting clusters only include nodes with edges within the last 365 days and the partitioning is deterministic with a fixed random seed. Given configuration selects shared-attribute similarity with JaccardThreshold=0.30 over attributes ["deviceId","ip","address"], When expansion runs, Then nodes with similarity >= 0.30 are included and nodes below the threshold are excluded.
Explosion Controls Prevent Runaway Expansion
Given edgeCapPerNode=100 and globalNodeCap=10000, When expansion encounters a node with degree > 100, Then at most 100 edges from that node are traversed and expansion halts when globalNodeCap is reached with a termination reason recorded. Given timeWindowDays=365 and lobFilter=["Auto","Home"], When expansion runs, Then only edges with eventDate within 365 days and claims with lineOfBusiness in ["Auto","Home"] are considered; excluded counts are captured in metrics. Given maxRuntimeSeconds=45, When expansion exceeds this runtime, Then it terminates gracefully, persists a partial snapshot with status="truncated", and emits a warning event.
Cluster Deduplication and Snapshot Versioning
Given two expansions produce overlapping member sets with Jaccard overlap >= 0.80, When persisting, Then the clusters are merged under a single stable clusterId and a new version is created with version incremented by 1. Given an existing clusterId has no membership change, When expansion re-runs, Then the prior version is reused (no new version created) and lastEvaluatedAt is updated. Given membership changes (add/remove), When persisting, Then a new immutable snapshot is written with version, createdAt, changeSummary (addedCount, removedCount), and previousVersion pointer.
Cluster-Level Risk Scoring and Threshold Actions
Given the risk scoring config weights signals {sharedPaymentAccount:5, sharedAddress:3, velocity:4, pastFraudHit:7}, When a cluster is persisted, Then a riskScore in [0,100] is computed deterministically from member signals and stored with the snapshot. Given riskScore >= holdThreshold (default 70), When a cluster version is created, Then an action "place_hold" is included in the output with holdScope="payments" and holdTTL defaulting to 14 days (configurable). Given riskScore < alertThreshold (default 40), When a cluster version is created, Then no hold or alert event is emitted.
Persisted Membership with Explainable Linkage
Given a cluster member node, When queried via API GET /clusters/{clusterId}/v/{version}/members, Then each member record includes linkPath(s) to the seed, edge types, timestamps, and evidence attributes used for inclusion. Given a member was excluded by constraints (e.g., outside time window), When queried via API with includeExcluded=true, Then the exclusion reason code is returned. Given audit requirements, When a snapshot is created, Then a provenance record includes algorithm, configHash, jobId, input seed(s), and compute timestamps.
Downstream Event Publication for Workflows and Alerts
Given a new cluster version is persisted, When post-processing completes, Then an event is published to topic "ring-risk.events" within 10 seconds containing {clusterId, version, riskScore, actions[], changeSummary, snapshotUrl, correlationId}. Given the same version is retried, When publishing, Then exactly-once delivery is ensured via idempotencyKey=clusterId:version and duplicate publishes are rejected. Given subscriber downtime, When the broker buffers events, Then events are retained for at least 7 days and can be replayed by subscribers from the last acknowledged offset.
Configurable Risk Threshold Holds
"As a claims manager, I want high-risk claims to be automatically placed on payout hold based on ring risk so that we prevent losses while an investigator reviews the case."
Description

Enables policy-based, configurable payout holds when claim- or cluster-level risk exceeds thresholds. Supports multiple thresholds by line of business, jurisdiction, and claim type; hold durations and SLA timers; and override/appeal workflows with full audit trails. Integrates with ClaimFlow’s workflow engine to auto-create tasks, assign owners, and route for SIU review. Ensures idempotent hold placement/removal, emits notifications (in-app, email, webhook), and provides reporting on hold outcomes and leakage avoided.

Acceptance Criteria
Auto-Apply Hold When Risk Threshold Exceeded
Given a claim with Line of Business L, jurisdiction J, and claim type T And active hold policies with thresholds for L, J, and T When the claim- or cluster-level ring risk score is updated to ≥ the configured threshold Then a payout hold is placed on the claim within 5 seconds of threshold detection And the hold references the matched policy ID and threshold version And the hold status is set to Active and displayed on the claim header and payments panel And payment disbursement actions are blocked while the hold is Active And reprocessing the same event for the same claim and policy does not create duplicate holds (idempotent)
Multi-Dimensional Threshold Resolution and Precedence
Given multiple active hold policies can match a claim by L, J, and T And policies define priority and effective date ranges When more than one policy matches a risk event Then the system selects the policy with the highest priority And if priorities tie, the most specific match (matches all three dimensions) is selected And if still tied, the policy with the latest effective start date is selected And the selected policy ID and resolution rationale are written to the audit log
Hold Duration and SLA Timer Management
Given a hold policy defines a hold duration D and an SLA S When a hold is placed on a claim Then the hold expiry is set to now + D and auto-evaluated every minute And an SLA timer starts using the jurisdictional business calendar And at 75% of S without SIU decision, an escalation task is created and assigned to SIU And when the hold expires without extension, the status changes to Expired and payments are unblocked
Override and Appeal Workflow with Full Audit Trail
Given a user with Override permission opens an Active hold When they submit an override with mandatory reason, evidence link, and scope selection Then the hold status changes to Overridden and payments are unblocked immediately And an appeal item is created and routed to SIU with the submitted details And the audit log records user ID, timestamp, fields changed, previous values, and IP address And if SIU denies the appeal within SLA, the hold is reinstated under the original policy with linkage to the prior hold
Workflow Integration and Idempotent Tasking
Given a hold transitions state (Active, Overridden, Expired, Reinstated) When the workflow engine processes the hold event Then at most one SIU review task is created per hold state transition, with no duplicates on retries And tasks are assigned per routing rules for L, J, and T And task records reference the originating hold ID and claim ID And reprocessing an identical event yields no additional tasks (idempotent)
Notifications on Hold State Changes (In-App, Email, Webhook)
Given notification channels (in-app, email, webhook) are configured When a hold is Created, Updated, Overridden, Expired, Reinstated, or Removed Then an in-app banner appears on the claim within 5 seconds including state, reason, risk score, threshold, and hold ID And an email is sent to the claim owner and SIU group with the same details and deep links And a webhook is POSTed once per transition with HMAC signature, idempotency key = holdID:state, and retry with exponential backoff up to 24 hours And no duplicate notifications are emitted for retried or replayed events
Hold Outcomes and Leakage Avoided Reporting
Given holds have been applied to claims over a reporting period When the Hold Outcomes report is generated for a date range Then the report includes counts of holds by state, average time to SIU decision, average hold duration, number of overrides, and percentage escalated And it includes monetary metrics: total dollars on hold, dollars released, dollars avoided (based on configurable leakage model), and net leakage avoided And all metrics are filterable by L, J, T, and policy ID, and exportable as CSV And definitions and calculation methods for each metric are included in the report metadata
Watchlist Suggestions & Management
"As an SIU investigator, I want intelligent suggestions and easy management of watchlists so that I can track recurring bad actors and get alerted when they resurface in new claims."
Description

Provides UI and APIs to create, manage, and audit watchlists for entities and clusters. Suggests watchlist additions based on similarity scores, proximity to known rings, repeat contact details, or rule/model hits. Supports bulk import/export, de-duplication, expiration policies, ownership/notes, and cross-tenant segregation. Integrates with risk scoring to elevate entities on watchlists and with alerting to notify on new interactions with watchlisted items.

Acceptance Criteria
Create and Update Watchlist Items (UI & API)
Given a user with WATCHLIST.WRITE permission in Tenant A When they create a watchlist item for an entity or cluster with required fields {entityType, entityKey (normalized), reason, owner, expirationDate} Then the system returns 201 (API) or success (UI) and persists the item with status=Active, createdBy, createdAt, tenantId=Tenant A And retrieving by id and searching by entityKey returns the item within 1 second (p95) And attempting to create a duplicate (same normalized entityKey and scope in Tenant A) returns 409 and no new item is created And users without WATCHLIST.WRITE receive 403 and no item is created And updates to notes, owner, severity, tags return 200 and increment version with updatedAt set And soft-deleting sets status=Archived, excludes from default searches, and keeps it in audit records And expired items auto-transition to status=Expired at 00:00:00 UTC on expirationDate and become non-blocking in workflows
Automated Watchlist Suggestions with Explainability
Given suggestion thresholds are configured (similarity>=0.85, proximityHops<=2, repeatContact>=3, ruleOrModelHit=true) When a new claim or entity is ingested Then the system generates a suggestion for each entity meeting at least one predicate and includes evidence {type, score, rationale, matchedAttributes} And each suggestion displays a confidence score and source(s) And accepting a suggestion creates a watchlist item with link to source entity and reason prefilled with evidence And dismissing a suggestion suppresses the same entity+tenant suggestion for 30 days And no suggestion is shown for entities already on the watchlist in the same tenant And suggestion processing latency is <= 2 minutes from ingestion time (p95) And all accept/dismiss decisions are captured in the audit log
Bulk Import/Export with Deduplication
Given a user with WATCHLIST.ADMIN permission uploads a CSV or JSON with required columns {entityType, entityKey, reason, owner, expirationDate} When pre-validation runs Then schema, required fields, and data types are verified and a preview with row-level errors is returned And on confirm, items are created for valid rows, duplicates (same normalized entityKey in tenant) are skipped, and invalid rows are rejected And the response includes a summary {total, created, skippedDuplicates, failed, duration} And importing 100k rows completes within 15 minutes end-to-end (p95) And an export endpoint returns filtered watchlist items (by status/owner/date/riskTag) via streaming within 30 seconds for up to 1M rows (p95) And imported items apply default expiration policy if none provided and set owner per file metadata And all import/export operations are recorded in audit with checksums for files
Audit Trail and Governance
Given audit logging is enabled When any watchlist item is created, updated, archived, accepted from suggestion, dismissed, imported, or exported Then an immutable audit record is written with {tenantId, actorId, actorType(user/apiKey), action, itemId, before, after, timestamp, ip} And audit records are queryable by filters (date range, actor, action, itemId) and exportable as CSV/JSON And attempts to modify or delete audit records are blocked with 403 and produce a security alert And audit retention meets or exceeds the tenant-configured period (default 7 years) And time on records is stored in UTC with millisecond precision
Risk Scoring Integration for Watchlisted Entities
Given a claim includes an entity that matches a watchlist item in the same tenant When the risk scoring pipeline executes Then the score includes a watchlist_uplift component per tenant configuration and sets watchlistHit=true with reference to watchlistItemIds And the final riskScore reflects the uplift and is surfaced in the claim UI with a Watchlist badge linking to details And scoring events include an explanation entry for the uplift And removing the entity from the watchlist eliminates the uplift on subsequent scorings And the scoring API response time remains within existing SLOs (no more than +50ms p95 due to watchlist checks)
Alerting on New Interactions with Watchlisted Items
Given alert channels are configured (in-app, email, webhook) and user has WATCHLIST.ALERTS permission When a new claim, message, or payment references a watchlisted entity in the same tenant Then an alert is generated within 2 minutes (p95) containing {entityKey, watchlistItemId, interactionType, claimId/messageId/paymentId, timestamp, riskScore} And duplicate alerts for the same interaction are suppressed And webhook deliveries use signed requests, retry with exponential backoff for up to 24 hours, and mark status delivered/failed And alert visibility is limited to authorized roles and scoped to the tenant And alert actions (acknowledge, assign, mute) are recorded in audit
Cross-Tenant Segregation and RBAC Enforcement
Given tenants A and B exist with separate users and data When a user from Tenant A lists, searches, creates, updates, or exports watchlist items Then only Tenant A items are returned or modified, and attempts to access Tenant B items yield 404 (resource not found) without leaking existence And all API endpoints require authenticated context with tenant scoping and enforce role permissions {WATCHLIST.READ, WATCHLIST.WRITE, WATCHLIST.ADMIN} And auto-suggestions and alerts are generated only within the originating tenant’s boundary And superadmin cross-tenant actions require elevated scope and are fully audited
Investigator Graph Console & Alerts
"As a field investigator, I want an interactive graph view with actionable alerts so that I can quickly understand ring structure, gather evidence, and take immediate action within my workflow."
Description

Delivers an in-product console to visualize clusters and claim linkages with interactive graph views (filter by time, edge type, LoB), risk overlays, timelines of events, and evidence panels showing supporting artifacts. Offers one-click actions (place hold, assign task, add to watchlist), case notes, and export/print for referrals. Provides subscription-based alerts with noise controls (thresholds, frequency caps, dedupe) across in-app, email, and webhook channels. Targets responsive performance budgets and accessibility standards.

Acceptance Criteria
Interactive Graph Filtering and Drill-Down
- Given a cluster with ≥1000 nodes and ≥3000 edges is loaded, when the investigator opens the graph view, then the initial render completes within 2.0 seconds at p95 on supported browsers. - Given time range, edge type, and Line of Business filters are visible, when the user applies or removes any combination of filters, then the graph hides non-matching nodes/edges, updates counts and legend, and re-renders within 800 ms at p95. - Given a node or edge is clicked, when the user selects “Expand neighbors,” then the next ring of connected entities is added without duplications and the view auto-centers within 600 ms at p95. - Given a set of active filters, when the user copies the page URL, then the URL includes the filter state and reopening the URL restores the exact view. - Given filters have been applied, when the user clicks “Reset,” then all filters clear and the default view is restored within 800 ms at p95. - Given keyboard-only navigation, when the user tabs through filters and graph actions, then all controls are reachable and operable via keyboard and have accessible names per WCAG 2.1 AA.
Timeline of Events for Cluster and Claims
- Given a cluster is selected, when the investigator opens the Timeline tab, then events from all linked claims are displayed in chronological order with source, timestamp (UTC and local), and entity references. - Given more than 500 events exist, when the user applies time and type filters on the timeline, then the event list updates within 500 ms at p95. - Given an event is clicked, when the user drills in, then the associated claim, node/edge, and evidence panel are brought into focus in the graph and details panel. - Given time zones vary across events, when displayed, then all events show normalized UTC time with local time offset indicators. - Given keyboard-only navigation, when the user uses Arrow keys and Enter, then the focus moves across events and expand/collapse works per WCAG 2.1 AA.
Evidence Panel with Artifacts and Provenance
- Given a node or edge is selected, when the Evidence panel opens, then it displays supporting artifacts (images, messages, documents) with thumbnails, file types, capture timestamps, source system, and a verifiable checksum (SHA-256). - Given an artifact is clicked, when preview loads, then a larger view opens within 400 ms at p95 with download option and link to original record in ClaimFlow (opens in new tab). - Given an artifact has been redacted, when displayed, then the panel shows a redaction banner including who, when, and reason from audit metadata. - Given an unavailable artifact, when the panel attempts to load it, then a non-blocking error message appears with retry and report options; the rest of the panel remains usable. - Given the panel is open, when the user exports evidence, then selected artifacts and their metadata are added to the referral pack manifest.
One-Click Actions: Hold, Assign, Add to Watchlist
- Given proper permissions, when the investigator clicks “Place Hold,” then the claim’s payout status is set to Hold within 1 second, a reason must be selected, hold level and duration are recorded, and the claim UI shows a hold badge. - Given insufficient permissions, when the user hovers or clicks “Place Hold,” then the control is disabled and a tooltip explains the required role. - Given “Assign Task” is selected, when the user chooses an assignee and due date, then a task is created with SLA, appears in the assignee’s queue within 5 seconds, and a case note is added. - Given “Add to Watchlist” is clicked, when confirmed, then the entity/claim is added to the selected watchlist and subsequent matches raise a watchlist flag in alerts. - Given any one-click action completes, when viewing case notes or the audit log, then an entry appears with timestamp, actor, and action details retrievable via API. - Given keyboard-only navigation, when activating any one-click action via Enter/Space, then the action executes equivalently to mouse interaction and focus returns to the originating control.
Alert Subscriptions with Thresholds, Caps, and Dedupe
- Given the Alerts settings, when a user creates a subscription, then they can configure ring risk threshold (0–100), minimum cluster size, filters (LoB, geography, time window), frequency cap (e.g., 1 per cluster per 24h), channels, and a deduplication window. - Given multiple qualifying events occur within the dedupe window, when alerts are generated, then only one alert is emitted per cluster/entity with an incremented occurrences count. - Given a frequency cap is set, when more matches occur than allowed, then excess alerts are suppressed and a daily summary is sent indicating suppressed count. - Given a subscription is saved, when the test button is pressed, then a test alert is delivered across chosen channels within 10 seconds. - Given an existing subscription, when paused, then no alerts are sent until resumed; audit trail records create, edit, pause, resume with actor and timestamp.
Multi-Channel Alert Delivery: In-App, Email, Webhook
- Given an alert is triggered, when delivered in-app, then it appears in the notification center within 5 seconds with unread state, cluster ID, risk score, top linkages, and deep links to the console. - Given email channel is selected, when an alert is sent, then the email uses the configured brand, includes subject with [Ring Radar], risk score, and cluster ID, and contains a secure deep link; deliverability passes SPF/DKIM/DMARC and includes a manage-subscriptions link. - Given webhook channel is selected, when the endpoint responds 2xx, then the payload is delivered exactly once with HMAC-SHA256 signature header and an idempotency key; when 5xx occurs, then retries happen with exponential backoff for up to 24 hours. - Given network or channel failures, when delivery retries exhaust, then an in-app warning and an email to the subscription owner are generated with failure details. - Given PII governance, when alerts are delivered, then only fields allowed by the recipient’s role are included; sensitive fields are masked per policy.
Export/Print Referral Pack
- Given a cluster is selected, when the user clicks Export, then a referral pack PDF is generated within 6 seconds at p95 containing a summary (cluster ID, risk score, size), graph snapshot, timeline, key entities, and case notes. - Given evidence is included, when exporting, then selected artifacts are embedded or linked with a manifest (filename, checksum, source, timestamp) and a separate CSV of nodes/edges is included. - Given role-based masking is required, when exporting, then PII is redacted per policy and the PDF is watermarked with the viewer’s name, date, and “Confidential.” - Given the user selects Print, when the print view opens, then a printer-friendly layout with grayscale option renders correctly in Chrome and Edge, and page breaks do not cut through images or table rows. - Given export completes, when the user downloads, then the file size does not exceed 25 MB for clusters up to 1000 nodes/3000 edges; if exceeded, a split export option is offered.
Explainable Ring Risk
"As a compliance-conscious analyst, I want clear explanations for ring risk scores so that I can justify actions to stakeholders and regulators."
Description

Generates transparent claim- and cluster-level risk scores with human-readable explanations: rule hits, key features, and top contributing edges/paths. Supports model versioning, calibration, drift monitoring, and A/B testing of scoring strategies. Captures analyst feedback and investigation outcomes to close the loop for training data. Exposes evidence packets with links to source artifacts and maintains decision logs for defensibility and compliance.

Acceptance Criteria
Claim-Level Explainability at Intake
Given a claim is scored by Ring Radar When an analyst opens the claim detail view Then the UI displays the risk score (0–100), the top 5 contributing features with contribution values, and all triggered rules (IDs and descriptions) And the explanation includes deep links to source artifacts referenced by those features/rules (minimum 3 if available) And the explanation payload is stored with the decision log entry And the explanation panel renders in <= 2.0 seconds at p95 over the most recent 1,000 scored claims And 100% of scored claims expose an explanation; missing explanations are flagged and logged as errors
Cluster-Level Path Explanation for Suspected Ring
Given a scored claim belongs to a detected cluster When the analyst opens the cluster insights tab Then the system shows the cluster-level ring risk score (0–100) And lists the top 10 contributing edges/paths up to depth 3 with contribution scores and node/edge IDs And each path is clickable to navigate to the underlying claims, policies, and entities And an "Export paths" action downloads the list as CSV and JSON And the cluster explainability view renders in <= 3.0 seconds at p95
Evidence Packet Generation with Source Links
Given an analyst clicks "Export evidence packet" on a claim or cluster When the export is requested Then the system generates a packet containing: risk score, model name/version, UTC timestamp, rules hit, top features with contributions, contributing paths (if cluster), decision summary, and analyst notes (if any) And includes deep links and immutable references (artifact IDs and checksums) to all cited source artifacts (photos, messages, policies, payments) And outputs both a human-readable PDF and a machine-readable JSON And signs the packet with a system certificate and provides a SHA-256 checksum of the bundle And completes generation in <= 10 seconds at p95 And records the export in the decision log with requester, time, and packet hash
Decision Logging and Reproducibility
Given any scoring event occurs When the score is persisted Then the decision log entry includes: claim/cluster IDs, model name/version/hash, feature vector hash, config/thresholds, experiment/variant (if any), score, rules hit, top features, contributing paths, UTC timestamp, and actor/system And the log is stored in WORM storage with retention >= 7 years And a "Reproduce score" API allows re-scoring with the same model version and inputs to produce the same score within tolerance 1e-6 And an auditor can fetch a complete record by decision ID within 1 second at p95
Model Versioning and Calibration Management
Given a new scoring strategy is registered When it is promoted to active for a line of business Then the system records approver, change ticket, and effective UTC timestamp And the active version is visible in the UI and included in all decision logs And calibration metrics (ECE and Brier score) are computed on a held-out validation set and stored with dataset ID And ECE <= 0.05 and Brier <= 0.20 for the targeted segment before promotion; otherwise promotion is blocked And a calibration plot is viewable in the UI and exportable as PNG/CSV And rollback to the prior version can be completed in <= 5 minutes and is fully audited
Drift Monitoring and Alerting
Given the system runs daily drift monitoring jobs When population, covariate, or performance drift exceeds thresholds Then an alert is created in-app and sent to configured email/Slack channels with impacted segments and metrics And thresholds include: PSI > 0.20 for any key feature, KS test p-value < 0.01 for score distribution shift, or AUC absolute drop >= 0.05 vs. baseline And a drift dashboard shows time series of metrics and allows downloading evidence as CSV And a ticket is auto-created in the risk queue with links to affected models/versions And all drift events are written to the audit log
Experimentation and Analyst Feedback Loop
Given an experiment comparing two scoring strategies is configured with a defined traffic split (e.g., 50/50) When claims are scored during the experiment Then users are deterministically assigned to a variant (sticky by claim ID) and the assignment is logged And each decision log includes experiment ID and variant And an experiment report provides sample sizes, target metrics, uplift, confidence intervals, and p-values with alpha = 0.05 And analysts can submit structured feedback per claim/cluster: outcome label (Confirmed ring/Not ring/Unclear), reason codes, and free-text notes And feedback is persisted within 1 minute, linked to decision ID, and exportable as CSV/JSON And feedback is incorporated into the next training snapshot within 24 hours and tagged with source and timestamp
Privacy, RBAC, and Audit Controls
"As a security and compliance officer, I want strict access controls and auditable activity trails so that fraud detection does not compromise privacy or regulatory obligations."
Description

Applies role-based access controls and least-privilege policies to Ring Radar data and actions, including field-level masking for PII and sensitive financial identifiers. Ensures encryption in transit/at rest, tenant isolation, IP allowlists, and comprehensive audit logging of views, changes, holds, and overrides. Implements retention policies, redaction workflows, and legal hold support to align with GLBA/CCPA and carrier policies without degrading core detection capabilities.

Acceptance Criteria
RBAC Enforcement for Ring Radar Graph and Actions
Given a user without any Ring Radar role, When they request any Ring Radar UI or API, Then the system returns HTTP 403 and no data is leaked. Given a user with role Claims Viewer, When viewing Ring Radar, Then only anonymized graph structure and non-PII tags are visible and all action buttons (add to watchlist, place hold, override) are disabled. Given a user with role Fraud Analyst, When viewing Ring Radar, Then PII remains masked and the user can add entities to watchlists and submit hold requests for approval but cannot override holds. Given a user with role Fraud Manager, When viewing Ring Radar, Then the user can place and override holds, approve unmask requests, and export allowed reports; PII remains masked unless an unmask is granted. Given any user whose role membership changes, When they next call the API or refresh the UI, Then permission changes take effect within 60 seconds.
Field‑Level PII Masking and Just‑In‑Time Unmask
Given a user without unmask authorization, When viewing SSN, DOB, bank account, driver’s license, email, phone, or address fields, Then values are masked per policy (e.g., last4 only) and excluded from exports and screenshots APIs. Given a user requests to unmask PII, When they provide a purpose code and justification, Then a workflow routes to a Fraud Manager for approval and, upon approval, unmasking is granted for the specific record for a maximum of 15 minutes and auto‑remasked afterward. Given an unmask event occurs, When it is executed, Then an audit entry records user, fields unmasked, purpose code, approver, time window, and source IP. Given an API token lacking an approved unmask claim, When calling PII endpoints, Then responses return masked values and HTTP 200 with a masked flag per field.
Encryption in Transit and At Rest
Given any client‑to‑service or service‑to‑service connection, When a handshake is initiated, Then TLS 1.2+ with approved cipher suites is enforced and plaintext connections are refused. Given internal microservice calls, When authentication is validated, Then mutual TLS (mTLS) is required and unauthorized calls are blocked with 401/403. Given data at rest in databases, object storage, search indexes, and backups, When stored, Then AES‑256 encryption is used with KMS‑managed keys and keys are rotated at least every 90 days. Given tenant‑scoped encryption keys, When a key rotation or compromise response is executed, Then re‑encryption completes without data loss and without more than 5 minutes cumulative downtime per tenant.
Tenant Isolation and IP Allowlists
Given a user authenticated for Tenant A, When querying Ring Radar data, Then only Tenant A records are returned and cross‑tenant leakage tests return zero records. Given IP allowlisting is enabled for a tenant, When a request originates from a non‑allowlisted IP/CIDR, Then the request is blocked with HTTP 403 and an audit event is recorded. Given multi‑tenant batch or streaming jobs, When processing data, Then compute contexts and storage namespaces are isolated per tenant and no shared identifiers or caches are reused across tenants.
Audit Logging of Views, Changes, Holds, and Overrides
Given any Ring Radar view or mutation, When the action occurs, Then an immutable audit record is written within 1 second capturing actor ID, tenant, role, action type, object IDs, before/after values (for writes), timestamp (UTC), source IP, user agent, and correlation ID. Given a Compliance role user, When searching audit logs, Then they can filter by actor, action type, object ID, time range, and export results as CSV or JSON. Given audit log retention policies, When records exceed the configured retention period, Then they are purged unless on legal hold and purge events are themselves audited; backups containing purged records are pruned within 30 days.
Retention Policies, Redaction Workflows, and Legal Hold
Given a tenant‑configured retention policy (e.g., 7 years), When records exceed the retention period, Then they are scheduled and deleted from primary stores within 30 days with a verifiable deletion report. Given an approved data subject redaction request (GLBA/CCPA), When executed, Then PII is irreversibly redacted across primary stores and search indexes within 30 days while preserving non‑identifying analytics aggregates. Given a legal hold applied to a subject or case, When the hold is active, Then deletion and redaction processes skip affected records until the hold is released and all hold changes are fully audited.
Privacy Controls Preserve Detection Performance
Given masking, RBAC, and encryption are enabled, When running Ring Radar detection on the standard evaluation dataset, Then precision/recall/F1 deltas are each within 1% of the baseline without controls. Given privacy controls are enabled, When processing live claims traffic, Then the 95th percentile time to first ring‑risk score increases by no more than 5% versus the established baseline. Given analysts operate with masked UI views, When they add to watchlists or submit hold requests, Then server‑side detection and ring expansion operate on full underlying data with no missing links attributable to masking.

Route Orchestrator

Risk-tier routing that adapts to line of business, jurisdiction, and dollar exposure. Automatically sends high-risk claims to SIU, medium-risk to a screener, and low-risk to fast-track, factoring in team capacity and SLAs. Ensures the right work lands with the right team at the right time, accelerating honest claims and elevating true risks.

Requirements

Dynamic Risk Scoring Engine
"As a claims manager, I want every new claim automatically risk-scored and tiered so that routing decisions are fast, consistent, and defensible."
Description

Compute a real-time risk score and tier (High/Medium/Low) for each claim using inputs from the NLP extraction engine, line of business, jurisdiction, dollar exposure, claimant/policy history, photo forensics flags, and channel metadata. Provide explainable outputs (top contributing factors with weights), configurable thresholds per line of business and jurisdiction, and deterministic fallbacks when data is incomplete. Expose the score via an internal API/event so Route Orchestrator can trigger routing within 500 ms p95. Support idempotent re-scoring on data updates, model/version tagging, and safe degradation to default tiers if the service is unavailable. Integrates with ClaimFlow intake events and persists score artifacts for audit and analytics.

Acceptance Criteria
Real-time risk scoring and tiering via API/event within 500 ms p95
Given a ClaimFlow intake event with NLP-extracted features, lineOfBusiness, jurisdiction, dollarExposure, claimant/policy history, photoForensics flags, and channel metadata When the Dynamic Risk Scoring Engine receives a scoring request via the internal API Then it returns HTTP 200 with a body containing riskScore (numeric) and riskTier in {High, Medium, Low} And the end-to-end service processing time from request receipt to response is <= 500 ms p95 across at least 1,000 requests in a production-like environment And an internal scoring-completed event is emitted containing claimId, riskScore, riskTier, modelVersion, configVersion, timestamp, and explainability payload, observable by a test subscriber on the event bus
Explainable outputs with top contributing factors
Given any successful scoring response When the response payload is validated Then it includes topContributors as an array of at least 3 factors, each with factorKey, direction (positive|negative), weight (0..1), and contributionScore And the contributors are sorted by absolute contributionScore descending And the sum of weights is 1.0 ± 0.01 And factorKeys map to a documented factor dictionary
Configurable tier thresholds by line of business and jurisdiction
Given threshold configuration exists for each (lineOfBusiness, jurisdiction) pair defining boundaries for Low/Medium/High When a configuration value is updated for a specific (lineOfBusiness, jurisdiction) Then subsequent scoring requests for that context use the new thresholds without requiring a service redeploy And the response includes configVersion and thresholdsApplied reflecting the active configuration And boundary tests verify that scores exactly at thresholds map deterministically to the configured tier
Deterministic fallbacks for incomplete input data
Given one or more inputs (e.g., claimant history, photoForensics, channel metadata) are missing or invalid When the engine performs scoring Then it applies deterministic fallback rules from configuration and produces a riskTier and a riskScore (or null if configured) And the response includes fallbackApplied=true and fallbackReasons enumerating each missing/invalid input source And repeated scoring with the same available inputs yields identical riskScore and riskTier
Idempotent re-scoring on claim data updates with model/version tagging
Given a claim update event that changes one or more inputs When the engine re-scores the claim Then a new artifact is produced with modelVersion and configVersion tags, leaving prior artifacts immutable And the response and event include scoreVersion that increments monotonically per claim And when the same request is retried with the same idempotencyKey (or identical payload hash), the engine returns HTTP 200 with the original result and does not create a duplicate artifact
Safe degradation to default tiers on service or dependency failure
Given the model runtime or a critical dependency is unavailable or times out When a scoring request is received Then the engine responds within 500 ms p95 with riskTier set to the configured default for the claim's (lineOfBusiness, jurisdiction), riskScore=null, and degraded=true And the response includes errorCode and errorMessage indicating the cause And a degradation event is emitted; no unbounded retries occur
Persistence of score artifacts for audit and analytics
Given a scoring operation completes (success or degraded) When the artifact is persisted Then the stored record contains claimId, requestId, inputsUsed summary, thresholdsApplied, riskScore, riskTier, topContributors, fallback flags and reasons, modelVersion, configVersion, scoreVersion, timestamps, and checksum And retrieval by claimId and scoreVersion returns an immutable artifact exactly matching the response/event payload And artifacts are queryable for analytics by time range, lineOfBusiness, jurisdiction, and riskTier
Configurable Routing Policies
"As an operations admin, I want to configure routing logic without engineering changes so that the right teams receive the right claims under changing business rules."
Description

Provide an administrative policy engine and UI to map risk tiers, line of business, jurisdiction, exposure thresholds, and claim attributes to destination queues, roles, and workflows. Support rule precedence, exceptions, and effective-dated versions with draft, validate, simulate, and publish steps. Allow JSON/YAML import/export, RBAC-controlled edits, and policy testing against historical claims. Ensure safe-rollout with canary and rollback, and emit policy version in all routing events for traceability. Multi-tenant isolation for MGAs and carriers with tenant-specific defaults and overrides.

Acceptance Criteria
Admin maps risk tiers to destinations
Given tenant T has defined destination queues and workflows And an authorized admin opens the Policy Engine UI When the admin creates a draft policy that maps combinations of lineOfBusiness, jurisdiction, exposure thresholds, and claim attributes to queues, roles, and workflows And saves the draft Then validation passes with no schema or reference errors And test routing using at least 5 sample claims produces destinations exactly matching the configured mappings And the saved policy is retrievable via UI and API with identical rule definitions
Rule precedence and exception overrides
Given a policy with a base rule and a more specific exception rule with higher precedence When a claim matches both rules Then the exception rule fires and the base rule does not And precedence is determined first by explicit precedence value, then by specificity, then by stable ruleId ordering And the decision payload includes the winning ruleId and the reason for rule selection
Effective-dated versions with draft, validate, simulate, publish
Given a draft policy with effectiveStart and optional effectiveEnd within tenant scope When Validate is executed Then the system detects and blocks overlapping effective date ranges for the same policyKey within the tenant and reports precise errors with rule and date ranges When Simulate is run against at least 500 historical claims selected by the admin Then the system returns routing outcomes and deltas versus the current active version with summary metrics (match rate, delta count) When Publish is confirmed Then the policy becomes Scheduled if future-dated or Active if effectiveStart is now, with only one Active version per policyKey per tenant
JSON/YAML import and export
Given a policy definition file in JSON or YAML conforming to schema version S When the admin imports the file Then the system creates a draft policy, or rejects with field-level errors pinpointing invalid paths And an immediate export of the created draft yields semantically equivalent JSON and YAML representations (round-trip check) And exports include policyKey, version, effective dates, rules, and tenantId
RBAC-controlled policy editing
Given RBAC roles: Viewer, Editor, Publisher, Admin with corresponding permissions When a user without the required permission attempts view, edit, validate, simulate, publish, or rollback Then the action is blocked with HTTP 403 and the UI control is disabled or hidden And a user with the required permission can complete the action successfully And all policy operations are constrained to the user's tenant; cross-tenant access is denied
Canary rollout and rollback
Given an active version V1 and a newly published version V2 When a canary of 10% is configured for tenant T Then approximately 10% ±1% of at least 1000 new claims are routed using V2 based on a deterministic claimId hash And the policyVersion used is stable per claim across retries When the canary is promoted to 100% or rolled back Then new claims use the selected version within 60 seconds; in-flight claims keep their originally assigned version
Routing event traceability with policy version
Given any routing decision produced by the orchestrator Then the emitted event and claim audit record include tenantId, policyKey, policyVersion, matched ruleId, decision destination, and timestamp And the event conforms to the published JSON schema And for canary traffic the correct policyVersion is present and matches the applied routing
Capacity and SLA-Aware Assignment
"As a queue owner, I want routing to account for capacity and SLAs so that work is distributed fairly and no claim violates service commitments."
Description

Continuously factor team capacity, working calendars, WIP limits, skill tags, and SLA commitments into routing decisions to balance load and prevent breaches. Pull live queue metrics and user availability, then assign to the best queue/assignee with overflow to backup teams when thresholds are reached. Re-route automatically if SLA risk increases, and honor jurisdictional handling restrictions. Provide configuration for prioritization strategies (e.g., shortest slack time, skill-first), and expose real-time capacity snapshots to the policy engine. Integrate with workforce management calendars and send alerts when capacity constraints block routing.

Acceptance Criteria
Capacity- and Skill-Aware Initial Assignment
Given live queue metrics, user availability (on-duty), WIP limits, skill tags, jurisdiction eligibility, and SLA targets are available When a new claim with line of business, jurisdiction, dollar exposure, and required skills enters the routing engine Then it is assigned within 2 seconds to an eligible assignee who is on-duty, under WIP limit, has all required skills, and is jurisdiction-eligible And the decision respects the currently active prioritization strategy And the assignment action is recorded with rationale, metrics snapshot, and timestamp in the audit log
Overflow to Backup Teams on Threshold Breach
Given a primary team is configured with backup teams and capacity thresholds When the primary team cannot accept a claim due to WIP limit reached, no on-duty eligible assignee, or minimum staffing threshold not met Then the claim is routed within 3 seconds to the first backup team that satisfies skill and jurisdiction rules And the overflow reason, evaluated teams, and selection are logged And if no backup can accept, the claim is placed in Capacity Hold with reason code NO_CAPACITY
Automatic Re-Routing on SLA Risk Escalation
Given assigned claims are monitored with predicted completion time and slack computed from live capacity and SLA due time When predicted completion exceeds SLA or slack falls below the configured threshold Then the claim is re-evaluated and reassigned within 60 seconds to an eligible resource/team that reduces breach risk And prior and new assignees are notified And no claim is auto re-routed more than once every 15 minutes unless time-to-breach is under 30 minutes
Jurisdictional Handling Restrictions Enforced
Given jurisdiction authorization rules for teams and users are configured When evaluating routing or re-routing for a claim with a specific jurisdiction Then only authorized teams/users are considered for assignment And any attempt to assign to an unauthorized handler is blocked with error code JURISDICTION_NOT_AUTHORIZED and a compliance audit entry
Real-Time Capacity Snapshot Exposed to Policy Engine
Given the policy engine requests the capacity snapshot When GET /capacity-snapshot is called with valid auth Then the response returns 200 with per team and per user fields: onDuty, wipCount, wipLimit, availableSlots, nextAvailableAt, avgHandleTime, and lastUpdatedAt with staleness <= 5 seconds And p95 latency is <= 500 ms at 50 rps And changes are also published on the capacity event stream within 5 seconds of change
Workforce Calendar Integration and Availability Honor
Given integration with workforce management calendars for shifts, PTO, holidays, and time zones is configured When a user's calendar status changes or the system crosses a shift boundary Then the user's on-duty availability within routing updates within 60 seconds And routing never assigns claims to users marked off-duty or on PTO And if calendar sync fails for a user, the user is excluded from eligibility until sync recovers and the failure is logged
Capacity Constraint Alerts on Routing Block
Given routing of a claim is blocked due to capacity constraints for more than 30 seconds When the block condition is detected Then an alert is sent within 15 seconds to configured channels with claimId, reason, affected teams, and recommended action And alerts are deduplicated to at most one per 10 minutes per team and per reason And a recovery alert is sent when the claim leaves Capacity Hold or is assigned
SIU Auto-Referral Pack
"As an SIU analyst, I want high-risk claims to arrive with a complete, standardized referral pack so that I can investigate faster and more effectively."
Description

Automatically generate and route a complete SIU referral when a claim is tiered High risk, including a structured dossier with claim summary, NLP-extracted entities, exposure, anomaly flags, geo/time inconsistencies, claimant/policy history, and supporting images/documents. Create an SIU case, notify the SIU queue, and maintain two-way status sync for accept/decline outcomes with fallback routing if declined. Capture reason codes, timestamps, and artifacts for audit, and enforce jurisdiction-specific referral criteria and thresholds.

Acceptance Criteria
High-Risk Claim Triggers SIU Case and Dossier Generation
Given a claim with claimId, riskTier = "High", a valid jurisdictionCode, and an active policy When the Route Orchestrator processes the claim Then the system creates a new SIU case with siuCaseId associated to claimId within 15 seconds p95 of the routing event And the SIU case status is set to "Pending Review" And a structured dossier is generated and stored with a stable dossierId And the dossier contains sections: claimSummary, nlpExtractedEntities, exposureEstimate, anomalyFlags, geoTimeInconsistencies, claimantHistory, policyHistory, attachments And nlpExtractedEntities includes at minimum: policyNumber, claimantName, lossLocation, lossDateTime And exposureEstimate contains amount and currency And attachments includes all intake-uploaded images/documents linked to the claim and are retrievable
Jurisdiction-Specific Referral Rules Are Enforced
Given a jurisdictionCode with configured SIU referral criteria and thresholds And a claim whose attributes meet the configured criteria When the claim is evaluated for SIU referral Then an SIU referral is generated and routed as required for that jurisdiction And the ruleEvaluationLog is recorded with ruleId, ruleVersion, matched = true, and evaluation timestamp Given a jurisdictionCode with configured SIU referral criteria and thresholds And a claim whose attributes do not meet the criteria When the claim is evaluated for SIU referral Then no SIU referral is generated And the ruleEvaluationLog is recorded with matched = false And the outcome is visible in the audit trail for the claim
SIU Queue Notification and Delivery
Given an SIU case is created for a claim When the notification step executes Then a message is published to the SIU queue/topic with payload fields: siuCaseId, claimId, riskTier, jurisdictionCode, reasonCodes, dossierLink, createdAt And the publish operation receives an acknowledgement from the queue And end-to-end notification latency is < 30 seconds p95 from case creation to queue acknowledgement And on transient publish failure the system retries at least 3 times with exponential backoff And on exhausted retries the system records NotificationFailed in audit, raises an alert, and surfaces a dashboard error
Two-Way Status Sync: Accept or Decline
Given an SIU case with siuCaseId linked to claimId When SIU sends status = "Accepted" with optional reasonCodes Then claim.siuStatus updates to "Accepted" And the SIU case status updates to "In Investigation" And the update is reflected in the claim within 60 seconds And the audit log captures inbound payload, timestamps, and reasonCodes Given an SIU case with siuCaseId linked to claimId When SIU sends status = "Declined" with reasonCodes Then claim.siuStatus updates to "Declined" And the claim is routed to the Screener queue within 60 seconds And the SIU case is marked "Declined" And no SIU-only tasks remain active on the claim And the audit log captures inbound payload, timestamps, and reasonCodes
Audit Trail and Artifact Capture
Given an SIU referral lifecycle occurs for a claim When referral is triggered, dossier generated, case created, queue notified, SIU accepted/declined, and any fallback routing executes Then an immutable audit entry is recorded for each event with fields: claimId, siuCaseId, eventType, ISO8601 timestamp, actor (system/user), reasonCodes (if any), and artifactReferences (documentIds, imageIds, checksums) And the audit log is queryable by claimId and siuCaseId and returns all entries in chronological order And exporting the audit for the claim returns exactly the set of recorded events with matching checksums for artifacts
Idempotency and Duplicate Prevention
Given multiple routing events for the same claimId with the same correlationId occur within 24 hours When the system processes these events Then exactly one SIU case exists for the correlationId And subsequent duplicate events are acknowledged and logged without creating additional SIU cases or dossiers Given a previously Declined SIU case for a claim And a new High-risk routing event occurs with a new correlationId When processed Then a new SIU case and dossier are created
Dossier Content Completeness and Traceability
Given a dossier is generated for an SIU referral When required data is assembled Then all required sections are present: claimSummary, nlpExtractedEntities, exposureEstimate, anomalyFlags, geoTimeInconsistencies, claimantHistory, policyHistory, attachments And each NLP-extracted entity includes a sourceReference (e.g., messageId, documentId, or imageId) And if any required field cannot be resolved, the field is present with value = null and missingDataReason populated And geoTimeInconsistencies includes both the reported and derived values used to determine inconsistency And attachments are included with filename, size, mimeType, checksum, and are downloadable
Fast-Track Automation
"As a claims manager, I want low-risk claims to be fast-tracked with controls so that honest claims are paid quickly without increasing leakage."
Description

For Low-risk tiers, automatically place claims on a fast-track path with pre-configured tasks, straight-through processing where permitted, and pre-approval up to configurable dollar thresholds. Enforce compliance gates by jurisdiction, generate a minimal document checklist, and perform random sampling for QA with easy pull-back if anomalies arise. Provide guardrails to halt fast-track on new red flags, and measure cycle-time, approval rates, and leakage indicators to continuously improve.

Acceptance Criteria
Auto-Assign Low-Risk Claims to Fast-Track
Given a claim is scored Low risk and the claim’s line of business and jurisdiction permit fast-track When the claim is ingested or re-scored Then the system assigns the Fast-Track workflow within 2 seconds And applies the Fast-Track task template matching the claim’s line of business, jurisdiction, and effective date, creating all tasks with correct owners, SLAs, and dependencies And sets claim processing status to "Fast-Track" and exposes it via UI and API And records an audit entry including rule ID, inputs (tier, jurisdiction, exposure), timestamp, and actor = system
Straight-Through Pre-Approval within Configured Thresholds
Given a Fast-Track claim with calculated payable amount less than or equal to the configured pre-approval threshold for its line of business and jurisdiction and all required compliance gates are satisfied When the payment decision is evaluated Then the system issues pre-approval automatically without human intervention And the pre-approval amount is less than or equal to the threshold and equals the calculated payable to the cent And the claimant and assigned adjuster are notified via the configured channel within 60 seconds And an auditable decision record is stored including threshold identifier, version, rules applied, amount, and artifact links Given the calculated payable exceeds the configured threshold When the payment decision is evaluated Then the system does not auto-approve and routes the claim to manual review
Jurisdictional Compliance Gates Enforcement
Given a Fast-Track claim When any required jurisdictional compliance check (e.g., identity verification, required notices, consent, sanctions/fraud watchlist) is incomplete or failed Then the claim cannot transition to Auto-Approval state And the UI and API return a blocking reason code with the specific unmet requirements Given all required checks are completed successfully and are within validity windows When the gate evaluation runs Then the gate is marked Passed and the claim can progress to the next step And each gate evaluation is versioned and stored with timestamp, inputs, outcome, and evaluator
Minimal Document Checklist Generation and Tracking
Given a claim is moved to Fast-Track When the document checklist is generated Then only documents tagged as minimal_required for the claim’s line of business and jurisdiction are included, and optional documents are excluded unless explicitly configured And the checklist is delivered to the claimant’s preferred channel within 60 seconds and is visible to the adjuster And each document request has a due date aligned to the Fast-Track SLA and an associated reason code And checklist completion status updates within 5 seconds of document receipt with 100% consistency to stored artifacts Given a document is marked not_applicable by configuration for the claim context When the checklist is generated Then that document is excluded
Random QA Sampling of Fast-Track Claims
Given a QA sampling rate R% configured for the claim’s line of business and jurisdiction When a claim is placed on Fast-Track Then the system selects the claim for QA with probability R% using a reproducible pseudo-random method with auditable daily seed And selected claims are routed to the QA queue before auto-approval and are excluded from straight-through processing until QA completes And an exclusion list prevents sampling of claims with tags that prohibit QA sampling (e.g., regulatory hold), with reasons logged And sampling logs include seed, claim ID, draw value, and selection outcome Given N ≥ 200 Fast-Track claims in a day When sampling is executed Then observed sample size is within R% ± 1% of N and variance is reported
Guardrails and Pull-Back on New Red Flags
Given a Fast-Track claim When new red flags are detected (e.g., SIU trigger, exposure update above threshold, model score crosses risk threshold, inconsistent metadata) Then the system halts Fast-Track processing within 5 seconds and reroutes the claim to the appropriate queue (Screener or SIU) based on configured rules And any in-flight auto-approval or payment jobs are canceled prior to execution and marked Aborted with a reason code And all stakeholders (assigned adjuster, team inbox) are notified within 60 seconds with details of the red flag And an audit record captures red flag type, source, prior state, new state, timestamp, and user/system actor Given an authorized user resolves or clears the red flag When they apply the Reinstate Fast-Track action Then the claim is returned to Fast-Track and prior completed steps are preserved
Performance and Outcome Metrics Collection
Given Fast-Track processing events occur When metrics ingestion runs (real-time stream or within 5 minutes of each event) Then the system records per-claim metrics: start/end timestamps, cycle time, gate outcomes, approval outcome, pre-approval amount, leakage indicator flags, QA sampling status, and jurisdiction And the metrics API and dashboard report aggregates (median cycle time, approval rate, leakage proxy = post-payment adjustment incidence) that reconcile to event logs within ±0.5% And metrics are filterable by line of business, jurisdiction, date range, and risk tier And exports are available as CSV via API with at least 24 months of retained data
Screener Triage Console
"As a screener, I want a streamlined triage console so that I can review and route medium-risk claims quickly and consistently."
Description

Deliver a dedicated console for medium-risk claims where screeners see a prioritized queue by risk and SLA, a compact claim card with key facts and suggested actions, and one-click routing (accept, escalate to SIU, or fast-track). Include filters, bulk actions, keyboard shortcuts, and inline notes with activity history. Ensure latency under 300 ms for queue refresh and emit decision events back to Route Orchestrator for closed-loop metrics.

Acceptance Criteria
Prioritized Medium-Risk Queue Ordering and Refresh Latency
- Given medium-risk claims with varying SLA remaining time and risk scores exist, When the Screener Triage Console loads or refreshes the queue, Then only medium-risk claims are displayed and ordered by SLA breach proximity ascending, then risk score descending, then claim created time ascending. - Given a manual refresh or server push update occurs, When the queue contains up to 100 visible items, Then the queue visually updates within 300 ms at p95 browser render time and the queue API responds within 200 ms at p95. - Given Route Orchestrator marks some claims as deferred due to team capacity, When the queue is displayed, Then deferred items are visually de-emphasized and always ranked below actionable items. - Given a new higher-priority medium-risk claim arrives, When the console receives the push event, Then the claim is inserted in correct order without full page reload and without moving the user’s current keyboard focus.
Compact Claim Card Key Facts and Suggested Actions
- Given a claim card is rendered, Then it displays: Claim ID, Insured Name, Loss Date, Line of Business, Jurisdiction, Exposure Amount, Risk Tier (Medium), SLA due timestamp with countdown, top extracted facts (up to 5), and a Suggested Action with confidence score. - Given any field is missing, When the card renders, Then the field shows a placeholder “—” and the layout does not shift. - Given the Suggested Action confidence is < 0.60, When the card renders, Then the Suggested Action is labeled “Review” and no action button is preselected. - Given the user interacts with the card, When clicking the Claim ID, Then the ID is copied to clipboard; When clicking “View details,” Then the full claim opens in a new tab.
One-Click Routing with Closed-Loop Event Emission
- Given a claim card is focused or selected, When the user triggers Accept, Escalate to SIU, or Fast-Track, Then the claim is routed and removed or updated in the queue within 1 second of the user action. - Given a routing action completes, Then an immutable activity entry is added with decision type, optional reason, user, and UTC timestamp. - Given a routing action is taken, Then a DecisionEvent is sent to Route Orchestrator containing claimId, decisionType [ACCEPT|ESCALATE_SIU|FAST_TRACK], userId, timestamp (UTC), optional reason, and suggestionConfidence; the console shows success on 2xx ack or retries up to 3 times with exponential backoff on failure and surfaces a non-blocking warning toast during retries. - Given the DecisionEvent is acknowledged, When metrics are queried from the orchestrator’s metrics endpoint, Then the corresponding counters update within 60 seconds, enabling closed-loop reporting.
Filtering by SLA, Line of Business, Jurisdiction, Team, and Suggestion
- Given the filter panel is opened, Then the user can filter by: SLA bucket [Overdue, <2h, Today, This Week], Line of Business, Jurisdiction, Team/Queue, Suggested Action [Accept, Escalate, Fast-Track, None], and free-text search on Claim ID or Insured Name. - Given one or more filters are applied, When the user changes any filter, Then the result set updates within 200 ms client-side and all filters are combined with AND logic. - Given filters are applied, Then the URL reflects current filters as query parameters so the state is shareable; clearing filters resets the URL. - Given no results match, Then the console displays a zero-state message and a “Clear filters” control.
Bulk Actions with Safeguards and Feedback
- Given the user selects 2–50 claims, When initiating a bulk Accept/Escalate/Fast-Track, Then a confirmation modal presents the action and count; confirming proceeds with the operation. - Given the bulk operation runs, Then eligible claims are processed and removed from the queue; ineligible or changed-state claims are skipped with a per-claim reason listed in the completion summary. - Given up to 50 claims are processed, Then the operation completes within 2 seconds at p95; progress is streamed and summarized with success/fail counts. - Given a bulk operation completes or partially fails, Then individual DecisionEvents are emitted per claim with a shared batchId for traceability.
Keyboard Shortcuts and Accessible Operation
- Given the console is focused, Then the following shortcuts perform actions: A=Accept, E=Escalate to SIU, F=Fast-Track, N=Add Note, R=Refresh Queue, ?=Show Shortcuts, Up/Down=Navigate, Space=Select/Deselect card, Enter=Open details. - Given a modal or text input has focus, When keys are pressed, Then shortcuts are suppressed to prevent unintended actions. - Given only keyboard input is used, When navigating and acting on claims, Then all functions are operable without a mouse and visible focus is maintained per WCAG 2.2 AA. - Given the user opens the shortcuts help, Then the overlay lists all shortcuts and can be dismissed with Esc.
Inline Notes and Activity History
- Given a claim card is open, When the user adds an inline note and submits, Then the note saves within 500 ms at p95 and appears at the top of the activity history with user, UTC timestamp, and content. - Given activity history is viewed, Then it shows chronological entries of notes and system events (decisions) with type icons and supports filtering by All, Notes, or Decisions. - Given a user attempts to edit or delete a note, Then the system prevents the action and displays a message that notes are immutable. - Given a history has more than 20 entries, When the user scrolls, Then the next page of 20 entries loads seamlessly (infinite scroll).
Routing Audit and Explainability
"As a compliance officer, I want full visibility into routing decisions so that we can demonstrate fairness, consistency, and regulatory compliance."
Description

Record every routing decision with inputs (score features, policy version, capacity snapshot), decision rationale, timestamps, and user overrides. Provide human-readable explanations for why a claim was routed to a team, searchable logs with retention controls, export to CSV/Parquet, and streaming to the data warehouse. Mask PII per role, maintain tamper-evident logs, and support regulator-ready reports showing tier thresholds, rule history, and outcomes over time.

Acceptance Criteria
Decision Audit Record Completeness
Given a claim is routed by the Route Orchestrator When the routing decision is persisted Then the audit record contains claim_id, correlation_id, routing_outcome (tier/team/queue), rationale_codes, rationale_text, score_features (name:value), rule_or_model_version, policy_version_id, capacity_snapshot, SLA_context, evaluated_at and persisted_at timestamps in ISO-8601 UTC, user_override_flag, and audit_id And if user_override_flag = true Then override_user_id, override_role, override_reason, override_timestamp, and previous_routing_outcome are present And the audit_id is immutable and writes are idempotent on correlation_id And the record validates against schema routing_audit_v1 And the record is retrievable by claim_id within 1 second at p95 for the last 30 days
Human-Readable Routing Explanation
Given a routed claim and a signed-in user with role permissions When the user opens the Routing Explanation view Then a human-readable summary shows the final routing outcome, top 5 contributing factors with weights and thresholds, and the active rule/model version at decision time And a "Why not" section explains why alternative routes (e.g., SIU, Fast-Track) were not selected when applicable And the explanation renders in under 500 ms at p95 And the explanation text contains no PII beyond what the user’s role is permitted to view
Log Search and Retention Controls
Given retention_policy for jurisdiction J is configured to 7 years and search filters are provided (claim_id, date_range, team, tier, user_id, decision_outcome, rule_version, rationale_code) When an authorized user performs a search Then results include only records matching the filters and the user’s data-access scope And results return within 2 seconds at p95 for up to 10,000 matched records And records older than the retention horizon are excluded from standard results and appear as tombstones to Compliance role And updates to retention_policy are versioned and auditable, and apply prospectively; retroactive changes require an explicit reindex job And search results honor role-based PII masking rules
Externalization: Export to CSV/Parquet and Stream to Warehouse
Given a date range and filters for routing audit records When Compliance initiates a CSV export Then the generated file uses UTF-8, comma delimiter, RFC 4180 escaping, ISO-8601 UTC timestamps, canonical header names, and row count equals matched records And PII columns are redacted or included based on the requester’s role and export policy When Parquet export is selected Then files are written with Snappy compression, schema routing_audit_v1, and partitioning by decision_date=YYYY-MM-DD Given a configured warehouse sink When new routing decisions are written Then events are streamed within 60 seconds p95 with at-least-once delivery, ordered per claim_id, with exponential backoff retries and dead-letter routing on repeated failures And schema evolution is backward-compatible and versioned in event metadata
Role-Based PII Masking and Unmasking
Given roles Adjuster, Screener, SIU, Compliance, and Admin with defined data-permissions When a non-privileged user views audit logs Then PII fields (e.g., SSN, bank_account, email, phone, address) are masked using irreversible format-preserving masking in UI, search results, exports, and streams And users with Unmask permission must provide a reason to request unmasking, receive time-bound access (<= 60 minutes), and the event is fully audited And attempts to export or stream unmasked PII are blocked unless the policy explicitly permits and the action is approved and logged
Tamper-Evident Logging and Integrity Verification
Given the append-only audit log store When records are appended Then each record includes a content hash and the previous record’s hash (per partition), forming a verifiable hash chain And any modification or deletion breaks chain verification and triggers an integrity alert within 5 minutes And WORM or append-only semantics are enforced for the configured retention period And a daily integrity verification job produces a signed checkpoint digest that can be independently validated by Compliance
Regulator-Ready Reporting on Tiers and Outcomes
Given a reporting period and jurisdiction When Compliance generates the regulator-ready report Then the report includes tier thresholds active by day, rule/model version history, counts and rates of routing outcomes, user and team override rates, and SLA adherence metrics And all figures reflect time-travel semantics using the rules, capacities, and policies as of decision time And the report exports to PDF and CSV within 2 minutes for up to 1,000,000 decisions and includes links to underlying audit records for traceability

Evidence Bundle

One-click, audit-ready SIU packet that assembles all supporting artifacts: anomaly rationale, cross-claim links, Proof Seal hashes, geofence checks, Timecode Anchors, and source images/docs. Exports to PDF/JSON or pushes to case systems, saving hours of manual compilation and strengthening case quality.

Requirements

One-Click Bundle Generation
"As an SIU investigator, I want to generate a complete evidence bundle with one click so that I can save hours of manual compilation and ensure every case is consistently documented."
Description

Assembles a complete, audit-ready SIU evidence packet from a claim with a single action. Automatically gathers and normalizes all supporting artifacts—anomaly rationale, cross-claim links, Proof Seal hashes, geofence checks, Timecode Anchors, and original source images/documents—into a consistent structure. Orders sections, applies standardized filenames and timestamps, deduplicates attachments, and embeds metadata for chain of custody. Supports on-demand creation from the claim detail view and bulk generation from SIU queues. Executes as an asynchronous job with a durable link to the final PDF/JSON outputs and packaged originals, ensuring repeatable, consistent results across cases.

Acceptance Criteria
On-Demand Generation from Claim Detail View
Given a claims manager or SIU analyst views an eligible claim in the Claim Detail view When they click "Generate Evidence Bundle" Then an asynchronous job is created and the UI shows an in-progress state within 1 second And the generation completes within 2 minutes for claims with ≤500 source assets and ≤50 anomalies And upon completion, durable links to PDF, JSON, and a packaged originals archive are visible in the claim within 1 second of job completion And an audit log event records user ID, claim ID, job ID, start/end timestamps (UTC), and outcome And the "Generate Evidence Bundle" action is disabled while a job for the same claim is running
Bulk Generation from SIU Queue
Given an SIU analyst selects 10–200 claims in the SIU queue When they trigger "Generate Evidence Bundles" Then the system enqueues one job per claim and a batch ID is created And the batch progress view shows counts for queued, running, completed, failed updated at least every 5 seconds And successful jobs produce durable links per claim; failed jobs do not block others And each failed job is retried up to 3 times with exponential backoff starting at 30 seconds And the system achieves a throughput of at least 30 completed bundles per hour for claims with ≤500 assets each
Artifact Completeness and Ordering
Given a claim contains anomaly rationale, cross-claim links, Proof Seal hashes, geofence checks, Timecode Anchors, and source images/documents When an evidence bundle is generated Then the output PDF and JSON include a section for each artifact category present And if a category is absent, the section header is present with value "None" And section order is Summary, Anomalies, Cross-Claim Links, Geofence Checks, Timecode Anchors, Proof Seals, Source Artifacts, Appendices And the JSON mirrors this order under top-level keys And every source artifact referenced in the claim is included exactly once in the originals package
Deduplication and Normalization of Attachments
Given a claim contains duplicate source artifacts by identical Proof Seal hash or by identical content SHA-256 When an evidence bundle is generated Then duplicates are included only once in the originals package and referenced once in PDF/JSON And the kept copy is the highest-resolution version when duplicates differ in resolution And standardized filenames use the pattern {section-order}_{section-slug}_{index}_{timestamp-UTC} And all timestamps in filenames and metadata are ISO 8601 UTC (YYYY-MM-DDThh:mm:ssZ)
Chain of Custody Metadata and Proof Seal Integrity
Given an evidence bundle generation job completes When the outputs are inspected Then the PDF XMP metadata and JSON include generator version, claim ID, job ID, generatedAt (UTC), operator user ID, and hashing algorithm And each included file has a recorded SHA-256 hash and byte size in the manifest And recalculating hashes over the outputs matches the recorded values And the Proof Seal hashes listed for artifacts match those stored on the claim without deviation
Asynchronous Job Lifecycle and Durable Links
Given an evidence bundle job exists When the job status API is polled Then the job surfaces states: queued, running, completed, failed And progress percent is available while running And durable links remain accessible for at least 180 days unless explicitly revoked And links require authentication and are bound to claim and job IDs And re-requesting a durable link after revocation returns 403
Repeatability and Consistency Across Runs
Given no changes are made to a claim between two bundle generations When two evidence bundles are generated sequentially Then the JSON manifest includes a deterministicContentHash that is identical across runs And per-artifact SHA-256 values are identical across runs And PDF and archive outputs contain the same ordered content; only the generatedAt timestamp may differ And re-running with the same job parameters produces idempotent results without duplicate jobs
Template Configuration & Branding
"As a compliance lead, I want to configure bundle templates and branding so that our evidence packets meet regulatory requirements and internal guidelines across jurisdictions."
Description

Provides a configurable template engine for PDF and JSON outputs, enabling conditional sections, jurisdiction-specific disclosures, and carrier/MGA branding. Allows admins to define layout elements (cover page, table of contents, exhibits), map claim fields to template placeholders, and include/exclude artifacts based on line of business, loss type, and SIU rule triggers. Supports localization (dates, units, currencies), custom watermarks, and footers, ensuring the bundle meets regulatory and internal documentation standards without developer changes.

Acceptance Criteria
Jurisdiction-Specific Disclosures in PDF
Given an active template "SIU Packet v1" with a disclosure block id "NY_Fraud_Warning" set to appear when claim.jurisdiction = "NY" And the same block is set to be hidden otherwise When a claim with jurisdiction "NY" is exported to PDF Then the PDF includes the disclosure block "NY_Fraud_Warning" at the configured section position And the block version and rule id are recorded in the export metadata When a claim with jurisdiction "NJ" is exported to PDF Then the PDF does not include the disclosure block "NY_Fraud_Warning"
Artifact Inclusion Rules by Line of Business and SIU Triggers
Given template rules: - Include "Geofence Check" section when siuTriggers contains "geofence_mismatch" - Include "Proof Seal Hashes" section when artifacts.proofSeal.hashes exists - Include "Cross-Claim Links" section when relatedClaims.length > 0 When exporting claim A (Auto) with siuTriggers ["geofence_mismatch"], artifacts.proofSeal.hashes present, and two related claims Then the PDF includes sections "Geofence Check", "Proof Seal Hashes", and "Cross-Claim Links" When exporting claim B (Property) with no relevant triggers and no related claims Then the PDF omits those sections And the table of contents lists only included sections with correct page numbers
Field Mapping to Template Placeholders and Validation
Given an admin maps placeholders: - {{claim.number}} -> claim.number - {{loss.date}} -> loss.date - {{insured.name}} -> insured.fullName And sets default value "[MISSING]" for unmapped placeholders When exporting a claim with all three fields populated Then the PDF cover shows the exact values for claim.number, loss.date, and insured.fullName in the mapped positions When a template contains an unmapped placeholder {{adjuster.phone}} Then the template validator blocks publish with an error listing the unmapped key When the admin assigns default "[MISSING]" for {{adjuster.phone}} and republishes Then the export succeeds and renders "[MISSING]" where data is absent
Branding, Watermarks, and Footers by Carrier/MGA
Given brand "Acme MGA" with assets: - Logo: acme_logo.png - Watermark text: "CONFIDENTIAL" - Footer: "Acme MGA | Claim {{claim.number}} | Page {{page}} of {{pages}}" And the template selects brand "Acme MGA" When exporting a claim for tenant "Acme MGA" Then the PDF cover displays the logo in the header area with preserved aspect ratio And each page shows the watermark at 10–15% opacity behind content And the footer renders the dynamic fields with correct values on every page And switching the template brand to another tenant updates logo, watermark, and footer without a deployment or service restart
Localization of Dates, Units, and Currencies
Given locale-aware formatting is enabled and the template sets date patterns: - en-US: MM/DD/YYYY - en-GB: DD/MM/YYYY - fr-CA: YYYY-MM-DD And tenant locale mappings are configured: US -> en-US, UK -> en-GB, Quebec -> fr-CA When exporting a US claim with loss.date = 2025-02-07, reserve = 1234.5 USD, and speed = 60 mph Then the PDF shows "02/07/2025", "$1,234.50", and "60 mph" When exporting a UK claim with loss.date = 2025-02-07, reserve = 1234.5 GBP, and speed = 96.56 km/h Then the PDF shows "07/02/2025", "£1,234.50", and "96.6 km/h" When exporting a Quebec claim with loss.date = 2025-02-07, reserve = 1234.5 CAD, and metric units enabled Then the PDF shows "2025-02-07", "1 234,50 $ CA", and metric units
JSON Export Template and Schema Compliance
Given a JSON template "SIU_Packet_JSON v1" with optional blocks "proofSeal", "geofenceCheck", and "timecodeAnchors" And a JSON Schema v1.0 for EvidenceBundle is configured When exporting a claim where only "timecodeAnchors" is present Then the JSON output includes a "timecodeAnchors" array with the configured fields And omits the keys "proofSeal" and "geofenceCheck" entirely And the output validates against the schema with zero errors And field names match the configured mapping exactly (case-sensitive) When exporting a claim with all three blocks present Then all three blocks are included and validate against the schema
Layout: Cover Page, Table of Contents, and Exhibits
Given the template defines a cover page, an auto-generated Table of Contents, and an Exhibits section that lists included source images/docs with captions and labels (Exhibit A, Exhibit B, ...) When exporting a claim with 3 included artifacts and 1 excluded by rule Then the PDF paginates the bundle and generates the TOC And the TOC lists only included sections and exhibits with correct page numbers And exhibits are labeled sequentially and display captions from artifact metadata And page numbers in the footer are continuous across the entire bundle
Cryptographic Proof Seal & Tamper Evidence
"As an SIU analyst, I want cryptographic seals on the bundle and its artifacts so that I can prove the evidence has not been altered during audits or litigation."
Description

Generates a tamper-evident manifest for every bundle, computing per-artifact SHA-256 hashes and a bundle-level Merkle root embedded into the PDF and JSON. Includes a timestamp, signer identity, and a scannable QR/link to a verification endpoint. Optionally requests RFC 3161-compatible trusted timestamps or platform key signing. Produces a machine-readable verification JSON and a human-readable integrity report, enabling courts and auditors to independently validate that images, documents, locations (geofence checks), and Timecode Anchors have not been altered since bundling.

Acceptance Criteria
Tamper-Evident Manifest with Per-Artifact SHA-256 and Merkle Root
Given an Evidence Bundle containing artifacts (images, documents) and metadata items (geofence checks, Timecode Anchors) When the bundle is generated Then a manifest is created that lists every item with stable itemId, type, byteLength, and SHA-256 hash (hex) And the manifest includes a bundle-level Merkle root computed from the ordered list of item hashes using SHA-256, duplicating the last node when the level has an odd count And the manifest records createdAt (UTC ISO 8601 Z), hashAlgorithm=SHA-256, sealVersion, signer identity, and product version And the Merkle root is deterministic for identical input across runs And the manifest is persisted with the bundle and included in all exports
Proof Seal Embedded in PDF Export
Given a generated manifest and Merkle root When the bundle is exported to PDF Then the PDF contains a visible Proof Seal summary page showing merkleRootHex, createdAt, and signer identity And the PDF XMP metadata embeds the full manifest JSON and signature/timestamp blocks when present And the first page displays a QR code encoding an HTTPS verification URL with bundleId and merkleRootHex And scanning the QR from a mobile device opens the verification URL and loads within 3 seconds on broadband And the embedded manifest in the PDF matches the stored manifest byte-for-byte
Proof Seal Embedded in JSON Export
Given a generated manifest and Merkle root When the bundle is exported to JSON Then the JSON contains a top-level proofSeal object with fields: version, createdAt, signer, hashAlgorithm=SHA-256, merkleRootHex, itemHashes[], canonicalizationRules And the JSON is emitted using the declared canonicalization rules (UTF-8, LF, sorted keys, no insignificant whitespace) used for hashing And merkleRootHex equals the computed Merkle root And a verification block is included that enables offline validation without server access
Public Verification Endpoint and QR/Link Validation
Given a sealed bundle with a verification URL/QR When the verification URL is requested Then the endpoint responds HTTP 200 with JSON containing: verdict ∈ {valid, invalid}, merkleRootHex, checkedAt, inputs, mismatches[], message And when no bundle is found, the endpoint returns HTTP 404 with a machine-readable error code And when tampering is detected, verdict=invalid and mismatches enumerate itemIds with expectedHash vs actualHash And the endpoint supports CORS and responds within 1500 ms p95 under nominal load
RFC 3161 Trusted Timestamp Option
Given TSA integration is enabled and reachable When a bundle is sealed Then an RFC 3161 timestamp is requested over the Merkle root And on success, the returned TimeStampToken (DER base64) is embedded in the manifest and exports And the verification endpoint validates the token chain to the configured trust anchor and reports tsaVerified=true And if the TSA is unavailable or errors, sealing completes without a token and the report sets tsaVerified=false with reason
Platform Key Signing Option
Given platform key signing is enabled and a private key exists in the configured keystore/HSM When a bundle is sealed Then the system signs the Merkle root and manifest using SHA-256 with RSA or ECDSA, recording algorithm and key fingerprint And the signature is embedded in PDF XMP and JSON proofSeal.signature And the verification endpoint validates the signature chain to a configured certificate and reports signatureVerified=true And if the key is unavailable or invalid, sealing fails with a clear error and no exports are produced
Tamper Detection Across Artifacts, Geofence Checks, and Timecode Anchors
Given a sealed bundle When any artifact, geofence check output, or Timecode Anchor is modified, deleted, added, or reordered Then recomputed hashes produce a different Merkle root and verification returns verdict=invalid And the integrity report highlights the specific items with status=Fail and shows expectedHash vs actualHash And unmodified items are reported as Pass And the PDF export displays a visible red integrity warning banner when invalid
External Case System Push
"As an SIU operations lead, I want evidence bundles to auto-sync to our case management system so that investigators can begin work immediately without manual uploads."
Description

Delivers generated bundles and their artifacts directly into external SIU/case management systems via REST, SFTP, or message queues. Supports OAuth2/API key auth, field mapping, idempotency keys, delivery receipts, and configurable routing per carrier or line of business. Implements retries with exponential backoff, poison-queue handling, and attachment chunking for large media. Provides success/failure callbacks and updates claim notes with destination IDs, eliminating manual uploads and accelerating investigator handoffs.

Acceptance Criteria
REST Push with OAuth2/API Key and Field Mapping
Given a finalized Evidence Bundle for claim CF-123 under carrier profile "CarrierA-REST-v1" with configured REST endpoint, field mapping, and auth And the profile specifies OAuth2 client credentials or API Key auth When ClaimFlow pushes the bundle via REST Then the request includes the required Authorization header (Bearer <token> for OAuth2 or Api-Key <key> for API key) according to the profile And the JSON payload fields map exactly to the configured schema, with required fields present and data types validated And all bundle artifacts (anomaly rationale, cross-claim links, Proof Seal hashes, geofence checks, Timecode Anchors, and source images/docs) are included per mapping And a delivery receipt with a destination caseId is returned within 30 seconds And ClaimFlow records the destination caseId and receipt timestamp in claim notes and marks delivery status "Delivered"
Idempotent Re-push on Network Timeout
Given a prior REST push attempt for claim CF-124 used idempotency key "abc123" and timed out before receipt When the same bundle is re-pushed with the same idempotency key within 24 hours Then the external system must not create a duplicate case And the response echoes the original destination caseId And ClaimFlow stores a single delivery record linked to that idempotency key and logs the second attempt as "Deduplicated"
Exponential Backoff Retries and Poison Queue Handling
Given the external endpoint returns HTTP 5xx on push attempts When ClaimFlow retries with exponential backoff starting at 1 minute, doubling each attempt, capped at 15 minutes, for a maximum of 6 attempts Then after 6 consecutive failures the delivery is moved to the poison queue with the last error code and response body captured And an alert is emitted to the SIU integrations channel with correlationId and route details And the delivery status is set to "Failed-RoutedToPoison" And operators can trigger a single-click replay from the poison queue that reuses the original idempotency key
Attachment Chunking for Large Media over REST
Given the bundle includes a 450 MB MP4 artifact and the chunk size is configured to 10 MB When ClaimFlow pushes the attachment via REST Then the system uploads 45 ordered chunks each with a SHA-256 checksum and sequence index headers And only failed chunks are retried on transient errors And upon server reassembly acknowledgment the end-to-end checksum matches the original file And the delivery receipt includes the artifactId and totalChunks count
SFTP Delivery with Manifests and Receipts
Given the route for carrier "CarrierA-Auto" is configured for SFTP delivery to sftp.example.com:/ingest/siu When ClaimFlow pushes the bundle Then a new remote folder named with the correlationId is created And files bundle.json, bundle.pdf, and all artifacts are uploaded And a manifest.json containing filenames, byte sizes, and SHA-256 checksums is uploaded last And a done.marker file is placed after all uploads complete And ClaimFlow verifies remote file presence and sizes, records the remote path in claim notes, and sets delivery status "Delivered"
Message Queue Delivery with Callback and Correlation
Given the route for carrier "CarrierB-Commercial" is configured for message queue delivery to topic "siu.evidence" When ClaimFlow publishes the bundle message Then the message includes correlationId, idempotencyKey, routing metadata (carrier, LoB), and URIs for large artifacts in object storage And the broker acknowledges with a messageId And ClaimFlow records messageId in claim notes and sets delivery status "Published" When a success or failure callback is received on the configured webhook within the 15-minute TTL with the correlationId Then ClaimFlow updates the delivery status to "Delivered" or "Failed" accordingly and appends the destination caseId or error detail to claim notes And if no callback arrives within the TTL, set status to "Pending-Callback-Timeout" and surface a retry action
Configurable Routing by Carrier and Line of Business
Given routing rules are configured: CarrierA-Homeowners->REST profile A, CarrierA-Auto->SFTP profile B, CarrierB-Commercial->MQ profile C When three bundles for corresponding claims are pushed Then each bundle is sent via its configured channel and profile And routing decisions are logged with ruleId and evaluated attributes And no bundle is sent to a non-matching endpoint And if a rule is missing required configuration, the push is blocked with "Configuration Error" status and no data is transmitted
Redaction & Privacy Controls
"As a privacy officer, I want sensitive information automatically redacted in evidence bundles so that we comply with privacy regulations while sharing case materials externally."
Description

Applies rule-based redaction to PII/PHI and sensitive business data across text, images, and PDFs before packaging or export. Supports configurable profiles by jurisdiction and recipient (e.g., external counsel, NICB), selective artifact inclusion, and automatic watermarking. Enforces role-based access to unredacted originals, logs access events, and sets link expirations for shared downloads. Ensures compliance while preserving investigative value with clear annotations indicating where and why redactions occurred.

Acceptance Criteria
Jurisdiction Profile Redaction on Export
Given a claim file containing PII/PHI in notes, images, and PDFs And a redaction profile "CA-ExternalCounsel" with rules R-PII-*, R-PHI-*, R-TradeSecret-CA When a user exports an Evidence Bundle to PDF and JSON with profile "CA-ExternalCounsel" Then all content matching the profile rules is redacted across all artifact types And unredacted originals are excluded from the export artifacts and manifests And each redaction is annotated with rule_id, category, jurisdiction, and confidence And a Redaction Summary page is appended listing categories, counts, and rules applied And the export completes within 90 seconds for bundles <= 200 MB
Recipient-Specific Selective Artifact Inclusion
Given an export dialog with selectable artifacts and a recipient profile "NICB" When the user selects specific artifacts and initiates export to NICB Then only the selected artifacts are included in the export And profile-specific fields are filtered to the NICB allowlist And redaction is applied before packaging And the manifest explicitly lists included and excluded artifacts with reasons And no references to excluded artifacts remain in the bundle And the JSON push to the case system returns HTTP 202 with a bundle_id
Role-Based Access to Unredacted Originals
Given roles SIU Lead and System Admin have permission VIEW_UNREDACTED and others do not When a user without VIEW_UNREDACTED attempts to view or download unredacted artifacts Then the system serves only redacted versions and displays a lock indicator And the attempt is logged with user_id, artifact_id, timestamp, ip, outcome=denied And unredacted download links are not generated and APIs return HTTP 403 When a user with VIEW_UNREDACTED views or downloads an unredacted artifact Then the access is logged with user_id, artifact_id, timestamp, ip, outcome=granted, purpose And a user-specific watermark is applied to viewed/downloaded unredacted content
Expiring Shared Download Links
Given a generated shared download link with ttl=72h and one_time_use=true When the link is accessed within 72 hours for the first time Then the bundle downloads successfully and the access is logged When the link is accessed a second time or after 72 hours Then the system returns HTTP 410 Gone and no content is served And authorized users can revoke the link, after which any access returns HTTP 410 And the link metadata displays creation_time, expiry_time, and remaining uses
Automatic Watermarking on Redacted Exports
Given a redacted bundle export for an external recipient When the export is generated Then each PDF page and image contains a non-removable watermark with case_id, recipient, timestamp, and 'REDACTED' And text-only documents include header and footer watermarks with the same metadata And the watermark opacity maintains legibility of content (alpha between 10% and 20%) And a SHA-256 hash of the final redacted bundle is computed and included in the manifest as proof_seal
Image and Metadata Redaction Coverage
Given images containing faces, license plates, addresses, and paper documents, and images with EXIF metadata When the redaction engine runs with a standard external profile Then detected PII regions (faces, plates, addresses) are fully occluded with solid fill and cannot be reversed And redactions also remove PII from embedded metadata (EXIF, XMP) and thumbnails And on a curated test set of 500 images, detection meets or exceeds 95% recall and 98% precision for target entities And manual review UI supports adding or removing redaction regions, with changes reflected in the export and audit log
Context-Preserving Masking and Annotations
Given documents and messages containing sensitive fields (SSN, phone, email, policy number) When a redacted export is generated with a context-preserving profile Then masking preserves allowed portions (e.g., last 4 digits of SSN, domain of email) per profile rules And each masked field is annotated inline with [REDACTED:<category>:<rule_id>] And the JSON export includes a redaction_map with offsets/coordinates, category, rule_id, and confidence for each redaction And manual overrides (unredact/redact) require a reason and are recorded with user_id, timestamp, rule_id_override in the audit log
Cross-Claim Linkage & Rationale Trace
"As an SIU reviewer, I want transparent cross-claim links and rationale within the bundle so that I can quickly validate why the claim was flagged and what evidence supports the decision."
Description

Aggregates and explains cross-claim relationships discovered by the NLP and entity resolution engine, presenting a compact graph of linked claims, shared entities, time/place overlaps, and recurrence patterns. Captures rationale narratives for anomaly flags, cites source messages/images with anchors, and references geofence checks and Timecode Anchors that support or refute hypotheses. Includes confidence scores, suppression notes for false positives, and clear exhibits, enabling rapid triage and defensible SIU decisions.

Acceptance Criteria
Cross-Claim Graph Composition & Accuracy
Given a claim with 3 or more cross-claim links returned by the NLP/entity-resolution engine When the Cross-Claim view is generated for the claim Then a compact graph is displayed containing nodes for the current claim, each linked claim, and each shared entity (person, vehicle, address, phone, email) And edges are labeled with relationship type (shared-entity, time-overlap, geo-overlap, recurrence) and show confidence to 2 decimal places And the number of linked-claim nodes equals the engine’s link count for the claim And each shared-entity node lists the normalized entity identifier and source count And a recurrence pattern badge appears when 3+ linked claims share the same entity or location within a 180-day window And the graph renders within 2 seconds for datasets up to 50 links
Anomaly Flag Rationale with Source Anchors
Given an anomaly flag on a cross-claim relationship When the rationale panel is opened Then a prose rationale is shown between 50 and 1000 characters And at least one supporting citation is listed with a clickable anchor to the exact message timestamp or image region (Timecode Anchor) And citations include source type, sourceId, ISO 8601 timestamp, and Proof Seal hash reference And any geofence check involved is displayed with verdict (Pass/Fail), distance in meters, and threshold used And the rationale explicitly states the hypothesis and whether evidence supports or refutes it
Confidence Scoring, Ordering, and Threshold Filtering
Given a claim with multiple cross-claim links each with a computed confidence in [0,1] When the links panel is loaded Then links are sorted by confidence descending by default And each link displays its score with 2 decimal places and a tooltip explaining contributing factors with weights totaling 100% And a threshold control allows filtering to a minimum confidence with step 0.05 And adjusting the threshold updates the list and graph within 500 ms
False-Positive Suppression with Audit Trail
Given a user with SIU role permissions When the user marks a link or entity as a false positive Then a required reason field (minimum 15 characters) and scope selection (this claim only / all claims) must be provided And upon save, the item is hidden from default views and an audit record is created capturing user, UTC timestamp, scope, and reason And a "Show suppressed" toggle reveals suppressed items with a suppression badge and allows unsuppress with audit logging And suppressed items are excluded from exports by default unless "Include suppressed" is selected in export options
Evidence Bundle Export of Cross-Claim Exhibits
Given a claim with cross-claim graph, rationales, geofence checks, Timecode Anchors, confidence scores, and suppression notes When the Evidence Bundle is exported to PDF and JSON and pushed to a configured case system Then the PDF includes a legible graph exhibit (A4/Letter), a legend, numbered exhibits, and cross-references to citations And the JSON includes for each link: linkId, claimIds, entityIds, relationshipTypes, confidence, rationale, citations[], geofenceCheck, timecodeAnchors[], suppression[] And the JSON includes schemaVersion and validates against the published schema And all embedded Proof Seal hashes match recomputed values And export/push completes within 10 seconds for up to 50 links without broken anchors or missing assets
Geofence and Timecode Anchor Evidence Trace
Given two events linked by location and time When geofence checks are evaluated Then results include coordinates (lat/long to 5 decimal places), distance in meters, threshold in meters, withinGeofence boolean, and a map snapshot identifier And if distance <= threshold, the verdict is Pass; otherwise Fail When Timecode Anchors are resolved for source artifacts Then each anchor records sourceId, original timezone, normalized UTC timestamp, and confidence And time deltas between events are displayed; if delta <= 2 hours, a "near-simultaneous" badge is shown And if conflicting timestamps differ by more than 5 minutes across sources, a conflict note is displayed with both values and the selected canonical source
Generation Status, Retry & Observability
"As a claims platform administrator, I want real-time visibility and control over bundle generation so that I can troubleshoot issues quickly and maintain SLA commitments."
Description

Tracks the full lifecycle of bundle generation with job states, progress indicators, and SLA timers. Surfaces structured logs, artifact-level errors, and partial-completion fallbacks with clear flags in the output. Exposes metrics (success rates, durations, sizes), alerting for repeated failures, and per-tenant dashboards. Provides admin tools to retry, resume, or cancel jobs and automatically rehydrate missing artifacts when sources become available, ensuring reliable operations at scale.

Acceptance Criteria
Lifecycle States & Progress Visibility
Given a new evidence bundle request is submitted, When the job is accepted by the system, Then the job state is set to "queued" with created_at timestamp and SLA_due_at displayed. Given a queued job is picked by a worker, When processing starts, Then state becomes "running" with started_at timestamp and progress between 1–99% updated at least every 5 seconds. Given processing completes all artifacts without error, When finalization finishes, Then state = "completed", progress = 100%, finished_at is set, and duration is calculated. Given a recoverable error occurs for an artifact, When retries remain, Then state shows "retrying" with attempt count and next_attempt_at. Given a fatal error aborts the job, When no fallbacks are applicable, Then state = "failed" with reason code and human-readable message. Given an authorized admin cancels a running job, When cancellation succeeds, Then state = "canceled" with canceled_by and canceled_at recorded.
SLA Timers & Breach Alerts
Given tenant SLA is configured (e.g., 10 minutes), When a job starts, Then SLA_due_at is calculated and displayed. Given remaining SLA time drops below 20%, When the job is not yet completed, Then a "SLA at risk" flag is set and an alert is sent to configured channels within 60 seconds. Given SLA_due_at is exceeded, When the job is still not completed, Then the job is marked "SLA breached" and an alert is sent with job_id, tenant_id, and elapsed time. Given SLA is breached but job completes later, When completion occurs, Then final status retains "completed" with an SLA_breached=true flag for reporting.
Structured Logs & Artifact-Level Errors
Given a job_id, When viewing logs, Then logs are filterable by job_id, tenant_id, artifact_id, severity, and time window. Given an artifact fails to generate, When inspecting job details, Then the artifact entry shows error code, message, stack trace reference, and correlation_id. Given PII exists in source artifacts, When logs are emitted, Then PII is redacted per policy with placeholders and no raw PII stored. Given a user exports logs for a job, When export is requested, Then a JSONL file is generated within 60 seconds containing only the tenant's data.
Partial Completion Fallbacks & Output Flags
Given at least one artifact fails and others succeed, When finalization runs, Then a bundle is produced with partial=true and a list of missing_artifacts with reason codes. Given partial completion, When the bundle is exported to PDF and JSON, Then both formats include visible flags and sections indicating unavailable artifacts and suggested next actions. Given partial completion, When consumers ingest the JSON output, Then schema fields include completion_status, missing_artifacts[], and errors[] adhering to the published schema version.
Admin Retry, Resume, and Cancel Controls
Given a user with role "Claims Admin", When they trigger a retry on a failed job, Then a new attempt is enqueued with attempt count incremented and audit entry {who, when, why}. Given a job supports resume, When resume is invoked, Then processing restarts from the last successful checkpoint without duplicating already completed artifacts. Given a job is running, When cancel is requested, Then the system stops new work within 10 seconds and marks in-flight tasks as canceled safely. Given maximum retries is configured (e.g., 3), When retries exceed the limit, Then the job remains failed and an alert is sent with failure reason and retry summary.
Automatic Rehydration of Missing Artifacts
Given a job completed partially due to unavailable sources, When the missing source becomes available within 24 hours, Then the system automatically rehydrates the artifact and updates the bundle version with a new artifact appended. Given automatic rehydration occurs, When updates are applied, Then stakeholders are notified and the bundle's change log records previous and new artifact hashes. Given rehydration fails, When retries are exhausted, Then the job status remains completed(partial) and an error record is attached to the missing artifact with reason codes.
Metrics, Dashboards, and Failure Alerting
Given per-tenant metrics are enabled, When viewing the dashboard, Then success rate, failure rate, P50/P95/P99 durations, average bundle size, and artifact breakdown are displayed for the selected time window. Given repeated failures for a tenant exceed a threshold (e.g., 5 failures in 10 minutes), When the condition is met, Then an alert is emitted to the tenant’s channels and an incident is created with top error codes. Given metrics are exported, When the telemetry sink is reachable, Then metrics are pushed every 60 seconds with tags {tenant_id, region, version}. Given a release is deployed, When comparing before/after, Then the dashboard supports version filtering to visualize regressions in success rate and latency.

Outcome Trainer

Closed-loop learning that ingests SIU outcomes (confirmed fraud, cleared, recoveries) and analyst feedback to auto-tune rules, refresh thresholds, and flag model drift. Recommends new triggers based on recent patterns, steadily reducing false positives and catching novel fraud faster.

Requirements

SIU Outcome Ingestion Pipeline
"As a fraud operations lead, I want SIU outcomes automatically ingested and linked to prior alerts so that the system can learn from final determinations and improve future detection."
Description

Build a robust, near-real-time ingestion pipeline for SIU outcomes (confirmed fraud, cleared, recoveries, restitution amounts) with connectors to claims/SIU systems via API, webhook, and secure SFTP; normalize payloads, validate schema, deduplicate, and join to ClaimFlow claims and alerts using deterministic and fuzzy keys; support historical backfill, idempotent reprocessing, and PII-safe storage with configurable retention; emit data quality metrics and dead-letter queues; expose a health dashboard and retry policies to ensure closed-loop ground truth is available to the tuning engines.

Acceptance Criteria
Near-Real-Time SIU Outcome Ingestion via API/Webhook/SFTP
Given connectors are configured with valid credentials and network allowlists When an SIU outcome is received via API or webhook Then p95 end-to-end latency to canonical outcomes store and Outcome Trainer stream is <= 2 minutes and p99 <= 5 minutes And malformed or unauthorized requests are rejected without ingestion and produce audit events And schema-valid requests receive HTTP 2xx within 2 seconds When a new outcome file is dropped to the SFTP watch folder Then polling detects the file within 5 minutes and file-to-availability p95 is <= 10 minutes And unreadable files are quarantined and their records routed to DLQ with reason codes
Schema Validation and Normalization
Given an outcome payload or file row When schema validation runs Then required fields are present: outcome_id, decision_timestamp, outcome_type; optional: case_id, claim_id, policy_number, claimant_name, restitution_amount, currency And types conform: outcome_id is UUIDv4; decision_timestamp is ISO 8601 UTC; outcome_type in {'confirmed_fraud','cleared','recovery'}; restitution_amount >= 0 numeric when present with ISO 4217 currency And normalization maps source fields to canonical keys, normalizes dates, trims strings, and standardizes currency And unknown extra fields are preserved under 'meta' without blocking ingestion And invalid records are rejected to DLQ with machine-readable error codes and human-readable messages; validation_error_rate metric increments
Idempotent Reprocessing and Deduplication
Given a duplicate delivery (same outcome_id) or same case_id+claim_id+outcome_type+decision_timestamp within 24 hours When the record is processed or reprocessed (including backfill reruns) Then exactly one canonical record exists for the logical outcome And reprocessing any 24-hour window produces no net-new duplicates And duplicates_filtered metric increments with the dedup reason captured And idempotency keys and dedup decisions are persisted to the audit log
Join Outcomes to ClaimFlow Claims and Alerts
Given an accepted outcome with a valid claim_id present in ClaimFlow When joining records Then the outcome links deterministically with confidence = 1.0 and stores claim_id and related alert_ids When claim_id is absent or unmapped Then a fuzzy match using policy_number, claimant_name, loss_date, and state is attempted And fuzzy matching achieves offline-evaluated precision >= 95% and recall >= 90% on a labeled validation set And outcomes with match_score < 0.85 or multiple candidates route to 'outcome_link_review' within 10 minutes And each link records match_method, match_score, keys_used, and timestamp for auditability
Historical Backfill without Disrupting Real-Time
Given a historical ingestion request specifying source and date range When backfill is executed Then sustained throughput is >= 2,000 outcomes per minute without exceeding configured quotas And real-time ingestion p95 latency degradation during backfill is <= 10% And progress and ETA are surfaced on the health dashboard and via API And backfill can be paused, resumed, and restarted idempotently without creating duplicates And backfilled outcomes appear in the canonical store and Outcome Trainer stream with original decision timestamps
PII-Safe Storage and Configurable Retention
Given PII-bearing fields and tenant retention policies When outcomes are persisted Then data is encrypted at rest (AES-256) and in transit (TLS 1.2+) And sensitive fields (SSN, DOB, email, phone) are tokenized or masked per policy; only minimum necessary PII is stored And default retention is 24 months and is configurable per tenant (30–84 months); expired data is purged within 24 hours of eligibility And purge jobs emit deletion audit records (outcome_id, timestamp) without PII And unauthorized access attempts to PII are denied and audited
Data Quality Metrics, Dead-Letter Queue, Health Dashboard, and Retries
Given pipeline operations When operational telemetry is emitted Then the system exposes metrics: ingestion_rate, end_to_end_latency_p95/p99, validation_error_rate, dedup_rate, join_success_rate, fuzzy_review_backlog, dlq_depth, retry_queue_depth, consumer_lag_outcome_trainer, last_success_timestamp And alert thresholds are configured (e.g., end_to_end_latency_p95 > 2m for 5 minutes = warning; > 5m = critical) And retries use exponential backoff (initial 30s, max 10m, max_attempts 6); after max attempts, messages move to DLQ And DLQ entries contain original payload, error_code, error_message, first_seen, last_seen, attempt_count and support filtered replay with >= 99% replay success And the health dashboard shows per-connector status (up/down), lag, throughput, error rates, DLQ depth, last heartbeat, and an aggregate status API returning 200 with component statuses And outcomes are published to the outcome_trainer.siu_outcomes.v1 stream with at-least-once delivery; ordering is preserved per claim_id partition; consumer acknowledgements confirm availability within SLA
Analyst Feedback Capture UX
"As an SIU analyst, I want a quick way to mark alerts as correct or false positives with reasons so that my feedback tunes the system without slowing my review."
Description

Provide an in-workflow feedback module within alert review that captures analyst dispositions (true positive, false positive, uncertain), rationale tags, free-text notes, and selected contextual attributes; enable bulk actions, keyboard shortcuts, and offline queuing to minimize friction; enforce a controlled taxonomy managed by admins; store structured feedback events with timestamps and reviewer IDs, protected by role-based access and audit trail; stream these labels into the training feature store for near-real-time learning.

Acceptance Criteria
Inline Feedback Capture on Alert Review Screen
Given an analyst is on the Alert Review screen and network is online When they open the Feedback panel from alert actions Then the panel opens inline within 1 second p95 without navigating away and pre-populates Alert ID and Claim ID as read-only fields Given the Feedback panel is open When the analyst submits valid feedback Then the panel closes, a success confirmation appears within 1 second, and the alert’s Feedback badge updates in the queue within 2 seconds p95 Given the Feedback panel is open When the analyst cancels Then no data is persisted and the panel closes
Validation and Controlled Values for Disposition, Rationale, Notes, and Context
Given the Feedback panel is open When the analyst attempts to submit Then validation enforces: disposition is required and one of {True Positive, False Positive, Uncertain}; for False Positive: ≥1 rationale tag required; for Uncertain: notes required with ≥10 characters; rationale tags must exist in the active admin taxonomy (max 5 tags); notes length 0–2000 chars with HTML/JS stripped and line breaks preserved; contextual attributes must be from the configured allowlist and match their declared types; invalid fields show inline errors and the Submit button remains disabled until resolved Given valid input When feedback is submitted Then the stored event includes: event_id (UUIDv4), alert_id, claim_id, disposition, rationale_tags[], notes, contextual_attributes{}, reviewer_id, reviewer_role, timestamp_utc (ISO-8601 ms), taxonomy_version, client_version
Bulk Feedback Actions from Alert Queue
Given the Alert Queue supports multi-select When the analyst selects 2–200 alerts and chooses Bulk Feedback Then a dialog appears to set shared disposition, rationale tags, and an optional note template supporting tokens {alert_id} and {claim_id} with a preview of N selected alerts Given valid bulk inputs When the analyst submits Then each alert receives a distinct feedback event atomically; the summary shows counts of succeeded and failed with per-alert error reasons; no alert is updated more than once; operations for 200 alerts complete within 30 seconds p95 Given transient failures When the analyst retries the bulk action Then idempotency prevents duplicate events for previously succeeded alerts
Keyboard Shortcuts for Rapid Feedback
Given the Feedback panel is focused When the analyst presses T, F, or U Then the disposition is set to True Positive, False Positive, or Uncertain respectively Given the Feedback panel is open When the analyst presses Alt+R Then focus moves to the rationale tags field Given required fields are valid When the analyst presses Ctrl+Enter Then the feedback is submitted Given the Feedback panel is open When the analyst presses Esc Then the panel closes without saving Given browser and OS defaults When shortcuts are active Then they do not override standard input behavior and are ignored while typing in text fields (except Ctrl+Enter) Given supported environments (latest 2 versions of Chrome and Edge on Windows and macOS) When shortcuts are used Then they function consistently and a Shift+? shortcut opens an in-app shortcut help overlay
Offline Feedback Queue with Auto-Retry and Deduplication
Given the device is offline or the API is unreachable When the analyst submits feedback Then the feedback is queued locally (encrypted at rest), visible in an Outbox with status Pending, and no error toast is shown Given queued items exist When network connectivity is restored Then items auto-retry with exponential backoff and are sent within 2 minutes p95 for ≤100 items; the UI updates each item to Sent on server acknowledgment Given intermittent connectivity When duplicate retries occur Then idempotency keys ensure exactly-once creation of feedback events; no duplicate events are stored Given queued items exceed 7 days When the user next opens the app Then the Outbox flags expired items with a discrete warning and allows Discard or Retry actions
Admin-Managed Taxonomy Enforcement and Versioning
Given an administrator publishes a taxonomy change (add, deprecate, rename mapping) When an analyst opens or refreshes the Feedback panel Then the updated taxonomy is available within 60 seconds without a full page reload; deprecated tags are hidden from selection but remain visible on historical events Given a non-admin user When they attempt to add or edit taxonomy entries Then the action is blocked with a 403 error and no changes occur Given feedback uses tags When the event is stored Then the taxonomy_version is recorded with the event and only tags from that version are accepted
Structured Storage, RBAC, Audit Trail, and Near-Real-Time Streaming
Given a valid feedback submission When it is processed Then the event is written immutably to storage within 2 seconds p95 with fields: event_id, alert_id, claim_id, disposition, rationale_tags[], notes, contextual_attributes{}, reviewer_id, reviewer_role, timestamp_utc, taxonomy_version, client_version Given a user attempts to modify an existing feedback event When they submit a change Then a new event is created with supersedes_event_id referencing the prior event; the prior event remains unchanged Given role-based access controls When a user without create permissions submits feedback Then the request is rejected with 403 and logged in the audit trail; authorized roles can create and read per policy Given events are accepted When they are streamed to the training feature store Then they appear within 2 minutes p95 and 5 minutes p99 with exactly-once delivery (idempotency key), correct schema mapping, and failures routed to a dead-letter queue with observable alerts if DLQ rate exceeds 0.1% over 15 minutes
Auto-Threshold Tuning Engine
"As a claims manager, I want thresholds to self-adjust to meet precision and volume targets so that my team focuses on the highest-value alerts."
Description

Implement an automated threshold optimizer that uses recent outcomes and analyst feedback to adjust alerting thresholds per product line, channel, geography, and time window; optimize to business objectives (maximize fraud capture subject to alert volume caps and minimum precision/recall guardrails) using Bayesian optimization with safety constraints; support canary rollouts, scheduled recalibration, change logs, and one-click rollback; publish explanations of threshold changes and projected impact on KPIs before activation.

Acceptance Criteria
Objective-Driven Threshold Optimization
Given labeled SIU outcomes and analyst feedback within the configured lookback window per segment, When the optimizer runs, Then it selects thresholds that maximize expected fraud capture subject to: (a) projected alert volume ≤ configured cap per segment, and (b) projected precision and recall ≥ configured guardrails per segment. And Then the optimizer outputs for each segment: chosen threshold values, objective score, constraint utilizations, projected KPIs with confidence intervals, and the training data window used. And Then no single threshold change exceeds the configured per-run step-size limit; proposals violating limits are rejected and logged.
Segmented Thresholding by Product, Channel, Geography, and Time Window
Given configured segmentation (product line, channel, geography, time window), When thresholds are updated, Then distinct thresholds are stored, versioned, and applied per segment. And Then for any segment with insufficient data, default fallback thresholds are applied, the fallback is logged, and stakeholders are notified. And Then decisioning requests reference the correct active threshold version for the request’s segment with added latency ≤ 50 ms at P95 and ≥ 99.99% availability.
Outcome and Analyst Feedback Ingestion and Weighting
Given SIU outcomes and analyst feedback arriving via batch and stream, When ingested, Then events are validated (required fields present), deduplicated, and matched to claims with a ≥ 99.9% successful match rate; unmatched events are queued for manual review. And Then feedback is incorporated using configurable weights and time decay; conflicting feedback is resolved by precedence rules and recorded. And Then if per-segment sample size < minimum N or data freshness > max age, optimization is skipped, thresholds remain unchanged, and notifications are sent with reason codes.
Bayesian Optimization with Safety Constraints
Given objective and constraint definitions, When optimization executes, Then a Bayesian optimizer with safety constraints is used, initializing priors from the last N runs and honoring exploration bounds. And Then runs are reproducible within tolerance using recorded random seeds and config hashes; results include convergence metrics and iteration counts. And Then if convergence criteria are not met within the iteration/time budget or safety constraints are infeasible, the system reverts to the last known good thresholds and logs a failure with diagnostics.
Canary Rollout, Monitoring, and One-Click Rollback
Given a candidate threshold set, When a canary rollout is started, Then a configurable percentage of traffic per segment is routed to the candidate with deterministic stickiness at claim/user level; the remainder uses the control thresholds. And Then gating metrics (alert rate, precision proxy, recall proxy, analyst handle time) are monitored in near real time; if any metric breaches control limits or alert caps, auto-rollback occurs within 60 seconds and alerts are sent. And Then an authorized user can trigger manual rollback in one click, restoring the previous thresholds portfolio-wide within 60 seconds and recording the action in the audit log.
Scheduled Recalibration and Governance
Given a configured schedule and freeze windows, When the schedule triggers, Then recalibration jobs execute automatically, skip during freeze windows, and run idempotently with safe retries on failure. And Then each run persists artifacts (dataset snapshot ID, configuration, random seed, optimizer outputs) with retention ≥ 18 months and access-controlled audit logs. And Then failures trigger exponential-backoff retries and on-call notifications with run IDs and failure reasons.
Pre-Activation Impact Preview and Change Log with Explanations
Given a proposed threshold change, When a user reviews it pre-activation, Then the system displays projected deltas for alert volume, precision, recall, and fraud captured with confidence intervals at segment and portfolio levels. And Then human-readable explanations of key drivers and trade-offs are provided, including which constraints are binding and why. And Then upon activation, a tamper-evident change log entry is created with who/when/what/why, diff from prior thresholds, projected vs. realized KPIs (once available), and a rollback link.
Rule Weight Optimization
"As a product owner, I want rule weights to be updated based on evidence while remaining interpretable so that detection improves without surprising stakeholders."
Description

Recalibrate rule weights and composite risk scores by learning from labeled outcomes, applying regularized logistic regression or gradient boosting with monotonicity and fairness constraints; generate weight updates and sensitivity analyses, validate in a shadow mode against a rolling holdout, and promote upon passing AUC/PR and business KPI gates; version every ruleset, maintain lineage to data cuts, and expose a diff view to explain weight changes to stakeholders.

Acceptance Criteria
Shadow Validation Against Rolling Holdout
Given a proposed ruleset version is available, When shadow mode is enabled, Then 100% of eligible new claims are dual-scored by candidate and production without altering routing decisions. Given the rolling 8-week holdout is defined, When nightly scoring completes, Then ≥99.5% of holdout claims have both scores persisted with timestamps and version IDs. Given shadow scoring runs, When errors occur, Then failure rate <0.1% per batch and alerts are emitted within 5 minutes; if failure rate ≥1% for 3 consecutive batches, Then shadow auto-disables and records incident. Given shadow mode is active, When users view claims, Then shadow indicators are visible only to admins and do not change SLAs or actions.
Monotonicity and Fairness Constraints Enforcement
Given monotonic directions are configured per rule, When training completes, Then learned weight signs comply with constraints and validation monotonic violations = 0. Given fairness constraints are configured for protected/proxy attributes, When evaluation runs, Then flag-rate disparate impact ratio between groups remains within 0.8–1.25 unless a documented waiver is attached. Given constraints are unsatisfiable, When training attempts, Then the run fails gracefully with a report of violating features and no weights are promoted.
Rule Weight Update Generation and Sensitivity Analysis
Given training is finalized, When the update package is built, Then it includes per-rule weight delta, 95% confidence intervals, feature importance, and partial dependence data in a versioned artifact. Given sensitivity analysis is executed, When analyzing the top 20 rules by importance, Then marginal score change per unit is computed and rules causing ≥5-point composite score change at 1 SD are flagged. Given a rule’s change would push >10% of claims across action thresholds, When the package is generated, Then the rule is marked "High Impact" and requires manual approval.
Ruleset Versioning and Data Lineage
Given a new ruleset is registered, When metadata is saved, Then a unique semantic version is assigned with code commit, data time window, feature schema hash, hyperparameters, constraints config, and random seed. Given auditors request lineage, When querying version N, Then dataset snapshot IDs and reproducible queries for train/validation/test splits are returned. Given rollback is initiated, When executed, Then the previous production version is restored within 5 minutes and all subsequent decisions log the correct version ID.
Diff View for Weight Changes and Stakeholder Explainability
Given two ruleset versions are selected, When Diff View loads, Then per-rule weight before/after, absolute/percent change, and direction are displayed with sortable columns. Given a rule’s weight change exceeds ±15% or flips sign, When rendering diffs, Then it is highlighted and accompanied by representative claim examples showing composite score impact. Given role-based access control, When a non-admin opens Diff View, Then sensitive training metrics are redacted and only summary deltas are shown.
Promotion Gates: AUC/PR and Business KPIs
Given shadow evaluation completes, When comparing candidate to baseline, Then AUC ≥ baseline + 0.01 and PR-AUC ≥ baseline + 0.01 on the rolling holdout are required to pass. Given business KPIs are evaluated, When holding precision fixed, Then recall increases by ≥5% or, when holding recall fixed, Then false positives decrease by ≥8% with no increase in average handling time. Given any gate fails, When promotion is attempted, Then promotion is blocked and a report details failing metrics and confidence intervals.
Outcome-Labeled Training Data Ingestion and Quality Checks
Given SIU outcomes and analyst feedback are ingested, When ETL merges labels to claims, Then ≥99.9% of records join successfully and mismatches <0.1% are flagged with reasons. Given label freshness policy is 90 days, When building the training set, Then only finalized outcomes within window are included and provisional labels are excluded. Given class imbalance is assessed, When exporting training data, Then positive rate and effective sample size are reported; if out of bounds, Then sampling/weighting is applied and logged in metadata.
Model Drift Detection and Alerting
"As a data science lead, I want automated drift detection with actionable alerts so that we can respond quickly before performance degrades."
Description

Continuously monitor feature distributions, risk score calibration, and outcome-based performance for data, concept, and performance drift; compute PSI/JS divergence, calibration curves, and rolling precision/recall, with dynamic baselines; surface drift dashboards, trigger alerts via email/Slack/PagerDuty when thresholds are breached, and automatically pause risky auto-tune actions while opening a ticket with diagnostics and suggested next steps.

Acceptance Criteria
Data Drift Detection via PSI/JS Divergence
Given feature monitoring is enabled with a 30-day rolling baseline and daily batches of at least 1,000 records When the PSI for any monitored feature exceeds 0.20 or the JS divergence exceeds 0.10 for two consecutive daily batches Then a Data Drift incident is created with severity Medium for PSI in [0.20, 0.30) and High for PSI >= 0.30 And the incident payload includes feature_name, psi, js_divergence, sample_size, baseline_window_start, baseline_window_end, detection_timestamp, and top_3_bucket_shifts And the Drift Dashboard displays the incident within 2 minutes of detection And the incident is persisted with a unique ID for audit
Dynamic Baseline Computation and Freeze on Incident
Given dynamic baselines are configured to refresh weekly using the most recent 30 days of clean data When the scheduled baseline refresh runs Then new baselines are computed and versioned with a timestamp and version_id And baseline changes are logged with per-feature summaries of central tendency and distribution deltas And if any Medium- or High-severity drift incident is open for a feature, the baseline refresh for that feature is skipped and rescheduled after the incident is resolved And the dashboard shows the active baseline version and next scheduled refresh time
Risk Score Calibration Drift Monitoring
Given labeled outcomes for the prior 14 days are available with at least 500 positive and 500 negative examples When Expected Calibration Error exceeds 0.03 or the Brier score worsens by more than 10% versus the 8-week baseline Then a Calibration Drift incident is created containing metrics (ECE, Brier, calibration_slope, calibration_intercept) and a reliability curve And the incident includes model_version, score_thresholds, sample_sizes, and observed_vs_predicted rates by decile And the Calibration panel on the dashboard updates within 5 minutes of label ingestion completion
Outcome Performance Drift via Rolling Precision/Recall
Given a rolling 7-day evaluation window at the production decision thresholds When recall decreases by more than 20% or precision decreases by more than 15% relative to the rolling 28-day baseline and a two-proportion z-test yields p < 0.05 Then a Performance Drift incident is created with metrics (precision, recall, F1, AUC_PR) and both absolute and relative deltas And the incident includes cohort breakdowns by line_of_business and geography when each cohort has at least 200 samples And the dashboard flags affected cohorts and links to confusion matrices for the current and baseline windows
Multi-Channel Alerting and Escalation
Given email, Slack, and PagerDuty channels are configured and enabled When any Medium- or High-severity drift incident is created Then an alert is delivered to all configured channels within 5 minutes containing incident_id, incident_type, severity, primary_metrics, thresholds, detection_time, and a deep link to the dashboard And delivery success or failure is logged per channel with timestamps And if the alert is not acknowledged within 15 minutes, a PagerDuty escalation is triggered to on-call level 2
Auto-Pause of Risky Auto-Tune Actions
Given Outcome Trainer auto-tune is enabled for rules and thresholds When a High-severity drift incident of type Data, Calibration, or Performance is opened Then pending auto-tune jobs are paused within 2 minutes and no new auto-tune changes are applied until the incident is resolved And a change-log entry is created noting the pause reason, incident_id, and impacted rules or thresholds And resuming auto-tune requires an explicit user action by a role of ML Admin or Risk Lead, with the action audited
Automatic Ticket Creation with Diagnostics and Recommendations
Given a ticketing integration is configured When any High-severity drift incident is created Then a ticket is automatically opened in the default queue within 5 minutes with title "[Drift][High] <type> - <primary_metric>" And the ticket includes links or attachments for: drift summary, affected features/models, metric tables, calibration or distribution plots, top contributing features, up to 100 sample records, and recommended next steps (e.g., retrain window, threshold rollback, feature review) And the ticket is assigned to the on-call group with a 24-hour triage SLA and is linked back to the incident
New Trigger Discovery Recommendations
"As an SIU strategist, I want the system to recommend new fraud triggers backed by evidence so that we can catch novel schemes faster."
Description

Mine recent claims, entities, and event sequences to discover emerging fraud patterns using anomaly detection, frequent pattern mining, and graph-based community detection; generate human-readable trigger candidates with example cases, estimated lift, projected false positive impact, and coverage; route recommendations to Rules Studio for review, with one-click creation, test-on-holdout evaluation, and staged rollout assistance.

Acceptance Criteria
Recommendation Generation with Metrics and Examples
Given the last 90 days of claims and related entities are available and indexed When the discovery job runs on its scheduled cadence or is triggered on-demand Then it outputs a list of trigger candidates, each including: a human-readable title and description; top contributing signals/features; 3–10 example claim IDs with deep links; estimated lift vs. baseline, coverage %, projected false positive impact %, and 95% confidence intervals; algorithm source (anomaly, frequent pattern, graph) and time window; a stable recommendation ID and reproducible query parameters
Route to Rules Studio with One-Click Rule Creation
Given a recommendation is selected in the UI and the user has Rule Author permission When the user clicks "Create Rule from Recommendation" Then a draft rule is created in Rules Studio pre-populated with logic, thresholds, metadata, and example cases And an audit log entry records user, timestamp, environment, and recommendation ID And a bidirectional link between the draft rule and originating recommendation is stored And permission checks prevent creation for unauthorized users with a clear error message
Holdout Evaluation and Metrics Display
Given a holdout dataset and baseline cohort are configured When the user runs "Test on Holdout" for a recommendation Then evaluation completes within 5 minutes for datasets up to 1,000,000 records And results include precision, recall, lift@k, ROC-AUC, coverage %, and a confusion matrix at the suggested threshold And metrics match an offline recomputation within 1% absolute difference And the full evaluation report is versioned, stored, and viewable with a shareable link
Staged Rollout Assistance and Monitoring
Given a recommendation has passed holdout evaluation and approval When the user initiates a staged rollout plan (e.g., 5% → 20% → 100%) Then the platform deploys the rule with traffic splitting per stage and records deployment versions And live monitoring shows alert rate deltas, precision proxy, reviewer workload, and SLA impact by stage And automatic alerts trigger and rollback is available if monitored KPIs breach configurable thresholds And a post-rollout summary compares observed vs. projected metrics and archives the report
Projected False Positive Impact Calibration
Given a deployed recommendation has accumulated 14 days of live data at 100% traffic When observed false positive impact is computed from labeled outcomes or reviewer dispositions Then the absolute error between projected and observed FP impact is within a configurable tolerance (default 10%) And recommendations exceeding tolerance are auto-flagged for recalibration and added to the calibration queue
Prioritization, Deduplication, and Filtering
Given multiple recommendations are generated for a line of business When recommendations are listed in the UI or API Then they are ranked by estimated net benefit (lift × coverage × cost savings − projected FP cost), highest first And only the top N (configurable; default 20) per LOB are shown by default And near-duplicates (logic Jaccard similarity ≥ 0.8) are merged or labeled as duplicates with a canonical entry And filters support LOB, algorithm source, coverage range, lift range, and date window
Human-Readable Trigger Candidate Formatting
Given a trigger candidate is generated When it is rendered in the UI or exported Then the title is ≤ 100 characters and the description is ≤ 500 characters using business-friendly terms from the data dictionary And rule logic is expressed in readable syntax with field names and operators (no internal feature IDs) plus a "why" explanation of the top 3 contributing signals with weights And labels and values pass a PII/profanity check, redacting sensitive fields beyond IDs and dates
Safe Rollout and Experimentation
"As a compliance-conscious product manager, I want safe rollout and A/B testing of tuning changes so that we can improve performance without disrupting operations."
Description

Provide experimentation tooling for model/rule updates, including champion–challenger tests, A/B splits, and incremental ramp-up with guardrails on alert volume and precision; manage experiment configuration, traffic allocation, and statistical significance calculations; isolate updates per workflow, maintain per-tenant version pinning, and auto-revert on KPI regression; consolidate results into decision reports for approvals.

Acceptance Criteria
Experiment Configuration Validation and Audit
- Given an authorized admin submits a new experiment with required fields (name, scope by workflows and tenants, model/rules versions, metrics, guardrails, traffic allocation, ramp plan, duration, success criteria) When they POST via API or save via UI Then the system validates types, ranges, and allowed values and returns 201 Created with experiment_id and version=1 - Given invalid or missing fields (e.g., allocation > 100%, negative thresholds, unknown workflow) When submission occurs Then the system returns 400 with machine-readable error codes per field and no experiment is created - Given an experiment is created or updated When the action completes Then an immutable audit log entry captures actor, timestamp, change diff, previous version, and reason - Given a new experiment targets a workflow+tenant already in an active experiment When creation is attempted Then the system blocks with 409 Conflict and lists conflicting experiment_ids
Traffic Allocation, Sticky Assignment, and Isolation
- Given a 70/30 champion/challenger allocation for workflow W1 and tenants T1,T2 When 10,000 eligible events are processed within the allocation window Then 70% ±1pp route to champion and 30% ±1pp to challenger - Given a claim_id is first assigned to the challenger When subsequent events for the same claim_id arrive within the experiment window Then they are consistently routed to the challenger (sticky assignment) - Given tenant T3 is not in the experiment scope When events from T3 are processed Then they bypass the experiment and use their pinned versions - Given two experiments target different workflows When both are active Then event routing remains isolated with no cross-assignment leakage
Incremental Ramp-Up with Guardrails and Auto-Pause
- Given a ramp plan [5%, 20%, 50%, 100%] with 60-minute evaluation checkpoints When a stage completes without guardrail breaches Then the next stage activates automatically at the scheduled checkpoint - Given alert volume exceeds +10% over baseline for 15 consecutive minutes When detected during any ramp stage Then the ramp auto-pauses, allocation reverts to the previous safe stage, and owners are notified within 5 minutes - Given precision (PPV) drops below baseline −3pp with 95% confidence When detected during an active stage Then the experiment transitions to Paused and no further ramp-up occurs until manual resume
Champion–Challenger Significance and KPI Evaluation
- Given primary and secondary KPIs are configured (e.g., precision, recall, approval_rate, time_to_decision) When each arm reaches minimum sample size n ≥ 2,000 alerts or the configured power threshold Then the system computes significance (frequentist p-values or Bayesian posteriors) and exposes 95% intervals for each KPI - Given no significant lift on the primary KPI and no meaningful benefit on secondaries by max_duration When evaluation completes Then the system recommends retaining the champion and marks the challenger for deprecation - Given significant lift on the primary KPI at ≥95% confidence with no guardrail violations When evaluation completes Then the system recommends promoting the challenger to champion and marks readiness status=Promotable
Automatic Revert on KPI Regression
- Given a challenger is promoted to champion for a workflow and tenant set When post-promotion monitoring detects KPI regression beyond configured thresholds for ≥30 minutes Then the system auto-reverts to the previous champion within 10 minutes and records an incident with triggering metrics and time window - Given an auto-revert executes When the revert completes Then new and in-flight decisions for that workflow+tenant use the restored champion on the next evaluation without event loss and a notification is sent to owners
Per-Workflow and Per-Tenant Version Pinning
- Given tenant T4 pins workflow W2 to model v1.8 and ruleset R-2025.09 When a global rollout attempts to update versions Then W2 for T4 remains on the pinned versions until explicitly unpinned or an approved override is applied - Given a pin has an expiry date of 2025-12-31 When the expiry passes Then the system unpins automatically and applies the current stable versions at the next deployment window - Given a pin is created, modified, or removed When the change is saved Then an audit log entry is recorded and the operation requires approver role permissions
Decision Report Generation and Approval Workflow
- Given an experiment has completed or is paused When an owner requests a decision report Then the system generates a report containing configuration snapshot, per-arm metrics, confidence intervals, sample sizes, guardrail breaches, and a promotion recommendation, and provides export as PDF and CSV - Given promotion requires approval When an approver approves via UI or API Then the system records approver ID, timestamp, immutable report version, and changes experiment status to Approved for Promotion - Given a report is generated When a subsequent config change is attempted Then the report remains immutable and a new report version is created for any re-evaluation

HeatPulse Alerts

Real-time surge detection that pings Ops and SIU on anomaly spikes by region, vendor, or channel. Sends Slack/Teams/email alerts with deep links into the affected cluster, respects quiet hours, and auto-suppresses duplicates. Accelerates response to coordinated events and protects against bursty fraud waves.

Requirements

Real-Time Surge Detection Engine
"As an operations lead, I want real-time detection of unusual claim surges by region, vendor, or channel so that I can quickly mobilize resources and minimize backlogs during spikes."
Description

Stream-based anomaly detection that continuously monitors claim intake volumes and NLP-extracted loss attributes across region, vendor, and channel dimensions. Calculates adaptive baselines with hourly/daily seasonality and applies statistical tests (e.g., z-score/Poisson) to flag significant spikes in near real time. Emits HeatPulse events with severity, cluster identifiers, and supporting metrics, persists alert records for auditability, and exposes APIs/webhooks for acknowledgment and downstream workflow triggers. Integrates with ClaimFlow’s ingestion pipeline and tagging services to ensure low-latency detection and accurate dimensioning.

Acceptance Criteria
Real-time spike detection within latency SLO
Given a live stream of claim intake events tagged with region, vendor, and channel and a configured monitoring window of 5 minutes with a 14-day seasonal baseline When the observed count for region='Gulf Coast', vendor='Acme IA', channel='SMS' exceeds the adaptive baseline with Poisson p_value <= 0.001 or z_score >= 3.5 Then a HeatPulse event is emitted for the cluster matching (region='Gulf Coast', vendor='Acme IA', channel='SMS') with fields: severity, test_type, window_start, window_end, baseline_stats, observed_metrics, detection_timestamp And the event emission latency from threshold breach to event persisted is <= 30 seconds And the event contains a deterministic cluster_id and dedupe_key
Adaptive baseline honors hourly/daily seasonality
Given 14 days of historical intake exhibiting hourly and day-of-week seasonality with no injected anomalies When the engine runs for a continuous 24-hour validation period Then it emits no more than 1 false-positive HeatPulse event across all monitored clusters And for an injected synthetic anomaly of +80% sustained over baseline for 30 minutes with p_value <= 0.001 Then exactly one HeatPulse event is emitted with severity in ['High','Critical']
Duplicate suppression and severity escalation per cluster
Given an active HeatPulse event exists for cluster_id C with severity='Medium' and a configured cooldown window of 10 minutes When a subsequent spike occurs in cluster_id C within the cooldown and the new observed_count increases < 50% over the prior event's observed_count Then no new HeatPulse event is created and the existing alert record is updated with an appended metric sample and last_seen_at timestamp When a subsequent spike occurs in cluster_id C within the cooldown and the new observed_count increases >= 50% over the prior event's observed_count Then the existing alert record severity is escalated by one level without creating a new alert record
Alert record persistence and audit retrieval
Given a HeatPulse event is emitted Then an immutable alert record is persisted with fields: alert_id, created_at, cluster_id, dimensions(region,vendor,channel), severity, status, test_type, window_start, window_end, baseline_stats, observed_metrics, dedupe_key, history[] And the record is retained for >= 365 days And a GET /alerts API supports filtering by created_at range, severity, region, vendor, channel, and status and returns the matching records within 2 seconds for up to 10,000 records
Webhook delivery, retries, and dead-letter handling
Given a registered webhook endpoint with idempotency support When a HeatPulse event is created Then the engine POSTs a JSON payload including alert_id, cluster_id, severity, and metrics with header Idempotency-Key=alert_id And on HTTP 2xx the delivery status is recorded as 'Delivered' on the alert record And on HTTP 5xx or timeout (>3s) the engine retries with exponential backoff over 5 attempts and then places the payload on a dead-letter queue with reason captured And duplicate deliveries with the same Idempotency-Key do not create duplicate downstream effects
Acknowledgment API state transitions and suppression
Given an existing alert record with status='Open' When a POST /alerts/{alert_id}/ack is received with a valid token and actor_id Then the alert status transitions to 'Acknowledged' with acknowledged_at and actor_id recorded in history[] And no further webhooks are delivered for this alert record And subsequent spikes for the same cluster during the remaining cooldown do not create new alerts
Accurate dimensioning from NLP tags with safe fallbacks
Given intake events with NLP-extracted attributes mapping to region, vendor, and channel When all three attributes are present and valid Then the event is dimensioned to the correct cluster with accuracy >= 99% on a labeled validation set When one or more attributes are missing or unrecognized Then the engine assigns 'Unknown' to the missing dimensions, still evaluates for surges at that granularity, and emits cluster_id values that encode 'Unknown' deterministically And dimensioning errors are logged with rate <= 0.1% and do not block detection
Configurable Thresholds & Sensitivity Controls
"As a product admin, I want to configure sensitivity and thresholds per region/vendor/channel so that alerts reflect our operational patterns and avoid false positives."
Description

Tenant- and environment-level controls to tune detection sensitivity and reduce noise. Supports per-dimension thresholds, minimum sample sizes, confidence levels, rolling window lengths, and cooldown periods. Includes business calendar awareness (weekends/holidays) and time zone alignment to normalize expected volumes. Provides an admin UI and API to manage configurations with versioning and safe rollout (staging to production), ensuring each insurer or MGA can tailor alerts to their risk profile and volume patterns.

Acceptance Criteria
Per-Dimension Thresholds, Window, Sample Size, and Cooldown
Given tenant "Northstar MGA" sets region.NE spikeThreshold=30%, minSample=25, rollingWindow=60m, cooldown=45m When 20 NE events in 60m produce a 40% spike Then no alert is emitted (minSample not met) Given the same config When 30 NE events in 60m produce a 35% spike Then exactly 1 alert is emitted for dimension=region:NE; alert includes threshold=30%, minSample=25, window=60m, cooldown=45m Given an alert fired for region=NE at T0 When another NE spike above threshold occurs at T0+30m Then no new alert is emitted (cooldown active) Given cooldowns are scoped per dimension value When a spike above threshold occurs for region=SW at T0+30m Then 1 alert is emitted for region=SW Given cooldown expired at T0+45m When another NE spike above threshold occurs at T0+50m Then a new alert is emitted for region=NE Given vendor.VendorX spikeThreshold=50% When a 45% spike occurs for VendorX with minSample met Then no alert is emitted for vendor dimension
Confidence Level Sensitivity Controls
Given confidenceLevel (alpha) = 0.05 for the tenant When a spike test yields pValue = 0.03 Then an alert is emitted Given alpha = 0.05 When pValue = 0.07 Then no alert is emitted Given alpha is changed to 0.10 and promoted to production When pValue = 0.07 Then an alert is emitted Given multiple evaluations occur within a rolling window When the configuration is updated at evaluation time Then the engine uses the latest active configuration and records alpha in alert metadata
Business Calendar and Time Zone Normalization
Given timeZone = America/New_York and calendar = US_Federal for the tenant When evaluating a window on Saturday 14:00 local with a 40% drop vs weekday mean Then no alert is emitted if within weekend/holiday baseline tolerance Given the same setup When evaluating Monday 10:00 local with the same volume Then an alert is emitted if deviation exceeds threshold vs weekday baseline Given July 4 is a configured holiday When evaluating July 4 11:00 local Then weekend/holiday baseline is applied and no alert is emitted for the same volume Given rollingWindow = 60m When the window crosses 00:00 local Then window boundaries and daily baselines reset at local midnight, not UTC
Admin UI: Versioned Configuration Management
Given an admin opens HeatPulse settings UI When required fields are empty or invalid (threshold < 0 or > 300, minSample < 1, rollingWindow < 5m or > 1440m, cooldown < 0 or > 1440m, unknown timeZone/calendar) Then inline validation messages are shown and Save is disabled Given valid inputs for per-dimension thresholds, minSample, confidenceLevel, rollingWindow, cooldown, timeZone, and calendar When Save to Staging is clicked Then a new configuration version is created with unique versionId, environment=staging, createdAt, createdBy Given versions exist When viewing version history Then versions are listed with versionId, environment, status (active/draft), and timestamp Given a staged version is selected When Promote to Production is confirmed Then the version becomes the active production config and the previous production version remains available for rollback
Config API: Versioning, Validation, Promotion, and Rollback
Given POST /heatpulse/configs with a valid payload Then 201 Created is returned with versionId and environment=staging Given POST /heatpulse/configs with invalid values (e.g., rollingWindow=2m, minSample=0, alpha=1.2) Then 422 Unprocessable Entity is returned with field-level errors Given If-Match ETag is provided on update When the ETag is stale Then 409 Conflict is returned Given GET /heatpulse/configs?environment=production Then 200 OK returns the active production configuration Given POST /heatpulse/configs/{versionId}/promote Then 200 OK marks the version active in production Given POST /heatpulse/configs/{versionId}/rollback Then 201 Created produces a new version cloned from the prior production version and marks it active Given all API calls require tenant scope When tenantId is missing or mismatched Then 403 Forbidden is returned
Environment Isolation and Tenant Scoping
Given tenants A and B each have distinct configurations When an alert evaluation runs for tenant A Then only tenant A’s active configuration is applied Given a configuration is saved in staging When evaluations run in production Then staging changes do not affect production alerts Given a promotion occurs at T0 When evaluations run at T0-1m and T0+1m Then pre-promotion alerts use the prior active config and post-promotion alerts use the new config; no reprocessing occurs for past windows Given bulk API updates are performed for tenant A When tenant B retrieves configuration Then tenant B sees no changes and retains its own configuration
Quiet Hours & Snooze Policies
"As a regional supervisor, I want quiet hours and snooze options so that my team isn’t flooded with non-urgent alerts off-hours while still receiving critical notifications."
Description

Organization-, team-, and user-level quiet hours that defer non-critical notifications outside defined windows while allowing critical severity to bypass based on policy. Time zone–aware schedules and on-call calendar integration ensure the right people are notified at the right times. Users can snooze an alert for a specified duration or until the anomaly subsides, with auto-rearm logic. Policies are audited and enforceable per tenant to respect compliance and reduce alert fatigue.

Acceptance Criteria
Org Quiet Hours with Critical Bypass
Given tenant default time zone is America/Chicago and org quiet hours are 22:00–06:00 with policy "severity >= Critical bypasses quiet hours" When a Non-Critical alert is generated at 23:30 local time Then the alert is deferred with a defer-until timestamp of 06:00 local and no outbound messages are sent before 06:00 When a Critical alert is generated at 01:15 local time Then the alert is delivered immediately to all configured channels and the delivery log records quiet_hours_bypassed = true When time reaches 06:00 local Then all deferred Non-Critical alerts are delivered within 2 minutes and tagged as delivery_reason = "deferred_quiet_hours"
Team Quiet Hours Respect Local Time Zones
Given team "SIU East" quiet hours are 21:00–07:00 America/New_York and tenant default time zone is America/Chicago When an alert targeted to the team occurs at 22:30 Eastern Then delivery to team endpoints is deferred until 07:00 Eastern regardless of individual member time zones When the team time zone is not configured Then the system uses the tenant default time zone to compute defer-until When a DST fallback occurs during quiet hours Then the defer-until remains 07:00 local clock time and is computed using the time zone database without duplicate deliveries
Policy Precedence and Conflict Resolution
Given org quiet hours 22:00–06:00, team quiet hours 20:00–08:00, user quiet hours 00:00–07:00, and policy "critical_bypass=true at org, false at team" When a Non-Critical alert occurs at 21:30 local time Then the alert is deferred until 08:00 (maximum end among active quiet windows at all levels) When a Non-Critical alert occurs at 23:30 local time Then the alert is deferred until 08:00 and the effective policy snapshot stores fields: level_applied = [org,team,user], defer_until, evaluation_timestamp When a Critical alert occurs at 23:30 local time Then the alert is delivered immediately because any applicable level allows bypass and the snapshot records bypass_source = "org" When a user sets "Always Notify" override Then Non-Critical alerts to that user are delivered during quiet hours while the team/org deliveries remain deferred
On-Call Calendar Overrides Quiet Hours
Given on-call integration is connected and team "Ops West" has on-call window 22:00–06:00 America/Los_Angeles with policy NotifyOnCallDuringQuietHours = true When a Non-Critical alert occurs at 23:00 Pacific during org quiet hours Then the alert is delivered immediately to the active on-call user and deferred for non on-call recipients When the on-call rotation changes from Jane to Mark at 02:00 Then alerts after 02:00 route to Mark without delivery gaps greater than 60 seconds When the on-call calendar fetch fails Then the system defers Non-Critical alerts per quiet hours policy and logs calendar_fetch_failure with correlation_id
Snooze Alert for Fixed Duration
Given a user snoozes alert cluster ABC-123 for 90 minutes at scope = "User" When additional notifications for ABC-123 are generated within the 90-minute window Then they are suppressed for that user only and visible to other recipients per policy When 90 minutes elapse Then the snooze auto-rearms and the next notification for ABC-123 is delivered within 2 minutes When the user cancels the snooze before expiry Then subsequent notifications are delivered immediately and the cancellation is logged with timestamp and actor_id
Snooze Until Anomaly Subsides with Auto-Rearm
Given a team applies snooze type = "Until Resolved" to cluster XYZ-789 with inactivity_threshold = 30 minutes When the anomaly metric remains above threshold Then all notifications for XYZ-789 to that team are suppressed and suppression_count increments per event When the metric falls below threshold and remains below for 30 consecutive minutes Then the system auto-rearms and sends a single "re-armed" notice to the team When the anomaly reoccurs within 15 minutes of rearm Then the next alert is delivered immediately and no automatic snooze is reapplied
Policy Audit Trail and Per-Tenant Enforcement
Given auditing is enabled for quiet hours and snooze policies When a policy is created, updated, or deleted Then an immutable audit record is stored with tenant_id, actor_id, timestamp, old_value, new_value, and change_reason When retrieving an alert’s delivery record Then the effective policy snapshot includes audit_reference_ids that explain defer, bypass, or snooze decisions When a user from Tenant A attempts to apply a policy to an alert in Tenant B Then the operation is rejected with 403 and the attempt is logged without cross-tenant data leakage When exporting audit logs for Tenant A Then only Tenant A’s records are returned and the export is filterable by date range and actor
Duplicate Suppression & Alert Grouping
"As an on-call analyst, I want duplicate alerts to be suppressed and grouped into a single thread so that I can focus on one incident timeline instead of managing redundant pings."
Description

Correlation logic that groups related anomaly signals into a single alert thread per cluster, using keys such as region, vendor, channel, and time window. Deduplicates repeated detections within a configurable window, rolls up metrics into a running summary, and posts incremental updates instead of new alerts. Provides re-arm conditions when activity subsides and resurges. Prevents notification floods while preserving a complete timeline of the incident for audit and postmortems.

Acceptance Criteria
Group Related Anomalies into Single Alert Thread
Given the system detects two or more anomaly signals with identical correlation keys (region, vendor, channel) within the active correlation window When the first signal is processed Then exactly one alert thread is created for that cluster and labeled with the correlation keys and a unique cluster_id Given subsequent related signals arrive within the same window When they are processed Then no additional alert threads are created for that cluster
Configurable Deduplication Window
Given a deduplication window W is set to N minutes in tenant settings When duplicate anomaly signals (same correlation keys and signature) arrive within W of the last processed signal Then the system suppresses new alert creation and increments the suppressed_count for the cluster by 1 per duplicate And the suppression reason includes "within_window" with window value W And the action is logged with detection_id and timestamp
Incremental Updates with Running Summary
Given an existing alert thread for a cluster is active When a new related signal is processed Then the system posts an incremental update to the existing thread (Slack thread reply, Teams reply, or same email conversation) rather than creating a new thread And the update includes delta metrics (new event count since last update), running totals (total events, suppressed_count), last_seen_at timestamp, and top correlated attributes And the update appears in the destination channel within 10 seconds of processing
Re-Arm and New Thread on Resurgence
Given no related signals have been observed for at least R minutes (re-arm window) When a new related signal is detected after R Then the prior cluster is marked "resolved" with resolved_at timestamp And a new alert thread is created for the new surge with a new cluster_id And the previous thread receives a final summary update indicating closure and total counts
Complete Audit Timeline
Given an incident cluster exists When an auditor retrieves the cluster timeline via API or UI Then the system returns an ordered list of events including initial_alert, update, suppression, closure with ISO 8601 timestamps, actor/system, correlation_keys, detection_ids, and metrics snapshots And the timeline is exportable to CSV and JSON And no gaps exist in event sequence numbers
No Over-Suppression of Distinct Clusters
Given two anomaly signals differ by any configured correlation key (region OR vendor OR channel) or fall outside the correlation window When both are processed Then two distinct alert threads are created with different cluster_ids And neither signal increments the other's suppressed_count or totals
Tenant-Level Correlation Configuration
Given an admin updates the tenant's correlation configuration (keys enabled and window durations) in settings When the changes are saved Then new detections use the new configuration within 5 minutes And existing active clusters continue using the previous configuration until resolved And configuration changes are validated (no zero/negative windows, at least one key enabled) and audit-logged with who, what, and when
Multi-Channel Alert Delivery Integrations
"As a duty manager, I want alerts delivered to Slack/Teams/email with links to context so that I can act immediately from our existing communication tools."
Description

Native connectors to Slack, Microsoft Teams, and email that deliver HeatPulse notifications with structured templates, severity badges, and deep links to the affected cluster. Supports per-tenant routing rules (Ops vs. SIU), channel/user targeting, delivery retries, rate limiting, and delivery status tracking. OAuth-based connection management with token refresh and per-tenant secrets isolation. Provides fallback to alternative channels on failure to ensure reliable delivery.

Acceptance Criteria
Slack Alert Delivery with Template, Badges, and Deep Link
Given a tenant has an active Slack OAuth connection and a routing rule targeting channel "#ops-incidents" And a HeatPulse surge event occurs with severity "High" and clusterId "CL-123" When the system emits an alert for the event Then a Slack message is posted to #ops-incidents within 15 seconds And the message uses the "HeatPulse v1" template with a visible severity badge "High" And the message contains region, vendor, and channel fields from the event payload And the message includes a deep link to the CL-123 cluster details that responds with HTTP 200 when followed And the delivery record stores provider message ID, timestamp, and status "Delivered" for Slack
Microsoft Teams Delivery with Channel and User Targeting
Given a tenant has an active Microsoft Teams OAuth connection And a routing rule maps SIU alerts to the "SIU-Bridge" channel and mentions the on-call user "@siu.oncall" And a HeatPulse alert with severity "Critical" is generated When the system sends the alert Then a Teams message is posted to the SIU-Bridge channel within 15 seconds And the message follows the "HeatPulse v1" template with severity badge "Critical" and a working deep link to the affected cluster And the message mentions @siu.oncall And the delivery record stores provider message ID, timestamp, and status "Delivered" for Teams
Email Delivery with Structured Subject and Deep Link
Given the tenant's email integration is configured with recipient "siu@tenant.com" And a HeatPulse alert with severity "Medium" and clusterId "CL-456" is generated When the system sends the alert via email Then the email is dispatched within 60 seconds And the subject begins with "[HeatPulse][Medium]" And the body uses the "HeatPulse v1" template including region, vendor, channel, and a deep link to CL-456 that responds with HTTP 200 And delivery status is recorded as "Delivered" with provider message ID, or "Bounced" with bounce code if rejected
Per-Tenant Routing Rules for Ops vs. SIU
Given tenant routing rules specify: severity Low/Medium to Ops Slack channel, severity High/Critical or fraud-tagged events to SIU in Teams and email And two alerts are generated: A1 (severity Medium, no fraud) and A2 (severity High, fraud-tagged) When routing is evaluated Then A1 is sent only to the configured Ops Slack channel And A2 is sent to the configured SIU Teams channel and SIU email recipients And no messages are sent to destinations not defined for the tenant And an audit log entry records the rule matched and destinations selected for A1 and A2
OAuth Connection Management and Secrets Isolation
Given Slack and Teams connectors are authorized with expiring access tokens and refresh tokens stored When an access token is within 5 minutes of expiry or has expired Then the system refreshes the token using the provider's OAuth flow before sending the next alert, without losing messages And per-tenant secrets are stored in isolated namespaces such that Tenant A cannot access Tenant B's credentials (verified via access control tests) And if a token is revoked, the system marks the connection as "Invalid" within 5 minutes and notifies the tenant admin via the configured admin channel And re-authorization via OAuth updates stored tokens and resumes deliveries without code changes
Retries, Backoff, Internal Throttling, and Fallback
Given a tenant's primary route is Slack with email as fallback, and per-tenant send rate is limited to 60 messages per minute per channel And Slack returns HTTP 5xx or rate-limit (429) responses for an alert When the system attempts delivery Then it retries up to 3 times with exponential backoff starting at 2 seconds and honoring provider Retry-After headers And it enforces the 60 msg/min/channel internal rate limit by queueing excess messages without triggering provider errors And if all Slack retries fail or the send exceeds a 2-minute SLA, the system sends the alert via email And the final statuses recorded are Slack="Failed" (with error code) and Email="Delivered" (with message ID), with a single fallback sent (no duplicates)
Delivery Status Tracking and Query API
Given alerts A1 and A2 were sent to Slack and email respectively When the delivery status API is queried for tenant T with alertId=A1 and A2 Then the response includes per-destination entries with status (e.g., Delivered, Failed, Queued), provider IDs, attempt counts, and timestamps And status transitions are visible within 5 seconds of provider callbacks or internal updates And the API supports filtering by time range, destination type, status, and tenant ID, returning results within 500 ms for up to 1000 records
Deep Link Context & Cluster Explorer
"As an investigator, I want a deep link into a detailed cluster view so that I can quickly assess scope, evidence, and next steps without manual filtering."
Description

Generation of permission-aware deep links that open a pre-filtered ClaimFlow view of the anomaly cluster, including timeframe, impacted regions/vendors/channels, trend charts, map overlays, top contributing claim types, and sample claims with images/messages. Enables quick triage with one click and provides actions to acknowledge, assign owners, create tasks, or escalate to SIU. Links are stable, tenant-scoped, and support UTM metadata for analytics on alert engagement.

Acceptance Criteria
Open Deep Link from Slack/Teams/Email
Given a HeatPulse alert contains a deep link shared via Slack, Teams, or Email within a ClaimFlow tenant When a permitted user clicks the deep link on desktop or mobile Then the ClaimFlow app opens directly to the Cluster Explorer with the anomaly’s timeframe and impacted regions, vendors, and channels pre-applied And if the user is not authenticated, they are prompted to log in and, upon success, are redirected back to the exact deep-linked Cluster Explorer state And all URL parameters are correctly URL-encoded and preserved through redirects
Permission-Aware Access Control
Given a user with required permissions to view the cluster and its underlying claims opens the deep link Then the Cluster Explorer loads with full context and permitted sample assets visible Given a user without permission to any part of the cluster or underlying claims opens the deep link Then access is denied with a 403-style message, no PII/claim details are rendered, and guidance to request access is shown And all access outcomes (allow/deny) are captured in the audit log with userId, tenantId, linkId, and timestamp And for partial permissions, restricted images/messages are redacted while permitted fields remain visible
Tenant-Scoped Link Enforcement
Given a deep link generated in Tenant A When opened by a user authenticated under Tenant B or unauthenticated with a different tenant context Then the request is rejected as out-of-scope without revealing any Tenant A identifiers or data And the same deep link, when opened by an authenticated Tenant A user with sufficient permissions, resolves successfully And the link cannot be used to enumerate cross-tenant resources (opaque linkId validated server-side; no incremental IDs in the URL)
Cluster Explorer Context Completeness
Given the deep link is opened successfully Then the Cluster Explorer shows: - Timeframe chip(s) matching the cluster window - Preselected filters for impacted regions, vendors, and channels - A trend chart for anomaly volume over time - A map overlay for affected geographies (when region data exists) - A Top contributing claim types list (top 5 by volume) with counts - A sample claims panel with at least 10 items showing thumbnails of images and message snippets And all counts and filters match the underlying cluster definition with zero variance for filter membership And toggling any preselected filter updates the results consistently while retaining the cluster context
Action Execution from Cluster Explorer
Given the Cluster Explorer is open and the user has action permissions When the user clicks Acknowledge Then the cluster status becomes Acknowledged, recording user, timestamp, and optional note, and the UI reflects the new status without a full page reload When the user Assigns owners Then selected owners are added, visible in the UI, and notified via configured channels When the user Creates a task Then a task is created in ClaimFlow with a backlink to the cluster and appears in the workflow within 10 seconds (p95) When the user Escalates to SIU Then an SIU case is created with cluster metadata and a backlink, and its ID is shown in the UI And all actions are permission-checked, idempotent on retry within 60 seconds, and audit-logged with actor, timestamp, and outcome
UTM Metadata Analytics Capture
Given a deep link contains UTM parameters utm_source, utm_medium, utm_campaign, utm_content (optional: utm_term) When the link is opened, including via a login redirect flow Then the open event is recorded with userId, tenantId, linkId, and all UTM parameters, and is available in analytics within 15 minutes And if UTM parameters are absent, the event is still recorded without error And UTM parameters persist unmodified across redirects and are not exposed via external referrers beyond the app domain
Deep Link Stability Across Releases
Given a deep link was generated for an alert When the application is upgraded across two consecutive releases and anomaly data is re-indexed or backfilled Then the deep link continues to resolve to the same filter configuration and cluster scope And link identifiers remain immutable; any schema changes maintain backward compatibility or provide seamless 301/302 redirects And copying/forwarding/QR-encoding the link preserves functionality and target resolution
SIU Escalation Rules & Workflow
"As an SIU lead, I want high-risk surges to auto-escalate into an SIU workflow so that investigations start immediately with the necessary evidence and accountability."
Description

Rules engine that routes high-risk anomalies directly to SIU with configurable criteria (e.g., vendor reputation score, fraud signals, cross-channel coordination). Automatically creates an SIU investigation task with attached evidence snapshots, severity, and rationale. Supports two-step acknowledgment, assignment, and SLA timers, with full audit trail and reporting on escalations to measure fraud wave response time and outcomes.

Acceptance Criteria
Auto-Route High-Risk Anomaly to SIU
Given a new anomaly event meets a configured rule (vendor_reputation_score <= 30 and fraud_signal = "synthetic_id"), When the event is processed, Then an SIU escalation is created within 10 seconds and appears in the SIU queue. Given multiple rules exist, When an anomaly matches more than one rule, Then the highest severity rule determines the escalation severity and all matched rules are recorded in the rationale. Given an anomaly does not meet any SIU rule, When processed, Then no SIU escalation is created.
Create SIU Investigation Task with Evidence Package
Given an SIU escalation is created, When the task is generated, Then the task includes: evidence snapshots (uploaded images and message excerpts), a deep link to the source cluster, computed severity (Low/Medium/High/Critical), and a rationale listing matched rule conditions and values. Given the evidence package is built, When attachments are created, Then each attachment includes a checksum and original source timestamp. Given the task is created, When opened by an SIU user, Then evidence is viewable in-app and downloadable as a ZIP without data loss.
Two-Step Acknowledgment and Assignment Workflow
Given an open SIU task, When an SIU user with role "Investigator" clicks Acknowledge, Then the task status changes to "Acknowledged", the acknowledgment timestamp is recorded, and the actor is logged. Given an acknowledged task, When a user with role "Supervisor" assigns it to an investigator, Then the assignee is set, the assignment timestamp is recorded, and the task status changes to "Assigned". Given role-based controls, When a user without the required role attempts to Acknowledge or Assign, Then the action is blocked with a 403 error and no state change occurs. Given an assigned task, When reassigned, Then the previous assignee remains in history and a reassignment reason is required.
SLA Timers, Pauses, and Breach Notifications
Given an SIU escalation is created, When timers start, Then an Acknowledgment SLA of 30 minutes and an Investigation Start SLA of 4 hours are tracked on the task. Given quiet hours are configured from 22:00–06:00 in the SIU team timezone, When an SLA timer spans quiet hours, Then the timer pauses during quiet hours and resumes afterward. Given an SLA is within 5 minutes of breach, When the threshold is reached, Then a reminder notification is sent to the assignee and SIU channel. Given an SLA breach occurs, When breached, Then the task is marked "SLA Breached", a breach event is logged, and a notification is sent to the SIU supervisor group.
End-to-End Audit Trail for Escalations
Given any escalation lifecycle event (create, acknowledge, assign, comment, state change, SLA pause/resume), When the event occurs, Then an immutable audit record is stored with user ID, timestamp (UTC), action, old/new values, rule version, and request ID. Given audit records exist, When queried by escalation ID and date range, Then results return within 2 seconds and are exportable as CSV. Given an audit record is generated, When tampering is attempted, Then integrity verification detects the mismatch and the write is blocked, with an alert logged.
SIU Escalation Reporting and KPIs
Given escalations exist, When viewing the SIU Reporting dashboard for a selected date range, Then the following metrics are displayed: total escalations, escalations by rule, median time to acknowledgment, median time to assignment, SLA breach rate, outcomes (confirmed fraud/prevented/false positive), and counts by region/vendor/channel. Given filters are applied (region, vendor, channel, rule, severity), When used, Then metrics recalculate within 3 seconds. Given the dashboard is viewed, When Export is clicked, Then a CSV with the visible metrics and applied filters is generated within 10 seconds. Given an escalation is closed with an outcome, When closed as "Confirmed Fraud", Then reporting reflects the outcome within 15 minutes.
Cross-Channel Coordination Detection and Rationale
Given anomalies share at least two identifiers across channels (e.g., phone_number and device_fingerprint) within a 24-hour window, When detected, Then a single SIU escalation is created for the coordinated cluster and severity is upgraded by one level. Given a coordinated escalation is created, When viewed, Then the rationale lists the cross-channel identifiers and counts per channel, and the deep link opens the cluster view with associated events highlighted. Given a coordinated cluster exists, When new matching anomalies arrive within a 2-hour suppression window, Then duplicates are auto-suppressed and appended as related evidence without creating new SIU tasks.

Critical Path

Visualizes every intake step and dependency as a live timeline, highlighting bottlenecks, slack, and the exact tasks driving breach risk. Gives Ops Leads a precise place to intervene and shows adjusters the next best action to keep the claim on track.

Requirements

Live Timeline Rendering
"As an Ops Lead, I want to see a live timeline of all intake steps and dependencies so that I can instantly understand progress and where to intervene."
Description

Render each claim’s intake workflow as a real-time, horizontally scrolling timeline that displays tasks, phases, and dependencies with current status, assignee, ETA, and SLA markers. The view updates instantly on workflow events (task creation/completion, reassignment, data capture from NLP), and visually distinguishes critical-path tasks from non-critical tasks using color and badges. It supports zoom, filter by role (Ops Lead vs. Adjuster), and collapsing of parallel branches for clarity. Integrates with ClaimFlow’s workflow engine and task router to read canonical task states and due dates, and with the messaging/photo ingestion layer to reflect auto-completed steps. Must handle up to 300 tasks per claim with sub-200ms frame updates and <1s end-to-end event-to-UI latency over WebSocket/SSE. Enforces role-based access to hide restricted tasks and includes accessible keyboard navigation and screen-reader labels.

Acceptance Criteria
Sub-1s Real-Time Update on Workflow Events
Given the claim’s timeline view is open and connected via WebSocket/SSE And the backend emits a workflow event (task created, completed, reassigned, status change, ETA change) for this claim When the event is received by the client Then the corresponding task card, phase, dependency line, and SLA marker update without a full page refresh And the visual update is rendered within 1 second end-to-end at the 95th percentile and 500 ms at the median And per-event frame processing time is <= 200 ms at the 95th percentile And multiple events received within 500 ms are applied in order and result in the correct final state And the horizontal scroll position and current selection are preserved
Critical Path Highlighting and Badge Accuracy
Given tasks and dependencies are loaded from the workflow engine When the critical path is computed based on current durations, dependencies, and due dates Then all tasks on the critical path are visually distinguished with the specified color and a "Critical" badge And non-critical tasks are visually de-emphasized without violating WCAG contrast And toggling the "Show only critical path" filter hides non-critical tasks and preserves dependency lines among critical tasks And when a change to task state/duration/ETA causes the critical path to change, the highlighting updates within 1 second And the set of highlighted tasks matches the workflow engine’s critical-path API output 100% for the same snapshot
Role-Based Visibility for Ops Leads vs Adjusters
Given a signed-in user with role Adjuster or Ops Lead When the timeline loads Then tasks restricted by RBAC to which the user lacks access are not rendered, not included in counts, and not discoverable via tooltips or search And attempts to query or deep-link to a restricted task return 403 and do not reveal metadata And an Ops Lead sees all tasks for the claim; an Adjuster sees only their assigned tasks and tasks marked visible-to-adjuster by policy And SLA breach markers and ETAs for hidden tasks are not shown or inferred And access checks are enforced both client-side and server-side
Zoom, Filter, and Parallel Branch Collapse Controls
Given a timeline with multiple phases and parallel branches When the user zooms in/out via keyboard shortcuts, mouse wheel with modifier, or on-screen controls Then the time scale adjusts smoothly, labels do not overlap, and the focused/selected item remains in view When the user applies the role filter (Ops Lead vs Adjuster) or status filters (e.g., Active, Completed, Blocked) Then only matching tasks are shown, counts are updated, and critical-path highlighting remains consistent with the full workflow; collapsed/hidden groups display a critical indicator if any hidden tasks are on the critical path When the user collapses a parallel branch Then the branch is replaced with a summarized pill showing task count, earliest start, latest end, and any SLA breach indicator And expanding the branch restores its previous scroll position and selection And the zoom level, filters, and collapsed state persist for the session and across a page refresh
Performance Under Heavy Load (300 Tasks)
Given a claim with 300 tasks across up to 20 phases and multiple parallel branches When the user pans horizontally, zooms, and selects tasks while receiving at least 10 workflow events per minute Then the UI remains responsive with input latency <= 100 ms for pan/zoom at the 95th percentile And visual updates per event complete with frame processing time <= 200 ms at the 95th percentile And end-to-end event-to-UI latency remains <= 1 second at the 95th percentile And memory usage of the timeline component stays under 200 MB in a fresh session on a mid-tier machine (8 GB RAM) And no more than 1 dropped frame per second is observed during continuous pan at 60 Hz in performance profiling
Accessible Navigation and Screen Reader Labels
Given a user navigating with keyboard only When focus enters the timeline Then Tab/Shift+Tab traverse actionable elements; Arrow keys move focus between adjacent tasks; Enter/Space activate or toggle controls; and focus is visibly indicated with at least 3:1 contrast And all functions (zoom, filter, collapse, select, open details) are operable via keyboard Given a screen reader user (NVDA, JAWS, or VoiceOver) When tasks and controls are focused Then ARIA roles, names, and states announce task title, status, assignee, ETA, SLA marker, and whether the task is on the critical path And color is not the sole means of conveying criticality or status And the timeline meets WCAG 2.2 AA for contrast and focus visible
Auto-Completion from NLP Ingestion Reflected in Timeline
Given the messaging/photo ingestion layer auto-completes a task via NLP extraction When the workflow engine updates the task state to Completed with completion timestamp and any derived data Then the task card reflects the Completed state, completion time, and an "Auto" badge with tooltip linking to the source message/photo And all downstream dependent tasks update to Active/Unblocked as appropriate And ETAs and SLA markers recalculate and render within 1 second end-to-end And an audit trail entry is accessible from the task details
Dependency Mapping Engine
"As a claims manager, I want the system to map task dependencies from our workflows so that the critical path reflects our operating rules accurately."
Description

Provide a deterministic service that constructs and maintains a directed acyclic graph (DAG) of intake tasks, gates, and conditional branches from ClaimFlow’s configurable workflows. It interprets prerequisite rules, optional steps, parallelization, and policy/LOB-specific conditions, and recalculates the graph when rules or task states change. Detects and flags potential cycles or misconfigurations with actionable diagnostics. Exposes an API that supplies the current DAG, critical path, earliest/latest start/finish times, and path explanations to the timeline and analytics modules. Consumes signals from NLP-extracted facts to satisfy gate criteria automatically when sufficient evidence is present. Persists snapshots for auditability and supports versioning of workflow definitions across carriers and MGAs.

Acceptance Criteria
Deterministic DAG Construction from Configurable Workflow
Given a workflow definition with tasks T1, T2, T3 and gate G1 where T2 requires T1, T3 is optional, T1 and G1 may run in parallel, and G1 requires (T1 complete AND policy.lob = "Auto") When the engine constructs the DAG for a claim with policy.lob = "Auto" Then the returned DAG contains nodes {T1, T2, T3, G1} and edges {(T1->T2), (T1->G1)} And T3 is marked optional with no incoming edges And the DAG is acyclic and passes topological validation And two consecutive builds with identical inputs produce byte-identical DAG JSON and topological order
Dynamic Recalculation on Rule and Task State Changes
Given an existing DAG for claim C with tasks A, B, C where B depends on A and durations A=2h, B=1h, C=1h When task A transitions to Done Then the engine recomputes the DAG and schedule within 200 ms for N<=100 nodes And B becomes Unblocked and earliestStart(B) equals actualFinish(A) And the critical path updates deterministically and is exposed with a new ETag And a new graphVersion is created and persisted
Cycle and Misconfiguration Detection with Diagnostics
Given a workflow definition containing a cycle A->B->C->A and an unreachable node D When the engine validates the workflow Then publication is rejected and no DAG is created And diagnostics include the cycle path [A,B,C,A] with offending edges And diagnostics list unreachable nodes [D] with reasons And an error event is emitted with code WF_CYCLE_DETECTED and correlationId
API Exposure of DAG, Critical Path, Schedule, and Explanations
Given a claim with an existing DAG of 50 nodes and computed schedule When a client calls GET /claims/{id}/dag Then the response is 200 with schema {nodes, edges, graphVersion, generatedAt} And median latency <= 150 ms and P99 <= 300 ms at 50 RPS When a client calls GET /claims/{id}/critical-path Then the response includes nodeIds, totalDuration, slack per node, ES/EF/LS/LF per node, and explanation strings for critical nodes And responses include an ETag and are cacheable for 30s unless graphVersion changes
Automatic Gate Satisfaction from NLP-Extracted Facts
Given a gate G that requires photo_of_damage=true with confidence >= 0.9 And the NLP engine emits fact f1 {key:"photo_of_damage", value:true, confidence:0.95, source:"MMS:123"} When the engine ingests f1 Then G is marked Satisfied within 1 second with provenance [f1.id] and rule evaluation details And downstream tasks depending on G become Unblocked When the NLP emits fact f2 with confidence 0.6 for the same key Then G remains unchanged and a low-confidence evaluation is logged And ingestion is idempotent if f1 is received multiple times
Snapshot Persistence and Auditability
Given any change to rules or task states that affects the DAG or schedule When the engine persists the new state Then a read-only snapshot is stored with claimId, workflowId, workflowVersion, graphVersion, timestamp, actor, and contentHash And GET /claims/{id}/dag?asOf=timestamp returns the exact snapshot and identical critical path for that time And GET /claims/{id}/dag/diff?from=graphVersionX&to=graphVersionY returns added/removed/changed nodes, edges, and timing deltas And snapshots are immutable and retained per retention policy
Multi-Carrier/MGA Workflow Versioning and Isolation
Given carriers C1 and C2 each with workflow version v1 (different rules) When a claim for carrier C1 is created Then the engine binds the claim to C1:v1 and uses only that definition to build the DAG And requests and data from C2 cannot influence C1's DAG When carrier C1 publishes v2 Then new claims bind to C1:v2 and existing claims remain on v1 unless an explicit migration is executed And API responses include carrierId and workflowVersionId for traceability
Slack Time Calculation
"As an adjuster, I want to see slack for each task so that I know what can wait and what must be done now."
Description

Compute total float and free float for every task based on current estimates, dependencies, and SLA deadlines, and surface slack visually in the timeline and as numeric values via API. Update calculations incrementally on task duration updates, reassignments, or auto-completion events from NLP. Highlight tasks with low or negative slack and project the impact of delays on downstream steps. Store baseline vs. actual slack to enable variance analysis and continuous improvement reporting. Supports per-claim and per-workflow templates for default durations and allows Ops to override task estimates with audit logs.

Acceptance Criteria
Compute Total and Free Float per Task
Given a claim workflow with tasks A(16h) → B(8h) → C(8h) and an SLA of 32h from A start When slack calculation runs Then A.freeFloat=8h, A.totalFloat=0h; B.freeFloat=0h, B.totalFloat=0h; C.freeFloat=0h, C.totalFloat=0h And all tasks have non-null numeric freeFloatHours and totalFloatHours And freeFloatHours ≥ 0 unless constrained by downstream deadlines producing negative totalFloatHours Given a Finish-to-Start dependency with an 8h lag from X to Y When slack calculation runs Then Y.earliestStart ≥ X.earliestFinish + 8h and floats incorporate the lag accordingly
Timeline Slack Visualization and API Values
Given the timeline view is opened for a claim When tasks render Then each task displays a visual slack indicator and a tooltip showing freeFloatHours and totalFloatHours in hours with two-decimal precision And tasks with 0 < freeFloatHours ≤ 8 display a Low Slack badge And tasks with totalFloatHours < 0 display an At Risk badge Given an API call GET /claims/{claimId}/tasks When the response is returned Then each task item includes numeric fields totalFloatHours and freeFloatHours matching the UI within ±0.01h and the endpoint responds within 500ms for ≤200 tasks
Incremental Recalculation on Updates and NLP Events
Given a workflow with 100 tasks and established floats When a single task’s estimated duration is updated Then slack values are recomputed only for the affected task and its dependent upstream/downstream tasks and complete within 2 seconds And tasks unrelated by dependency retain identical float values Given a task is reassigned without estimate change When recalculation runs Then floats remain unchanged and the recomputation completes within 2 seconds Given an NLP auto-completion event marks a task Done When the event is processed Then slack is recalculated within 1 second and values reflect the completion Given three rapid successive updates to the same estimate When processed Then the final floats reflect the last update only (idempotent result)
Low/Negative Slack Highlight and Downstream Impact Projection
Given a task T with freeFloatHours=4 and totalFloatHours=4 When the user simulates a 6h delay on T Then T shows totalFloatHours=-2 and all downstream tasks on the affected path show start/finish times shifted by +2h And any task with totalFloatHours < 0 is highlighted At Risk in the timeline Given the simulation panel is closed or the simulation is cleared When the user exits the mode Then all slack values and visuals revert to the baseline actuals with no residual changes
Baseline vs Actual Slack Storage and Variance
Given a claim is created and the first slack calculation completes When baseline is captured automatically Then each task stores baselineFreeFloatHours and baselineTotalFloatHours with a timestamp and baselineVersion=1 And subsequent changes update actualFreeFloatHours and actualTotalFloatHours only; baseline values remain immutable Given an API call GET /claims/{id}/slack-variance When the response is returned Then each task includes deltaFreeFloatHours = actualFreeFloatHours - baselineFreeFloatHours and deltaTotalFloatHours = actualTotalFloatHours - baselineTotalFloatHours Given a user triggers Set New Baseline When confirmed Then baselineVersion increments and new baseline* fields equal the current actual* values while preserving historical baseline versions
Workflow Templates and Per-Claim Duration Overrides
Given a workflow template defines default task durations When a new claim is instantiated from the template Then all claim tasks inherit the template durations and floats compute accordingly Given Ops updates a template default duration When a new claim is created after the update Then it inherits the updated duration, while existing claims remain unchanged Given Ops overrides a task estimate on a specific claim When saved Then the claim-level override takes precedence over the template value and slack recalculates within 2 seconds And GET /claims/{id}/tasks returns estimateSource="claim_override" for overridden tasks and "template" otherwise
Audit Log for Estimate Overrides and Automated Changes
Given an Ops user changes a task estimate from 4h to 6h When the change is saved Then an audit log entry is created with claimId, taskId, previousEstimateHours, newEstimateHours, userId, timestamp, source="manual_override", and optional reason And the entry is immutable and queryable via GET /claims/{id}/audit?type=estimate_override Given an NLP auto-completion reduces remaining duration to 0h When processed Then an audit log entry is created with source="nlp_auto_completion" capturing before/after values and the event id
Breach Risk Scoring
"As an Ops Lead, I want a breach risk score that identifies the tasks driving risk so that I can act before SLAs are missed."
Description

Calculate a dynamic breach risk score for each claim and for individual tasks by combining remaining duration, slack, dependency depth, current queue lengths, assignee capacity, and historical cycle-time distributions. Pinpoint the specific tasks that most contribute to breach risk and annotate them on the timeline. Refresh scores in near real time as events arrive from the workflow engine, NLP ingestion, or reassignment actions. Provide APIs and webhooks for downstream automation (e.g., auto-assign, notify broker) when thresholds are crossed. Start with a rules-plus-statistics model and allow pluggable ML models later, with model explainability fields for transparency to Ops.

Acceptance Criteria
Real-time Score Refresh on Workflow Events
Given a claim with persisted baseline breach risk scores When a workflow engine event (e.g., task status change or due date update), an NLP ingestion event (e.g., new fact extracted), or a reassignment action for any task on the claim is received Then both claim-level and task-level breach risk scores are recalculated and persisted within 5 seconds at P95 and 10 seconds at P99 from event receipt time And the recalculation uses the latest inputs for remaining duration, slack, dependency depth, current queue length, assignee capacity, and historical cycle-time distributions as of processing time And the recalculated scores are versioned with an incremented score_version and reference the triggering event_id And duplicate or replayed events are handled idempotently so that final persisted scores are not double-updated (last-write-wins by event timestamp) And the UI timeline and public APIs return the new scores within 2 seconds of persistence at P95
Risk Score Calculation Inputs and Behavior
Given fixed input values for remaining duration, slack, dependency depth, queue length, assignee capacity, and historical distribution parameters When the breach risk score is computed Then the score is deterministic for identical inputs and normalized to a 0–100 scale with one decimal place And holding other inputs constant, decreasing slack does not decrease risk; increasing remaining duration, dependency depth, or queue length does not decrease risk; increasing assignee capacity does not increase risk And if slack is less than or equal to 0, the claim-level risk score is greater than or equal to 80 And if projected completion is earlier than SLA by at least 25%, the claim-level risk score is less than or equal to 20 And the computed output includes fields: risk_score, risk_band (low|medium|high), score_version, computed_at, and input_snapshot_id
Task-Level Risk Attribution and Timeline Annotation
Given a claim with multiple in-flight tasks When the claim-level breach risk is computed Then the system produces a ranked list of top_contributors of size N=3 by default (configurable), each including task_id, contribution_pct (0–100), and primary_factors (e.g., slack, dependency_depth, queue_length, capacity, historical_variance) And the contribution list is sorted descending by contribution_pct with deterministic tie-breaking by task_id And the sum of contribution_pct across the listed tasks is less than or equal to 100 and greater than 0 And the timeline visually annotates each top contributor with its contribution_pct and current task risk score, and the annotations refresh within 2 seconds of new scores at P95 And an API endpoint returns the same contributor list for the claim (including task_id, contribution_pct, primary_factors)
Threshold-Based Webhook and API Triggers
Given default risk thresholds of 70 (warning) and 85 (critical), configurable per tenant and line of business When a claim-level or task-level risk score crosses a configured threshold upward Then a webhook POST is sent within 5 seconds at P95 and 10 seconds at P99 with payload including claim_id, optional task_id, score, threshold, direction, model_version, explanation fields, event_id, and computed_at And the webhook is HMAC-SHA256 signed with a shared secret and includes an idempotency key crossing_id; receivers can verify signature and deduplicate And retries occur with exponential backoff for up to 30 minutes on non-2xx responses; delivery is at-least-once And repeated oscillations around a threshold are debounced so that notifications fire only on boundary crossings (up/down) with a minimum 60-second quiet period per claim+task+threshold And public APIs expose current scores and the last 50 threshold events with pagination, enforce 100 RPS per tenant, and return 429 with Retry-After when rate limits are exceeded
Queue Length and Assignee Capacity Data Integration
Given integrations to queue length and assignee capacity data sources When risk scores are computed Then the latest queue length and capacity values used are no older than 60 seconds at P95; values older than 300 seconds are marked signal_stale=true And if sources are temporarily unavailable, the system uses last-known-good values for up to 15 minutes and applies an uncertainty penalty capped at +5 risk points, recorded in explanation fields And recovery from outage clears the penalty on next successful refresh And timeouts for external calls are bounded to 1 second per source with circuit-breaking to prevent cascading failures
Historical Cycle-Time Distribution Utilization
Given a task_type and line of business with sufficient historical data When computing projected remaining durations Then the model uses an empirical distribution built from the most recent 200 closed tasks within 180 days; if sample size < 50, it falls back to a global prior for that task_type And the distribution yields P50, P75, and P90 estimates used in risk calculations, with the source labeled as local or global in explanation fields And nightly at 02:00 UTC the distributions are recomputed; affected claims are re-scored within 10 minutes at P95 And on a synthetic dataset with known log-normal parameters, the estimated P90 has relative error ≤ 10%
Model Explainability and ML Plugin Interface
Given the default rules-plus-statistics model When a risk score is produced Then the API and timeline expose explainability fields including model_type, model_version, feature_contributions [{feature, value, contribution_pct}], top_reasons (human-readable), input_snapshot_id, score_confidence (0–1) And when an ML plugin is configured for a cohort or percentage rollout Then it can be enabled via configuration with A/B routing (e.g., 10% traffic) and must return the same output schema and 0–100 score range And P95 end-to-end inference latency for the ML plugin is ≤ 200 ms; on failure or timeout the system falls back to the default model within 250 ms with a fallback_reason recorded And every recalculation is audit-logged with claim_id, optional task_id, model_type, model_version, inputs_hash, output_hash, and computed_at
Bottleneck Detection
"As an Ops Lead, I want bottlenecks highlighted across the intake flow so that I can rebalance work and reduce delays."
Description

Identify systemic bottlenecks across the intake flow by monitoring queue depth, wait times, and utilization per step, role, and team. Attribute delay contributions to specific workflow stages and visualize congested nodes and edges on the timeline with quantitative metrics (e.g., average wait, WIP). Generate recommendations to rebalance workload (e.g., reassign to available adjusters, enable parallel reviews) and expose them to Ops within the Critical Path view. Ingest real-time telemetry from task router and capacity calendars; support configurable thresholds and business hours calendars to avoid false positives.

Acceptance Criteria
Real-time telemetry drives live bottleneck detection
Given task router emits task state changes and capacity calendars publish availability updates in real time When new events occur for steps in the intake workflow Then the ingestion service processes the events within 10 seconds and updates the metrics store And the Critical Path view reflects updated queue depth, wait time, WIP, and utilization within 15 seconds of event receipt And no more than 0.1% of events are dropped or out-of-order; out-of-order events are corrected within 60 seconds
Per-step/role/team metrics surface bottlenecks
Given the Ops Lead opens Critical Path for a portfolio with active claims When the view loads with the default trailing window of 7 calendar days filtered to business hours Then each workflow step shows: queue depth, average wait (business-hours), p90 wait (business-hours), WIP, and utilization by role and by team And utilization = assigned active time during business hours / scheduled capacity for the same window And metrics are available as tooltips and in a downloadable CSV with identical values
Threshold-based congestion highlighting
Given tenant-level thresholds are configured for queue depth, p90 wait, and utilization (e.g., Utilization High >= 85%, p90 wait >= 2 business hours) When a metric at a node or edge exceeds its threshold during business hours Then the node/edge is highlighted with a severity color and an icon indicating the metric in breach And outside business hours, highlights are suppressed unless breaches persist >= 2 business hours into the next shift And changing a threshold updates highlights on the view within 30 seconds
Delay attribution to workflow stages
Given a sample set of claims with known stage wait times and the SLA for intake completion When delay attribution is computed for the portfolio Then the sum of stage-level delay contributions equals the total observed delay vs. SLA within ±5% And each stage displays its contribution in minutes and percent of total And edges show handoff delay where applicable, separated from processing wait
Recommendation generation and exposure
Given a detected bottleneck where utilization for Team A is >= 90% and Team B has <= 60% utilization with matching skills When recommendations are generated Then the system produces at least one action with quantified impact (e.g., reassign 12 tasks to reduce p90 wait by 1.3 hours) And recommendations include prerequisites (skills, permissions), estimated time to relief, and confidence score And Ops can view recommendations inline in Critical Path and simulate apply to preview impact without committing
Business hours calendars and time zones
Given teams have distinct business hours, holidays, and time zones configured When metrics and thresholds are computed Then wait-time calculations exclude non-business hours and holidays for the responsible team at each stage And utilization uses scheduled capacity from the team's calendar And cross-time-zone handoffs use the sender’s calendar for wait until receipt and the receiver’s calendar thereafter
Next Best Action Guidance
"As an adjuster, I want the next best action with its impact shown so that I can keep the claim on track."
Description

Present adjusters with a prioritized list of next best actions derived from the current critical path, slack, and breach risk, including clear rationale (“reduces breach risk by 18%”) and one-click navigation to the task. Respect permissions and prerequisites, and suppress actions that require unavailable data or approvals. Show alternative actions when the top item is blocked and indicate the expected impact on claim cycle time. Track adoption and outcome metrics to refine guidance rules. Integrates with messaging/photo capture and NLP to suggest targeted data requests when missing artifacts are the blocking factor.

Acceptance Criteria
Prioritized Next Best Actions from Critical Path
Given an open claim with computed critical path, task dependencies, slack, and breach risk When the adjuster opens the claim workspace or the Next Best Actions panel refreshes Then the system displays a prioritized list of at least 3 actions sorted by estimated breach-risk reduction and cycle-time reduction And each action shows a rationale with a numeric percentage (e.g., "reduces breach risk by 18%") and an estimated cycle-time impact in hours or days And ties are broken deterministically by time-sensitivity, then by task effort And the list renders within 1.5 seconds in 95% of cases
Permission and Prerequisite Compliance
Given the current user's role and permissions, task prerequisites, and data availability When generating recommended actions Then actions requiring permissions the user lacks are excluded from the list And actions requiring unavailable data or pending approvals are suppressed and labeled with the suppression reason And the top visible action is executable by the current user without unmet prerequisites And suppression decisions are auditable via machine-readable reason codes attached to each hidden action
One-Click Navigation to Task Execution
Given a recommended action is visible with a primary call-to-action (CTA) When the adjuster clicks the CTA Then the app deep-links to the exact task screen with claim context and pre-filled parameters for that action And if the action involves messaging or photo capture, the appropriate composer opens with a pre-populated template and recipients And navigation completes within 800 ms in 95% of attempts And a task-started event is recorded with action ID, claim ID, user ID, and timestamp
Targeted Data Request via NLP for Missing Artifacts
Given the critical path identifies a missing artifact (e.g., proof-of-loss, photo set) as the current blocking factor When generating the next best action Then the system proposes a "Request [artifact]" action with a message template populated by NLP-extracted specifics of what is missing And the suggested communication channel respects claimant preferences (SMS/email/in-app) And the template includes at least one capture checklist item and a secure upload link And once the artifact is received and recognized by NLP, the action is removed from recommendations within 2 seconds
Fallback Alternatives and Blocked Indicator
Given the highest-impact recommended action is blocked by an unmet prerequisite or external dependency When the recommendations are displayed Then the blocked action is visibly labeled "Blocked" with the blocking reason And at least 2 alternative executable actions are shown with their expected breach-risk and cycle-time impact metrics And recommendations auto-refresh and clear the blocked status within 1 second after the dependency is resolved
Adoption, Outcome, and Feedback Loop Tracking
Given recommendations are displayed to a user When the user views, clicks, dismisses, completes, or ignores an action Then the system logs impression, selection, completion, and dismissal events with action ID, claim ID, user ID, timestamps, and time-to-completion And outcomes are attributed to claim-level cycle-time and breach outcomes And guidance rules are recalibrated at least daily using captured events And 95% or more of eligible events are available in analytics within 15 minutes of occurrence
Real-time Recalculation on State Change
Given the claim state changes (e.g., task completion, new photo/message arrives, approval received) When the change is persisted Then next best actions and their impact metrics are recomputed and refreshed in the UI within 2 seconds And the prior recommendation set is archived with a version ID and reason-for-change metadata And no action remains clickable once it becomes invalid due to the state change
Intervention Alerts & Escalations
"As an Ops Lead, I want alerts when breach risk spikes or the critical path is blocked so that I can reassign or escalate immediately."
Description

Generate configurable alerts for Ops Leads when breach risk exceeds thresholds, slack turns negative on critical tasks, or the critical path is blocked by unmet dependencies. Deliver notifications via in-app, email, and Slack/MS Teams with deep links into the affected timeline segment. Provide inline remediation controls to reassign tasks, adjust deadlines, or override gates with mandatory justification and full audit logging. Support quiet hours, deduplication, and escalation policies (e.g., escalate to Claims Director after 2 hours). Webhook support enables integration with external ticketing or paging systems.

Acceptance Criteria
Breach Risk Threshold Alert Triggering
Given a claim with breach risk scoring enabled and a threshold configured per line of business When the recomputed breach risk score transitions from below to above the configured threshold Then a single intervention alert is generated within 60 seconds tagged "Breach Risk" and associated to the claim and contributing task(s) And the alert payload includes claim_id, task_ids, current_score, threshold, severity, and timestamp And if the score falls back below the threshold, the alert auto-resolves and no new alert is produced until a new below→above transition occurs And changing the threshold retroactively triggers or resolves an alert only if it causes a transition across the threshold
Critical Path Condition Alerts (Negative Slack or Blocked Dependency)
Given a claim with an identified critical path When any task on the critical path has slack < 0 minutes Then an alert is generated within 60 seconds tagged "Negative Slack" and linked to the specific task And the alert includes slack_minutes, due_at, task_owner, and critical_path_position When any task on the critical path is blocked by an unmet dependency (predecessor not complete or gate not passed) Then an alert is generated within 60 seconds tagged "Blocked Dependency" listing the unmet dependency IDs and statuses And when the slack returns to ≥ 0 or the dependency is satisfied, the respective alert is auto-resolved
Multi-Channel Delivery with Deep Links
Given an alert is created for a claim When notification channels (in-app, email, Slack or MS Teams) are configured for the Ops Lead's team Then the alert appears in-app immediately and email plus Slack/Teams notifications are delivered within 60 seconds And each notification contains a deep link that, when clicked, opens ClaimFlow to the claim's Critical Path timeline focused on the affected task/segment And clicking the deep link from each channel is tracked and recorded on the alert with user_id, channel, and timestamp
Inline Remediation Controls with Mandatory Justification and Audit Logging
Given an Ops Lead opens an alert in ClaimFlow When they choose to reassign the affected task Then they must provide a non-empty justification before saving, and the task assignee is updated When they choose to adjust the task deadline Then they must provide a non-empty justification, the new due date cannot be in the past, and the deadline is updated When they choose to override a gate Then the action requires the "Override Gates" permission and a non-empty justification; otherwise the control is disabled And every remediation action writes an immutable audit log entry including alert_id, claim_id, actor_id, action_type, before_value, after_value, justification, timestamp (UTC), and source_ip, visible in the claim audit feed
Quiet Hours and Alert Deduplication
Given team quiet hours are configured with a team timezone When an alert is created during quiet hours Then in-app notifications are recorded but email and Slack/Teams deliveries are suppressed And upon quiet hours end, a single summary notification per channel is sent listing suppressed alerts with counts and deep links Given alerts share the same deduplication key (claim_id + trigger_type + task_id) When duplicate alerts occur within a 30-minute dedup window Then no additional outbound notifications are sent; instead, the existing alert's occurrence_count is incremented and last_seen_at updated
Escalation Policies and Acknowledgements
Given an alert type has an escalation policy configured (e.g., escalate to Claims Director after 2 hours if unacknowledged) When the alert remains unacknowledged for the configured duration Then an escalation notification is sent via all configured channels to the next-tier recipient(s) and the alert status updates to "Escalated" And multi-level escalation up to 3 tiers is supported with independent delays per tier And acknowledging the alert from any channel stops further escalations and records the acknowledging user and timestamp And all escalations and acknowledgements are captured in the audit log
Webhook Delivery to External Systems
Given webhooks are configured with a target URL and secret When an alert is created, updated, acknowledged, remediated, escalated, or resolved Then a webhook is sent with event_type, alert_id, claim_id, task_id, trigger_type, status, timestamps, and deep_link_url And the request includes an HMAC-SHA256 signature header computed over the payload using the shared secret And on 5xx responses the system retries with exponential backoff for up to 5 attempts; on 2xx the delivery is recorded as success And webhook delivery attempts and results are visible in an admin log, with a "Send test" action to validate configuration

Business Hours

Makes countdowns fair and compliant by honoring business calendars, local holidays, time zones, and waiting-on-claimant pauses. Shows clear ‘clock paused’ reasons and auto-resumes when conditions are met, reducing false alarms and audit disputes.

Requirements

Business Calendar Management
"As a claims operations admin, I want to define business hours and holidays for each office/region so that SLAs and countdowns reflect our real working schedule."
Description

Provide organization-level and region-level calendars to define business days, operating hours, company holidays, and ad-hoc closures. Support multiple calendars per tenant (e.g., by office, line of business, or team) with effective-dated exceptions and blackout periods. Calendars integrate directly with SLA timers, routing, and alerts so countdowns honor defined schedules across ClaimFlow.

Acceptance Criteria
Create Organization-Level Calendar
Given I am an admin with Calendar:Manage permission When I create a new organization-level calendar with name, time zone, business days, and per-day operating hours, and optionally mark it as default Then the calendar is saved, appears in the calendars list with the configured attributes, and its name is unique within the tenant And if marked default, it is flagged as the tenant default and replaces any previous default And an audit log entry records creator, timestamp (UTC), and all initial settings
Region-Level Calendar Override and Fallback
Given a tenant default calendar exists and a region-level calendar is configured for region "CA-West" When a claim is assigned to region "CA-West" Then SLA timers, due dates, and business-hour calculations for that claim use the "CA-West" region calendar And when a claim is assigned to a region without a specific calendar Then calculations fall back to the tenant default calendar And the calendar used is recorded on the claim for audit and reporting
Effective-Dated Exceptions and Blackout Periods
Given a calendar with standard business hours When I add an exception for a date range (e.g., 2025-12-24 13:00 to 2025-12-26 23:59 local) marking it closed Then those periods are treated as non-business time and excluded from SLA calculations And when I add a partial-day closure (e.g., 2025-07-03 12:00-17:00) Then only the specified window is excluded And when overlapping rules exist (standard hours, exceptions, blackout periods) Then precedence is Blackout > Exception > Standard, applied deterministically And the calendar view reflects the closures and their sources
Local Holidays and Recurrence Rules
Given a calendar with locale and time zone defined When I create a recurring holiday rule (e.g., "Thanksgiving: 4th Thursday of November, observed next weekday if weekend") Then the system computes and displays holiday dates for at least the next 5 years And observed dates are applied when the holiday falls on a weekend And I can add ad-hoc local holidays for a specific year that override recurrence for that date And these holidays are excluded from business time calculations
Time Zone and Daylight Saving Handling
Given a calendar in a time zone that observes DST When an SLA timer spans a DST transition (spring-forward or fall-back) Then counted business minutes do not skip or double-count due to the transition And all stored timestamps are in UTC and display in the calendar’s local time zone And business hours that cross midnight are correctly split across days for calculation and display
SLA Timer Pause/Resume and Clock-Paused Reasons
Given an active SLA timer on a claim using an assigned calendar When the claim status changes to Waiting on Claimant Then the SLA timer pauses immediately and displays reason "Clock paused: Waiting on Claimant" And when business hours end per the assigned calendar Then the SLA timer pauses with reason "Clock paused: Outside business hours" And when the claim returns to an in-progress status and business hours resume Then the timer resumes without losing previously accrued time And cumulative timing drift does not exceed ±1 minute per 24 hours of elapsed wall time And an audit trail records each pause/resume event with timestamp and reason
Multiple Calendars per Tenant with Assignment Rules and Fallback
Given calendars exist for Office, Line of Business, Team, and Region When an admin defines an assignment priority order (e.g., Claim-Specific Override > Team > Office > Line of Business > Region > Tenant Default) Then new claims are automatically bound to the highest-priority matching calendar based on their metadata And the assigned calendar is visible on the claim and editable only by users with Calendar:Override permission And changing assignment rules affects future claims only, unless a bulk re-evaluation job is executed explicitly And if no rules match, the tenant default calendar is applied And routing due dates and alert schedules for the claim are computed using the assigned calendar
Time Zone Aware SLAs
"As a claims manager, I want countdowns to automatically reflect the claim’s local time zone so that deadline alerts are accurate for my team and customers."
Description

Automatically resolve and apply the appropriate time zone to each claim and task based on configurable precedence (e.g., handling office, assigned adjuster, policyholder locale). Handle daylight saving changes and historical offsets to ensure accurate start/stop times, due dates, and escalations. Expose normalized UTC timestamps and localized display for consistency across ClaimFlow.

Acceptance Criteria
Time Zone Resolution by Precedence Chain
Given a precedence order [handling_office, adjuster, policyholder] and valid IANA TZ IDs for each source When a new claim is created and an intake task is generated Then the task SLA time zone is set from handling_office and the selected source and timeZoneId are audit-logged Given the precedence order is updated to [adjuster, policyholder, handling_office] When the next task is generated for the same claim with an assigned adjuster in a different time zone Then the task SLA time zone is set from adjuster and the selected source and timeZoneId are audit-logged Given one or more sources are missing When resolving the time zone Then the resolver falls back in the configured order and uses the first available source; if none are available, the system default time zone is applied and a warning is logged Given an active task with a running SLA When the precedence configuration is changed Then no existing timers change time zone until an explicit Recalculate SLA action is invoked and recorded in the audit log
Daylight Saving Transitions for SLA Timers
Given a task’s SLA is governed by a time zone that observes DST When the SLA timer crosses a DST start (spring-forward) boundary Then elapsed SLA minutes are counted continuously in UTC with no skipped or lost minutes, and the displayed local due time reflects the post-transition offset Given a task’s SLA is governed by a time zone that observes DST When the SLA timer crosses a DST end (fall-back) boundary Then elapsed SLA minutes are counted continuously in UTC with no double-counted minutes, and the displayed local due time reflects the post-transition offset Given a fixed-duration SLA of N business hours starting before a DST transition in the selected time zone When the due date is calculated Then the dueAtUtc equals startAtUtc plus the computed business duration, and dueAtLocal presents the correct wall-clock local time consistent with the new offset after transition
Historical Offset Accuracy for Backdated Events
Given claim and task events imported with local timestamps in prior years for a region with historical offset changes When normalizing to UTC and computing SLA start/stop/due/escalation times Then offsets are resolved using historical time zone database rules for the event date, not the current offset Given a local timestamp and timeZoneId from the event’s context When round-tripping (local -> UTC -> local) Then the resulting local timestamp equals the original wall-clock time and the same timeZoneId, and the UTC value remains identical across round-trip Given an event date prior to a known time zone rule change (e.g., policy effective in 2018) When SLA durations are computed Then the calculation uses the 2018 offset rules for that zone and matches an external reference calculation to within 1 minute
UTC Normalization and Localized Display Consistency
Given any SLA timestamp (start, pause, resume, due, escalation) When retrieved via API Then each includes: utc (ISO 8601 with Z), local (ISO 8601 with offset), timeZoneId (IANA), and timeZoneSource, with millisecond precision Given a list of tasks across multiple time zones When sorted by utc ascending Then the order reflects true chronological sequence regardless of local time zone Given a user viewing a task in the UI with a different personal display time zone than the task’s SLA time zone When the timestamps are rendered Then the primary display uses the user’s display time zone while a tooltip or detail reveals the task’s native local time, timeZoneId, and source, and both map to the same utc
Cross-Time-Zone Reassignment and Recalculation
Given a task with SLA time zone resolved from handling_office (Zone A) When the task is reassigned to an adjuster in Zone B and precedence is [adjuster, policyholder, handling_office] Then new tasks created after reassignment resolve to Zone B, while the existing task’s timer remains in Zone A Given the same reassigned task When an authorized user triggers Recalculate SLA Then the task’s SLA time zone switches to Zone B, due and escalation times are recomputed, an audit entry records fromZone, toZone, actor, and timestamp, and prior alerts are invalidated and re-evaluated Given escalations configured by business hours in the task’s SLA time zone When the task’s SLA time zone changes via recalculation Then future escalation schedules are regenerated using the new zone’s business calendar and offsets
Business Hours and Holiday Integration by Time Zone
Given business hours and local holidays are configured per IANA time zone for offices When computing SLA durations for a task using Zone X Then only the business hours of Zone X are counted and local holidays for Zone X are excluded from the countdown Given a task enters a waiting-on-claimant pause during business hours in Zone X When the pause is applied Then the SLA timer stops immediately, a visible reason shows “Clock paused: Waiting on claimant,” and a resume event automatically restarts the timer without changing the time zone Given an SLA spans a local holiday and crosses midnight in Zone X When the due date is calculated Then no business minutes are counted on the holiday, partial days are pro-rated by Zone X business hours, and the due time aligns to the next open window in Zone X
Business-Hours Countdown Engine
"As an adjuster, I want task timers that count only working hours so that I’m not penalized for nights, weekends, or holidays."
Description

Compute SLA timers that count only within defined business hours, excluding nights, weekends, and holidays. Support partial-day calculations, grace windows, and threshold-based warnings. Provide APIs and UI components to display remaining time, due dates, and percent complete. Persist timer state for resilience and ensure idempotent recalculation when inputs (calendar, time zone, pauses) change.

Acceptance Criteria
Business-hours countdown across nights, weekends, holidays
Given a claim with an SLA target of 16 business hours and a business calendar (Mon–Fri 09:00–17:00, America/New_York) with a holiday on 2025-11-27 When the timer starts at 2025-11-26T16:30:00-05:00 Then dueAt equals 2025-12-01T12:30:00-05:00 And only minutes within 09:00–17:00 on non-holiday weekdays are counted And weekend and holiday minutes are excluded from remaining and percentComplete And if startTime is outside business hours, counting begins at the next opening minute And remainingBusinessMinutes + elapsedBusinessMinutes = totalBusinessMinutes at all times
Partial-day SLAs with business-minute grace window
Given business hours Mon–Fri 09:00–17:00 in America/New_York and a 4-business-hour SLA with a 10-business-minute grace window When the timer starts at 2025-09-30T15:30:00-04:00 Then dueAt equals 2025-10-01T11:30:00-04:00 And the status is "In Grace" from 2025-10-01T11:30:00-04:00 to 2025-10-01T11:40:00-04:00 (business minutes) And the status becomes "Overdue" only after the grace window elapses within business hours And percentComplete is capped at 100% during the grace window And remaining and overdue indicators never count non-business minutes
Time zone and DST correctness
Given a claim timeZone of America/Los_Angeles with business hours 09:00–17:00 local and an assigned holiday calendar for that locale When computing dueAt across DST changes (spring-forward 2025-03-09 and fall-back 2025-11-02) Then business minutes are counted only within 09:00–17:00 local and never double-counted or skipped due to DST transitions And per business day exactly 480 minutes are counted when the day is not a holiday or weekend And all API timestamps are ISO 8601 with offsets (e.g., 2025-10-01T11:30:00-07:00) And the UI displays times in the claim’s time zone with an explicit TZ label (e.g., PT) And the correct holiday set for the claim’s calendar is applied to exclusion rules
Pause with reason and auto-resume on event
Given an active timer with dueAt computed When a pause is set with reason = "Waiting on claimant" at 2025-10-02T14:05:00-04:00 Then status becomes Paused, counting stops, and the UI shows "Clock paused — Waiting on claimant" with the pausedSince timestamp And pausedDuration increases while paused and is excluded from percentComplete and dueAt calculations And when a resume event (type = "document_received") arrives or a pauseUntil condition is met, status becomes Active and counting resumes automatically And overlapping or duplicate pause events are canonicalized so no paused minute is excluded more than once And an audit entry is recorded for pause/resume with actor, reason, and timestamps
Threshold-based warnings and notification idempotency
Given warning thresholds at 50%, 75%, and 90% of totalBusinessMinutes and an active timer When percentComplete crosses a threshold during Active status Then emit exactly one notification per threshold per claim with idempotencyKey = {claimId}:{threshold}:{dueAt} And do not emit threshold notifications while Paused; evaluate and emit upon resume if the condition still holds And recomputation or retries must not re-emit an already sent threshold notification And webhooks are delivered with exponential backoff up to 8 attempts on non-2xx responses And in-app banners and activity feed entries reflect the highest crossed threshold only once
API and UI exposure of SLA timer state
Given the SLA timer service is running When GET /api/v1/slas/{claimId} is called Then respond 200 with fields: status (Active|Paused|InGrace|Overdue), dueAt, remainingBusinessMinutes, totalBusinessMinutes, percentComplete (0–100), timeZone, pausedReason (nullable), inGrace (boolean), updatedAt, etag And respond 404 when claimId is unknown And ETag changes only when any returned field changes; If-None-Match yields 304 when unchanged And p95 latency ≤ 200 ms at 100 RPS for cached reads and ≤ 400 ms for recompute reads And the UI countdown shows: remaining HH:MM during Active, "Clock paused — {reason}" during Paused, "Overdue by HH:MM" during Overdue, and an explicit time zone label And UI updates no more than once every 30 seconds and meets WCAG 2.2 AA contrast with aria-live="polite" announcements
Persistence, recovery, and idempotent recalculation
Given timer state is persisted with an event-sourced history of starts, pauses, resumes, and configuration changes When the service restarts unexpectedly Then the last known state is restored within 5 seconds and matches a full recomputation from history And a recompute command executed multiple times with identical inputs yields identical dueAt, percentComplete, status, and no duplicate notifications And nightly reconciliation recomputes from history; discrepancies > 0 are logged with a diff and no more than 0.1% of timers show discrepancies And state transitions are recorded with monotonic sequence numbers; paused intervals are normalized to non-overlapping ranges And external notifications are exactly-once by enforcing idempotencyKey uniqueness in the outbox
Auto Pause/Resume Rules Engine
"As a claims supervisor, I want timers to pause automatically with a clear reason and resume when criteria are met so that follow-ups and alerts are fair and compliant."
Description

Enable rule-driven automatic pause and resume of SLA timers based on conditions such as outside business hours, waiting on claimant response, awaiting third-party documents, or force-majeure closures. Monitor events from messaging, document ingestion, and workflow states to detect pause/resume triggers. Record standardized reason codes, apply precedence when multiple conditions exist, and ensure immediate auto-resume when criteria are satisfied.

Acceptance Criteria
Auto-Pause Outside Business Hours
Given an active claim with an SLA timer and an assigned business calendar and time zone When the current time transitions into closed business hours or a designated local holiday Then the SLA timer pauses within 5 seconds and the current reason is set to OUT_OF_BUSINESS_HOURS And an audit event is recorded with timestamp, reason code, and source=calendar And the timer remains paused until the next opening time on the calendar And upon the next opening time, the SLA resumes within 5 seconds and total paused duration reflects the closed interval with drift <= 1 second And if the claim is created during closed hours/holiday, the SLA timer initializes in paused state with reason OUT_OF_BUSINESS_HOURS
Auto-Pause Waiting on Claimant Response
Given an active claim with an SLA timer And an outbound message or task is issued that is marked requires_claimant_response When that message is dispatched or the task state changes to Waiting on Claimant Then the SLA timer pauses within 5 seconds with reason AWAITING_CLAIMANT and records the triggering message/task ID And the pause persists across restarts until a matching claimant response is received on the same thread or the task is completed When a claimant reply is ingested that correlates to the pending request or the task state exits Waiting on Claimant Then the SLA resumes within 5 seconds and the reason is cleared, with audit events for resume and total paused duration updated And unrelated inbound messages do not resume the SLA
Auto-Pause Awaiting Third-Party Documents
Given an active claim with an SLA timer and a workflow step that specifies required third-party documents by type When the workflow state enters Awaiting Third-Party Documents with an enumerated list of required types outstanding Then the SLA timer pauses within 5 seconds with reason AWAITING_3RD_PARTY and audit logs include the outstanding types And the timer remains paused until all required document types are ingested and classified by the document engine When the last required document type is ingested and validated Then the SLA resumes within 5 seconds, reason is cleared, and the total paused duration is updated with drift <= 1 second And manual override to mark a document received immediately resumes the SLA and records actor and justification
Auto-Pause for Force Majeure Closures
Given an active claim with an SLA timer and a jurisdiction/team assignment tied to a business calendar When an admin-configured force majeure closure is active for that calendar/jurisdiction Then the SLA timer pauses within 5 seconds with reason FORCE_MAJEURE and the closure ID recorded in the audit trail And claims assigned to unaffected calendars/jurisdictions do not pause When the force majeure window ends Then the SLA resumes within 5 seconds and the reason is cleared, with the paused duration matching the closure window with drift <= 1 second
Time Zone, DST, and Local Holiday Handling
Given a claim assigned to a business calendar with a specific IANA time zone When evaluating open/closed status across a Daylight Saving Time transition Then the SLA pause/resume boundaries honor the local wall-clock business hours and shift correctly at the DST change with no double-counting or gaps And local public holidays defined on the calendar are treated as fully closed days (or partial hours if configured) And when the claim is reassigned to a different calendar/time zone, subsequent evaluations use the new calendar from the effective reassignment timestamp
Reason Codes and Audit Trail Integrity
Given any pause or resume event fired by the engine Then an immutable audit record is written containing: event_type (pause/resume), reason_code (from the controlled list: OUT_OF_BUSINESS_HOURS, AWAITING_CLAIMANT, AWAITING_3RD_PARTY, FORCE_MAJEURE), timestamp (UTC), effective_local_time, source (calendar|messaging|workflow|document_ingestion|admin), correlation_id (if applicable), actor (system|user_id), and previous_timer_state And the cumulative paused duration is recalculated deterministically after each event And the audit log is retrievable via API with filters by claim_id, date range, reason_code, and source
Precedence and Overlapping Conditions Resolution
Given multiple pause conditions become true concurrently or in overlapping intervals Then the engine applies precedence FORCE_MAJEURE > AWAITING_CLAIMANT > AWAITING_3RD_PARTY > OUT_OF_BUSINESS_HOURS, setting only the highest active reason as current while stacking the rest And audit events capture activation/deactivation for each condition and the current reason at any moment is deterministic When the highest-precedence condition clears while lower-precedence conditions remain active Then the SLA remains paused and the current reason transitions to the next-highest active condition within 5 seconds When no pause conditions remain active Then the SLA resumes within 5 seconds and the reason is cleared
Clock Pause Reason Display
"As an auditor, I want to see exactly why and when a timer paused so that I can validate compliance without manual investigation."
Description

Surface clear, auditable explanations for paused timers directly on claim and task views, including reason code, source event, start time, and next resume condition. Provide tooltips and a detailed drawer for history within the current SLA cycle. Show a prominent ‘clock paused’ banner in lists and detail pages and ensure accessibility-compliant labels for assistive technologies.

Acceptance Criteria
Paused Banner on Claim/Task Detail
Given a claim or task with an active paused SLA timer When the user opens the claim or task detail view Then a prominent banner labeled "Clock paused" is displayed at the top of the page And the banner displays reason code, human-readable reason label, source event, pause start time with timezone, and next resume condition summary And the running countdown is hidden and replaced with a paused state indicator And the banner remains visible until the pause ends And when no pause is active, no paused banner is shown
Paused Indicator in Lists
Given a list view of claims or tasks When a row has an active paused SLA timer Then a "Clock paused" badge appears in the row’s SLA column and is keyboard focusable And the badge shows a concise reason summary and start time And rows without an active pause show no paused badge And the badge exposes full details via the tooltip trigger
Pause Details Tooltip
Given a visible paused banner or badge When the user hovers or focuses the info icon or badge Then a tooltip opens within 250 ms and closes on Escape or blur And the tooltip content includes: reason code, source event, pause start timestamp (with timezone), next resume condition And the tooltip is accessible via keyboard (Tab/Shift+Tab) and screen readers via aria-describedby, with no focus trap And the tooltip positions within the viewport without clipping on small screens
SLA Cycle Pause History Drawer
Given a claim or task within the current SLA cycle When the user selects "View pause details" from the banner or badge Then a drawer opens displaying a chronological list (newest first) of all pause/resume events within the current SLA cycle And each entry shows reason code, source event, start time, end time (or "Active"), and duration And the drawer header summarizes total paused duration in the current cycle And timestamps are shown in the user’s local time zone with explicit TZ abbreviation
Auto-Resume State Update
Given an active paused timer with a defined next resume condition When the condition is satisfied by calendar/business-hour logic or a triggering event Then the UI removes the "Clock paused" banner/badge and reinstates the live countdown within 10 seconds of the backend status change And the history drawer receives a new resume event with end time and duration And the tooltip content updates to indicate the pause ended And no manual page refresh is required
Accessibility Compliance
Rule: All paused banners, badges, tooltips, and drawer controls are reachable via keyboard (Tab order follows DOM, focus indicators visible) Rule: Screen reader labels announce "Clock paused", reason code, source event, start time, and next resume condition; dynamic changes are announced via aria-live="polite" Rule: Color contrast for text and icons in paused UI elements meets WCAG AA (>= 4.5:1 for normal text) Rule: Controls have accessible names and roles; tooltips are associated via aria-describedby Rule: No information is conveyed by color alone; equivalent text is present
SLA Pause/Resume Audit Trail
"As a compliance officer, I want a complete audit trail of SLA timer events so that disputes can be resolved quickly and regulators can verify adherence."
Description

Maintain an immutable, tamper-evident log of all timer state changes with timestamps, actor (system or user), reason codes, related artifacts (message IDs, document IDs), and prior/next states. Support filtering, export to CSV/JSON, and API access for downstream BI and regulatory reporting. Enforce data retention policies and time-synchronized entries in both local time and UTC.

Acceptance Criteria
Pause triggered by claimant reply creates complete audit entry
Given a running SLA timer on claim CF-123 in timezone America/New_York and a claimant SMS reply (messageId=MSG-789) auto-pauses the timer outside business hours When the system processes the pause event Then an audit entry is appended containing: claimId, timerId, priorState=Running, nextState=Paused, reasonCode=WAITING_ON_CLAIMANT, actorType=System, actorId=ClaimFlow.BusinessHours, artifactIds=[MSG-789], businessCalendarId, timestampUTC (ISO 8601 Z), timestampLocal (ISO 8601 with offset and IANA zone), and prevEntryId if any And the entryId is unique and the combination (claimId,timerId,entryId) is immutable And the entry is visible in the audit trail UI within 2 seconds of event time And the 'clock paused' reason shown in UI matches reasonCode and includes a link to messageId MSG-789
Manual resume during business hours is accurately recorded
Given a paused SLA timer due to WAITING_ON_CLAIMANT and business hours have started When an adjuster user U-456 clicks Resume in the UI Then an audit entry is appended with priorState=Paused, nextState=Running, reasonCode=MANUAL_RESUME, actorType=User, actorId=U-456, and no message/document artifacts And the entry includes timestampUTC and timestampLocal fields populated and consistent with the user's selected timezone And the timer resumes and the next tick event generates no additional pause/resume audit entries
Audit trail storage is append-only and tamper-evident
Given existing audit entries for a timer When a privileged admin attempts to edit or delete an entry via UI or API Then the operation is rejected with HTTP 403 and no mutation occurs And each entry includes fields hash and prevHash forming a cryptographic chain over immutable fields And calling GET /api/audit/claims/{claimId}/timers/{timerId}/verify returns 200 with chainValid=true for unaltered data And any offline modification causes verify to return chainValid=false and the UI displays a "tamper suspected" banner for the affected claim
Dual timestamps are synchronized and consistent across DST and time zones
Given the system is synchronized to an NTP source When an audit entry is created in America/Los_Angeles during a DST transition window Then the entry includes timestampUTC with Z suffix and timestampLocal with offset and zoneId=America/Los_Angeles And the absolute instant represented by both timestamps is identical (difference <= 1 second) And entries for a single timer have non-decreasing timestampUTC ordering
Filter audit trail entries by common dimensions in UI
Given 5,000 audit entries across multiple claims When a user filters by [claimId=CF-123, dateRangeUTC, actorType=System, reasonCode=WAITING_ON_CLAIMANT, stateChange=Running->Paused, artifactId=MSG-789] Then the results include only matching entries, with total count displayed And the first page (50 rows) renders within 2 seconds and pagination is available And clearing filters restores the unfiltered view And exporting from the filtered view produces a file with the same records and order
Export filtered audit trail to CSV and JSON with integrity metadata
Given a filtered result set of N entries When the user exports to CSV Then a UTF-8 CSV is downloaded named audit-<claimId>-<YYYYMMDD>-<HHmmssZ>.csv with header columns: entryId, claimId, timerId, priorState, nextState, reasonCode, actorType, actorId, artifactIds, businessCalendarId, timestampUTC, timestampLocal, hash, prevHash And exporting to JSON produces an NDJSON file with the same fields and order And both files include an accompanying .sha256 checksum file and their checksums match And exports are limited to 250k records per file, with a continuation token provided when exceeded
REST API access and retention policy enforcement
Given an API client with read scope audit:read When it calls GET /api/audit/entries with filters and pagination params (limit<=500, cursor) Then the service returns 200 with items, nextCursor, and totalCount metadata, honoring filters and sort=timestampUTC asc|desc And responses include both timestampUTC and timestampLocal and are gzip-compressed when Accept-Encoding: gzip is set And entries older than the configured retention period (e.g., 7 years + 90 days) are excluded unless on legal hold And when a legal hold tag is applied to claim CF-123, purge jobs skip those entries and a retentionAction audit record is added when holds are applied/removed And a daily purge job deletes expired entries, emitting a summary report and append-only purge audit entries; attempting to retrieve purged entries returns 404
Workflow SLA Orchestration
"As a workflow designer, I want to attach business-hour SLAs and pause rules to workflow steps so that routing and escalations behave consistently."
Description

Integrate business-hour SLAs and pause rules into ClaimFlow’s configurable workflows. Allow each step to declare SLA targets, calendars, applicable time zones, pause criteria, and escalation rules. Emit workflow events on threshold crossings (e.g., 50%, 80%, overdue) to trigger routing, notifications, and auto-reassignment. Provide reusable templates for common claim types and backward-compatible migration for existing workflows.

Acceptance Criteria
Step SLA Timer Honors Business Calendars and Time Zones
Given a workflow step configured with SLA target 8 business hours, business hours 09:00–17:00, calendar "US-CA" with Monday 2025-09-01 marked as a holiday, and time zone "America/Los_Angeles" And the step is started on Friday 2025-08-29 at 16:00 PT When the SLA dueAt is calculated Then dueAt is Tuesday 2025-09-02 at 16:00 PT And elapsed/remaining time counts only business hours, excluding weekends and holidays And if a step-level time zone is omitted, the claim time zone is used; if the claim time zone is omitted, the org default time zone is used
SLA Pause and Auto-Resume on Waiting-on-Claimant
Given a step with pause rule code "WOC" triggered by an outbound document request and a visible pause reason "Clock paused: Waiting on claimant" And the SLA has 6 business hours remaining at the moment of pause When the pause is engaged Then the SLA clock stops advancing and no threshold events are emitted during the pause And an audit entry records pause start timestamp, reason code, actor, and remaining minutes When the required documents are received and the system detects completeness or an adjuster clicks Resume Then the SLA clock resumes with exactly 6 business hours remaining and an audit entry records resume timestamp and actor
Threshold Crossing Events at 50%, 80%, and Overdue
Given a step with SLA target 16 business hours When elapsed time first reaches 8h, 12.8h, and exceeds 16h in business time Then events "sla.threshold.50", "sla.threshold.80", and "sla.overdue" are each emitted exactly once for that step And each event is published within 60 seconds of the threshold crossing and contains: claimId, workflowId, stepId, calendarId, timeZone, dueAt (ISO-8601 with zone), elapsedBusinessMinutes, remainingBusinessMinutes And if the step is paused before a threshold is reached, no event is emitted until after resume and the next crossing occurs
Escalations Trigger Notifications and Auto-Reassignment
Given escalation rules for a step: on "sla.threshold.80" notify role "Supervisor-West" by in-app and email during business hours; on "sla.overdue+120m" auto-reassign to queue "Adjusters-West" and post a system comment And the step hits 80% at 19:30 local time (outside business hours) When the "sla.threshold.80" event is emitted Then notifications are queued and delivered at the next business open, and delivery is logged with timestamp and recipients When the step remains overdue for 120 business minutes Then the assignee is auto-reassigned to "Adjusters-West", a system comment is added to the claim, and the reassignment is recorded in audit with previous and new assignee
Template-Driven SLA Configuration for Common Claim Types
Given a published template "Auto-Property-Damage v1.2.0" that defines step-level SLA targets, calendars, time zones, pause rules, and escalation rules When a new workflow is created from this template for a claim Then the workflow instance inherits the template's SLA configuration and validates successfully, and the template version "v1.2.0" is recorded on the instance And local overrides to SLA fields are permitted only on steps marked overridable, and validation rejects overrides on non-overridable steps with a clear error And template changes require a new semantic version; editing a published version is disallowed
Backward-Compatible Migration for Existing Workflows
Given existing workflows created before SLA orchestration with no SLA configuration When the migration runs Then those workflows continue to operate without SLA timers, thresholds, or escalations, and the UI displays "SLA not configured" for their steps And no overdue notifications or events are generated for them until SLA configuration is explicitly added When a template is updated to include SLA configuration and published as a new version Then only new workflow instances created from the new version receive SLA features; in-flight instances remain unchanged unless a controlled migration flag "applySLAToInflight=true" is set by an admin And applying controlled migration logs a before/after snapshot of SLA fields per step and sends a confirmation notice to the admin

Capacity Sync

Syncs workload with real-time team availability, OOO status, and queue saturation to auto-reprioritize at-risk items. Suggests coverage swaps, split assignments, or vendor overflow before a breach occurs, cutting firefighting and idle time.

Requirements

Real-time Availability & OOO Ingestion
"As a claims operations manager, I want real-time adjuster availability and OOO data in ClaimFlow so that Capacity Sync can route work only to available staff."
Description

Ingest and normalize real-time availability, OOO, shift schedules, and time-zone data from calendar platforms (Google/Microsoft), HRIS PTO feeds, and Slack/Teams presence into a unified availability model per user. Provide minute-level refresh with caching and exponential backoff, conflict resolution for overlapping events, partial-day OOO handling, and grace windows for status transitions. Enforce RBAC-based visibility, store minimal PII, and support time-bound manual overrides. Expose normalized availability via an internal API to the Capacity Sync engine with retries, health checks, and alerting on stale data.

Acceptance Criteria
Calendar Availability Aggregation (Google & Microsoft)
- Given a user connected to Google and Microsoft calendars, When a new Busy or OOO event is created or updated in either source, Then the unified availability is updated within 60 seconds of the source change. - Given duplicate events detected across sources (same iCal UID or identical start/end within 5 minutes), When aggregation runs, Then only one normalized availability block is produced. - Given an all-day OOO event, When normalized, Then the user's availability is Unavailable for the full local calendar day. - Given events marked Free or Tentative, When normalized, Then they do not reduce availability unless explicitly marked Busy or OOO. - Given source events in varying time zones, When normalized, Then intervals are stored in the user's primary time zone with UTC offsets preserved.
HRIS PTO Feed Ingestion and Normalization
- Given an approved PTO entry in the HRIS feed, When ingested, Then the user's availability shows Unavailable for the PTO interval within 60 seconds of receipt. - Given a PTO cancellation or modification in the HRIS feed, When processed, Then the corresponding normalized interval is removed or updated within 60 seconds. - Given a partial-day PTO (e.g., 13:00–17:00 local), When normalized, Then only that interval is marked Unavailable and other hours remain unaffected. - Given an HRIS PTO entry with a time zone, When normalized, Then the interval is converted to the user's primary time zone with offsets preserved.
Slack/Teams Presence Integration with Grace Windows
- Given a user's presence transitions to Away or Offline, When a 5-minute grace window is configured, Then availability changes to Unavailable only if the state persists for at least 5 consecutive minutes. - Given presence returns to Active within the grace window, When evaluated, Then no availability change is published. - Given a user sets Do Not Disturb, When normalized, Then the user's availability is treated as Unavailable for routing during the DND interval.
Overlapping Event Conflict Resolution
- Given overlapping intervals from different sources, When one interval is HRIS PTO and another is calendar Busy, Then HRIS PTO takes precedence in the normalized availability. - Given overlapping OOO and Busy events, When normalized, Then OOO takes precedence over Busy. - Given overlapping intervals of equal precedence, When normalized, Then the union of intervals is applied so no gaps exist in unavailability. - Given a time-bound manual override exists that overlaps any intervals, When resolving conflicts, Then the manual override takes highest precedence for its duration.
Partial-Day OOO and Time-Zone-Aware Shift Schedules
- Given a user with a shift 09:00–17:00 America/New_York, When a partial-day OOO 13:00–15:00 is ingested, Then availability is Unavailable from 13:00–15:00 local and remains Available for the rest of the shift. - Given events created in a different time zone than the user's primary, When normalized, Then intervals reflect correct absolute times in the user's primary time zone with proper DST handling. - Given a DST transition day (spring forward or fall back), When a shift or OOO spans the transition, Then the interval boundaries account for the offset change without duplicating or skipping an hour.
RBAC Visibility, Minimal PII, and Time-Bound Manual Overrides
- Given a Manager role requests a user's availability, When data is returned, Then only normalized intervals and status are visible; event titles, descriptions, and attendees are neither stored nor returned. - Given a Non-Privileged role requests another user's availability, When enforced, Then access is denied with HTTP 403 and no data is leaked. - Given an Admin or authorized service account sets a manual override, When saved, Then an explicit start and end timestamp is required and the override auto-expires at the end time. - Given any create, update, or delete of manual overrides, When committed, Then an audit log entry is recorded with actor, timestamp, target user, change type, and expiry.
Internal Availability API with Retries, Health Checks, and Stale Data Alerting
- Given the Capacity Sync engine requests GET /internal/availability/v1/users/{id}, When data is fresh, Then the API returns 200 with normalized intervals and a last_updated timestamp no older than 60 seconds. - Given transient upstream failures during refresh, When retries occur, Then exponential backoff is used (initial 1s, doubling up to 32s, max 5 attempts) without blocking existing cached responses. - Given repeated identical requests within 30 seconds and no upstream changes, When served, Then responses are returned from cache and last_updated reflects the most recent successful source change. - Given data freshness exceeds 5 minutes, When /internal/availability/health is checked, Then status is unhealthy and an alert is sent to the on-call channel. - Given retries are exhausted and data cannot be refreshed, When a client requests availability, Then the API returns 503 with a Retry-After header and includes the last known good snapshot with a stale=true indicator.
Workload & SLA Risk Scoring
"As a claims manager, I want live workload and SLA risk scores so that I can identify at-risk items before breaches occur."
Description

Calculate per-user and per-queue capacity and saturation using current assignments, task complexity weights, remaining SLA time, and forecasted intake. Produce a normalized risk score and at-risk item list with configurable thresholds and weighting, updating continuously as availability changes. Support part-time schedules, skill tags, license/territory constraints, and line-of-business rules. Publish risk events to downstream consumers and provide API endpoints and widgets for visibility.

Acceptance Criteria
Real-Time Per-User Capacity Score Calculation
Given a user with active assignments each having a complexity weight and remaining SLA time And the user has an availability factor (e.g., 1.0 FTE, 0.5 FTE) within current working hours And the normalized risk scale is configured to 0–100 When the risk engine evaluates the user Then it computes current capacity and saturation using assignment weights, SLA remaining time, and availability And returns a normalized risk score between 0.00 and 100.00 with two-decimal precision And persists the score with a timestamp to the risk store And recalculates and updates the score within ≤30 seconds of any change to assignments or availability
Per-Queue Saturation and At-Risk List Generation
Given a queue with active items each having complexity weights and remaining SLA time And an at-risk threshold is configured (e.g., score ≥70) with a maximum list size When the risk engine evaluates the queue Then it calculates a saturation percentage for the queue And produces an at-risk item list including only items meeting or exceeding the threshold And orders the list by highest risk score then earliest SLA breach time And exposes the total count and pagination metadata when more than the maximum list size And updates the list within ≤30 seconds after any item, assignment, or availability change affecting the queue
Configurable Thresholds and Weighting Application
Given custom weighting parameters are configured for complexity, remaining SLA time, forecasted intake, and availability And custom thresholds are defined for Low/Medium/High/Critical risk bands When the risk engine evaluates users and queues Then computed scores reflect the configured weights and band thresholds And changing any weight or threshold via configuration API results in updated scores within ≤60 seconds And all configuration changes are audit-logged with user, old value, new value, and timestamp And default weights and thresholds are applied when no tenant-specific configuration exists
Part-Time Schedules and Out-of-Office Handling
Given a user with a part-time schedule (e.g., 0.6 FTE) and defined working hours And an Out-of-Office period is scheduled or activated immediately When the risk engine evaluates the user's capacity and saturation Then effective availability reflects the part-time factor during working hours and 0 outside working hours And during OOO periods the user's availability is 0 and their risk reflects inability to progress assigned items And queue saturation and at-risk lists update within ≤30 seconds to reflect the user's OOO state And OOO windows in the future do not affect current scores until they start
Skill Tags, License/Territory, and Line-of-Business Constraints
Given tasks tagged with required skills, licenses/territories, and line-of-business And a user has a defined set of skills, licenses/territories, and line-of-business eligibility When the risk engine evaluates user capacity and queue saturation Then only tasks the user is eligible to handle contribute to that user's saturation and risk score And ineligible tasks are excluded from the user's scoring but included in queue-level scoring for eligible pools And queue saturation metrics consider eligibility constraints when determining at-risk items per eligible cohort
Forecasted Intake Integration with SLA Sensitivity
Given a forecast feed providing expected intake volume, probability, and complexity by queue and time window And a fallback policy is configured for forecast outages When the risk engine evaluates future risk for users and queues Then forecasted workload is incorporated into scores weighted by probability and time-to-arrival relative to SLA remaining time And scores degrade gracefully using the last known forecast for up to 2 hours when the feed is unavailable, then exclude forecast thereafter And recalculated risk reflects forecast updates within ≤60 seconds of receiving new forecast data
Risk Event Publishing and API/Widget Visibility
Given risk thresholds for event emission are configured (e.g., crossing into High or Critical) When a user or queue score crosses a configured threshold or changes band Then a risk event is published within ≤10 seconds to the event bus with payload including tenant, subject type, subject ID, old band, new band, score, timestamp, and correlation ID And a REST API provides endpoints to retrieve current scores and at-risk lists for users and queues with filters by team, skill, territory, and line-of-business And API responses include schema: score (0–100), band, saturation %, lastUpdated, and atRiskItems[]; and meet performance SLO p95 ≤300 ms for reads under 100 items And an embeddable widget renders the same data and refreshes at ≤30-second intervals
Auto-Reprioritization & Queue Update
"As an adjuster, I want my task queue to auto-reprioritize based on urgency so that I always work on the most time-critical items."
Description

Automatically reorder task queues when risk thresholds are met, elevating items nearing SLA breach and de-emphasizing low-risk work. Apply idempotent updates to workflow tasks while preserving ownership and locks, and throttle reorders to prevent churn. Notify affected users in-app and via email/Slack with concise change reasons. Provide per-team policies, feature flags, manual freeze controls, and one-click rollback with pre/post order snapshots recorded.

Acceptance Criteria
Auto-Reprioritization at SLA Risk Threshold
Given the feature flag is enabled for the team and risk thresholds are configured And a queue is not frozen When an item's computed SLA risk score crosses the team-defined at-risk threshold Then the item is elevated ahead of lower-risk items in the same queue within 30 seconds And items under the low-risk threshold are de-emphasized behind medium- and high-risk items And items with equal risk maintain their prior relative order (stable sort) And a before/after position snapshot and audit record (including scorer version and timestamp) are stored
Idempotent Reorder While Preserving Ownership and Locks
Given the same queue state is processed more than once within a 10-minute window When auto-reprioritization runs on that unchanged state Then the resulting task order is identical to the first run And no duplicate audit entries or snapshots are created And task ownership and lock tokens remain unchanged And task versions only increment when an order change actually occurs
Reorder Throttling to Prevent Churn
Given team throttle policies are configured as max 1 reorder per item per 10 minutes and max 30 reorder events per team per hour When multiple risk changes occur rapidly for the same queue Then the system coalesces updates and performs at most the allowed number of reorder operations And deferred/skipped reorder attempts are logged with a throttle reason And no item is reordered more than once within its per-item throttle window
Targeted Notifications with Concise Change Reasons
Given at least one task changes position due to auto-reprioritization When the reorder completes Then affected users (assignees, queue owners, and watchers) receive an in-app notification within 15 seconds And email and Slack notifications are delivered within 2 minutes And each notification includes team, queue, count of impacted items, top 5 item IDs with position deltas, concise reason (e.g., "SLA risk ≥ 0.8"), and a link to the snapshot diff And no notifications are sent if no positions change And notifications are deduplicated per user per queue within a 10-minute window
Per-Team Policies and Feature Flag Isolation
Given Team A has auto-reprioritization enabled with thresholds X/Y/Z and Team B has it disabled When the scheduler runs for all teams Then only Team A's queues are evaluated and potentially reordered And Team B's queues remain unchanged And the thresholds X/Y/Z are applied only to Team A's queues And all audit and notification artifacts are scoped to the originating team
Manual Freeze Controls for Queues
Given a queue is set to Frozen by a manager for 2 hours When risk thresholds are met that would otherwise trigger auto-reprioritization Then no changes to task order are applied during the freeze window And a suppressed-event audit entry is recorded with the freeze reason and remaining time And the UI displays a Frozen badge with countdown And unfreezing immediately re-enables auto-reprioritization on the next evaluation
One-Click Rollback Using Pre/Post Snapshots
Given a reorder occurred and pre/post order snapshots are recorded When a user with permission initiates a One-Click Rollback within 24 hours Then the queue order is restored to the pre-change snapshot within 30 seconds And a rollback audit record is created capturing initiator, reason, and number of items restored And downstream caches are invalidated so all clients reflect the restored order within 60 seconds And affected users receive a concise rollback notification with links to both snapshots
Smart Assignment Rebalancing Suggestions
"As a team lead, I want explainable reassignment suggestions so that I can rebalance workload quickly without violating coverage rules."
Description

Generate ranked recommendations for coverage swaps, split assignments, or handoffs to teammates with compatible skills, licenses, geography, and workload headroom. Include rationale, predicted SLA impact, and before/after load effects for source and target, with hard checks for constraints such as catastrophe teams, severity tiers, carrier preferences, and policy restrictions. Present one-click approve/decline with optional notes and auto-create reassignment tasks upon approval, with notifications to stakeholders.

Acceptance Criteria
Ranked Suggestions Respecting Hard Constraints
Given an at-risk claim item is identified for rebalancing When the system generates suggestions Then candidates that violate any hard constraint (must-have skills, required licenses, severity-tier permissions, catastrophe team rules, carrier preferences, policy restrictions, geography coverage) are excluded And the remaining suggestions are labeled as swap, split, or handoff And the list is ordered by predicted SLA risk reduction descending And each suggestion has a numeric rank starting at 1
Compatibility and Capacity Validation
Given a claim with required skills, policy jurisdiction, loss location, and estimated effort When evaluating a candidate teammate Then the candidate has all must-have skill tags And holds an active license for the policy jurisdiction And covers the loss geography per assignment rules And has workload headroom greater than or equal to the claim’s estimated effort based on current capacity and assignments And for split assignments, each target’s projected utilization after the split remains less than or equal to the configured max_utilization threshold And for swaps or handoffs, all involved adjusters meet the same constraints and their projected utilizations remain within the configured threshold
Impact Preview with Rationale and Before/After Load
Given a suggestion is displayed When the user expands its details Then the UI shows rationale factors (skills match, license match, geography, headroom, queue saturation) used in the recommendation And shows predicted SLA impact including time-to-breach before vs after and the delta in hours And shows source and target utilization percentage and workload points before vs after And all numeric values display their data timestamp and calculation basis on hover or tap And the prediction snapshot is no older than 5 minutes at the time of display
One-Click Approve/Decline with Optional Notes
Given a suggestion is visible When the user clicks Approve Then the reassignment plan is applied atomically And an optional note from 0 to 500 characters can be saved with the action And the UI confirms success within 3 seconds or displays a clear error message if unsuccessful When the user clicks Decline Then no changes are applied And the decision and optional note are recorded And the declined suggestion is removed from the current list view
Task Creation and Stakeholder Notifications
Given a suggestion is approved When the system applies the reassignment Then reassignment tasks are created for all affected parties with links to the claim and due dates And notifications are sent to stakeholders via configured channels (in-app and email) within 1 minute And tasks and notifications include the approval note and suggestion identifier And if any task or notification fails to create or send, all changes are rolled back and an error is shown
Audit Trail and Enforcement of Constraints on Approval
Given a suggestion is approved When final validation runs Then the system rechecks all hard constraints and blocks approval if any are violated, displaying the specific violated constraint And an immutable audit record is stored including suggestion content, constraint check results, predicted impacts, approver identity, timestamp, and outcome And the audit record is retrievable by claim ID and suggestion ID
Vendor Overflow Dispatch
"As an operations manager, I want at-risk work dispatched to approved vendors when internal capacity is constrained so that SLAs are met consistently."
Description

When predicted internal capacity is insufficient, surface vendor overflow options based on pre-approved networks, geography, loss type, and pricing. Support policy-driven auto-dispatch with manager approval gates, generate structured work orders with least-privilege data sharing via secure links, and track vendor acceptance and SLA commitments. Maintain bi-directional status updates, handle decline/fallback or recall scenarios, and report cost and turnaround impact to operations dashboards.

Acceptance Criteria
Surface Pre-Approved Vendor Options on Predicted Capacity Shortfall
Given a claim task is forecast to breach SLA and internal capacity is flagged insufficient by Capacity Sync When the user opens Vendor Overflow options or an auto-evaluation is triggered Then only vendors from the pre-approved network matching claim geography (configurable radius), loss type, and pricing caps are listed And each vendor shows match reasons, current availability, estimated start-by time, rate card reference, and historical SLA performance And vendors failing constraints are excluded with reason codes available in details And the list is ranked by policy-defined scoring and produces identical ordering for identical inputs
Policy-Driven Auto-Dispatch with Manager Approval Gate
Given auto-dispatch policies and manager approval gates are configured And a claim meets a policy’s conditions (e.g., loss type, severity, budget cap) When the system recommends a vendor for auto-dispatch Then an approval task is created for the designated manager with vendor, cost estimate, SLA, and rationale And on manager approval, the vendor is dispatched automatically and the decision is audit-logged (timestamp, approver, policy ID, vendor ID) And on rejection, no dispatch occurs and the system presents the next compliant option (if any) with rationale And if no action is taken by the approval SLA (configurable), the system escalates per policy (notify next approver or cancel)
Structured Work Order Generation with Least-Privilege Secure Link
Given a vendor dispatch is approved When the work order is generated Then the work order includes only required fields: claim reference, service scope, site address, contact name and phone, loss type, response/SLA requirements, budget cap or rate card, relevant attachments/photos, and safety/access notes And sensitive fields not required for fulfillment (policy limits, coverage notes, SSN, DOB, adjuster internal notes) are excluded by default And a secure, tokenized link is created for the selected vendor only with configurable expiry and revocation And every access is authenticated, role-scoped to the vendor, and logged (timestamp, actor, IP, resource) And revoking the link immediately denies further access and invalidates tokens
Vendor Acceptance and SLA Commitment Capture
Given a vendor receives a dispatch via secure link or API When the vendor responds Then the vendor can Accept with a confirmed start-by window and SLA commitment, or Decline with a reason code, or take no action And on Accept, accepted rates/price basis are captured and the claim task status transitions to Dispatched → Accepted And on Decline, the decline reason and timestamp are captured and surfaced to the manager And on no response by the configurable timeout, the dispatch is marked No Response and participates in fallback logic And all vendor responses are acknowledged to the vendor and recorded in an immutable audit trail
Bi-Directional Status Sync Between Vendor and ClaimFlow
Given a dispatch is active When the vendor sends status updates (e.g., en_route, on_site, in_progress, awaiting_parts, completed) via API or portal Then ClaimFlow updates the internal workflow task status using a defined mapping table and stamps received_at and processed_at times And idempotent handling ensures duplicate vendor events do not create duplicate transitions And failures to ingest updates trigger retries and alerting per policy And status changes in ClaimFlow that affect the vendor (e.g., recall, scope change) are pushed to the vendor with acknowledgement tracking And the last_sync timestamp and health indicator are visible on the claim
Decline, Fallback, and Recall Handling
Given a vendor declines or does not respond within the configured timeout When fallback is enabled Then the next-ranked compliant vendor is automatically recommended or dispatched per policy, excluding vendors already declined or timed out And if all options are exhausted, the manager is notified with suggested next steps And if internal capacity becomes available before work starts, a manager can recall the dispatch; the vendor is notified, link access is revoked, and costs/cancellation terms are recorded And if work has started, recall requires manager override with reason and may be blocked per policy And all fallback and recall actions are audit-logged with timestamps and actors
Operational Reporting of Cost and Turnaround Impact
Given vendor overflow dispatches occur When operations dashboards are loaded Then metrics are available including: time to vendor acceptance, time to start, time to completion, acceptance rate, decline rate, no-response rate, cost vs. rate card, and delta vs. internal baseline And breach-avoidance rate for at-risk items is displayed and filterable by time range, geography, loss type, and vendor And totals and averages reconcile with underlying dispatch records And dashboards support export (CSV) with the same filters applied And data refresh cadence and last_updated timestamp are visible
Audit Trail & Policy Controls
"As a compliance officer, I want a complete audit trail of routing decisions so that audits and reviews can verify policy adherence."
Description

Create immutable, searchable logs for all reprioritizations, suggestions, approvals, reassignments, and vendor dispatches, capturing timestamp, actor, rationale, input signals, and resulting changes. Support export to SIEM/BI, retention and data residency policies, and role-based read-only audit views. Enforce configurable routing guardrails including skill, license, territory, and max workload caps, with validation feedback displayed during approval flows.

Acceptance Criteria
Immutable Audit Log Entry Creation
Given a reprioritization, suggestion, approval, reassignment, or vendor dispatch is completed in Capacity Sync When the operation commits Then an audit record is created with fields: event_id (UUID), action_type, case_id, timestamp (UTC ISO-8601), actor_id, actor_role, rationale_text, input_signals (key/value), pre_state, post_state, source_ip And the record is write-once (no update/delete) at API/UI level; any mutation attempt returns 403 and is itself logged And the record stores hash and previous_hash to form a tamper-evident chain; chain verification succeeds for new entries And the business operation does not finalize if the audit record cannot be persisted; the user sees a clear error message
Audit Log Search and Filter
Given a user with Audit Viewer role When they search by date range, actor_id, action_type, case_id, or free-text across rationale_text and input_signals Then results match all filters exactly and full-text matches stemmed keywords And default sort is timestamp desc with stable pagination (cursor-based) And query returns within 2s for 100k records and within 5s for 1M records in the tenant And user can export current result set to CSV (up to 50k rows) with identical field values
SIEM/BI Export Integration
Given a tenant has configured an export destination (HTTP webhook, S3/GCS, or Kafka) When new audit records are created Then records are delivered in JSON Lines format with field schema parity, at-least-once semantics, and idempotency via event_id And deliveries are TLS 1.2+ and HMAC-signed (or OIDC for webhook) with 3xx/4xx/5xx retries using exponential backoff for up to 24 hours before dead-lettering And batch exports can be scheduled hourly/daily and include a manifest with record count and time window And a Test Connection sends a signed sample record and surfaces pass/fail with diagnostics And exports comply with tenant data residency settings (no cross-region transfer)
Retention and Data Residency Enforcement
Given tenant-configurable retention is set (30–3650 days) When a record reaches its retention expiry Then it is hard-deleted within 24 hours, removed from search and exports, and a deletion tombstone is logged (without PII) And legal hold can be applied per case or tenant to suspend deletion until removed And storage is WORM-compliant during retention/hold windows And all audit data for a region remains stored and processed in approved regions only, verified by storage location metadata and data transfer logs
Role-Based Read-Only Audit Views
Given RBAC roles are configured When a user with Audit Viewer role accesses audit logs Then they can view and export permitted records but cannot edit or delete; any write attempt returns 403 and is logged And users without permission cannot access audit endpoints or UI; access returns 403 and is logged And sensitive fields marked as restricted are redacted per policy for non-privileged viewers And row-level access limits visibility to the user's tenant/org scope And record detail pages load within 1.5s for p95
Routing Guardrails Validation in Approval Flow
Given approval or assignment is initiated for a claim/task When an assignee or vendor is selected Then the system validates skill, license, territory, and max workload caps in real time and blocks submission on violations And inline feedback lists each violated rule with human-readable messages and links to policy docs And if overrides are enabled by policy, a user with the required role can proceed only after entering a justification; the override decision and justification are audited And the system suggests compliant assignees/vendors ranked by current workload within 2s And dispatch/assignment cannot complete if violations exist and override is not permitted
Policy Configuration Change Auditability
Given a user with Policy Admin role updates guardrails, retention, export, or residency settings When the change is saved Then a policy audit record is created with actor, timestamp, affected policy, before/after values, rationale, and effective_from And policies are versioned; viewers can diff versions and, if permitted, revert to a prior version, generating a new audit entry And saving validates that changes will not violate residency constraints and shows an impact preview (e.g., items newly out-of-compliance count) And all policy audit records participate in the same tamper-evident chain as operational events

Escalation Ladder

Configurable, multi-step escalation with acknowledgements, reason-coded snoozes, and auto-escalate if unanswered. Orchestrates Slack/Teams/SMS/email/voice alerts and keeps an auditable trail, ensuring no silent misses and faster saves.

Requirements

Escalation Policy Builder
"As an operations admin, I want to define multi-step escalation policies by claim type and severity so that critical intakes are routed and acted on without manual oversight."
Description

Provide a configurable, multi-step policy builder to define escalation ladders per claim type, severity, and tags within ClaimFlow. Admins can set step timings, recipient groups, channels (Slack/Teams/SMS/email/voice), entry/exit conditions, and SLA thresholds. Includes reusable templates, versioning with change history, validation to prevent orphan steps/loops, and a simulator to test policies against sample claims. Integrates with ClaimFlow’s workflow engine so escalations are triggered from NLP-extracted facts and task states, updating claim timelines and assignments upon each step. Expected outcome: reduced time-to-acknowledgement and elimination of missed critical intakes.

Acceptance Criteria
Build and save a validated multi-step escalation policy
- Given an admin defines a policy named "High Severity Auto Escalation" with 4 steps, recipient groups, and channels (Slack, Teams, SMS, email, voice), When Save is clicked, Then the policy is saved as Draft with a unique ID and appears in the policy list with correct metadata (name, step count, channels, last modified). - Given the policy contains a loop (cycle) or an unreachable/orphan step, When Validate or Save is clicked, Then save is blocked and validation messages enumerate the loop path(s) and list the orphan step IDs. - Given any step is missing required fields (timing offset, recipient group(s), at least one channel, message template), When Save is clicked, Then save is blocked with field-level errors highlighting the missing fields. - Given all required fields are complete and no structural errors exist, When Save is clicked, Then the policy persists successfully and the builder displays a success toast and the new policy version number.
Template creation and instantiation of escalation policies
- Given an admin clicks "Save as Template" for a configured policy, When a unique template name is provided, Then a template record is created and visible in the Templates library with version 1.0. - Given a user creates a new policy "From Template" selecting an existing template, When the builder opens, Then steps, timings, channels, recipient groups, entry/exit conditions, and SLA thresholds are pre-populated from the template. - Given a policy is created from a template, When the user saves it, Then the policy is an independent entity with its own versioning timeline and the source template remains unchanged. - Given a template is referenced by at least one policy, When the admin attempts to delete the template, Then deletion is blocked and an impact summary lists referencing policies.
Simulate policy against sample claims with preview and outcomes
- Given a sample claim (type=Auto, severity=High, tags=[injury]) and a policy with steps at T+0, T+5m, T+15m, When the Simulator is run with no acknowledgements, Then the preview timeline shows notifications at T0, T+5m, T+15m with expected recipients and channels per step. - Given the same simulation, When an acknowledgement at T+7m via SMS is added, Then all subsequent steps in that ladder path are canceled and the preview marks the exit reason "Acknowledged at T+7m via SMS". - Given a snooze with reason code "Investigating" for 10 minutes is added at step 1 (max snooze 30 minutes), When the simulation is re-run, Then subsequent steps shift by 10 minutes and the snooze reason is displayed in the preview. - Given a simulation has been executed, When the user clicks Export, Then the simulator output (timeline, steps, recipients, channels, events) is downloadable as JSON and attachable to a claim record.
SLA thresholds, acknowledgements, snoozes, and auto-escalation
- Given a live policy step requires acknowledgement within 5 minutes, When notifications are sent, Then the step status becomes "Awaiting Ack" and a 5-minute SLA timer starts. - When any recipient acknowledges via any configured channel, Then the step status updates to "Acknowledged" with user, channel, and timestamp, and subsequent steps for that path are canceled. - When a recipient snoozes with an allowed reason code and duration, Then the SLA timer extends by the snooze duration up to the policy maximum and the snooze event is logged with reason and user. - When the SLA (including snooze time) expires without acknowledgement, Then the system auto-escalates to the next step and logs the reason "Unacknowledged SLA breach". - All events (Sent, Acknowledged, Snoozed, Auto-escalated) appear in the claim’s audit trail and timeline within 5 seconds of occurrence.
Workflow engine integration and claim timeline updates
- Given ClaimFlow ingests a claim and NLP extracts facts (e.g., type=Property, severity=High), When entry conditions for a policy are met, Then a single active ladder instance is attached to the claim and step 1 notifications are enqueued. - Given the workflow engine updates task state per policy step, When an escalation requires reassignment, Then the claim assignment updates to the configured recipient group and the change appears on the claim within 5 seconds. - Given multiple triggers occur for the same claim and policy within 60 seconds, When the engine evaluates escalations, Then duplicate ladder instances and duplicate step notifications are prevented (deduplicated). - Then all policy-driven events (start, notifications, acknowledgements, snoozes, escalations, reassignments) are appended to the claim timeline with timestamp, actor, and channel context.
Policy versioning, effective dates, and change history audit
- Given a policy v1.2 is active, When the admin publishes edits, Then v1.3 is created with an effective date-time and a diff of changes (steps, timings, channels, recipients, conditions) is recorded. - Given claims running under v1.2, When v1.3 becomes effective, Then in-flight claims continue on v1.2 while newly triggered claims use v1.3. - Given the admin initiates a rollback to v1.2, When confirmed, Then v1.2 becomes the current version and v1.3 remains in history marked as "Superseded". - Given the change history view is opened, When a specific version is selected, Then the system displays who changed what and when, including rationale/notes if provided.
Entry/exit conditions, channel orchestration, and acknowledgment deduplication
- Given entry conditions (e.g., severity=High AND tag=Critical Intake) are met, When claim status becomes Open, Then the policy starts; When an exit condition (e.g., status becomes Assigned or Closed) is met, Then all future steps are canceled with reason "Exited by condition". - Given channel priority [Slack, Teams, SMS, Email, Voice] is configured, When the top-priority channel is unavailable for a recipient, Then the system falls back to the next available channel and records the final delivery channel and any failures. - When a recipient acknowledges on any one channel, Then pending notifications for the same step across other channels are suppressed and the ladder path is marked acknowledged. - For each step, delivery outcomes (Delivered, Failed, Retried) are captured per channel with error details and are visible in the step audit log.
Multi-Channel Notification Orchestrator
"As a claims manager, I want escalations to reach assignees on their preferred channel with consistent content so that alerts are seen and acted on quickly."
Description

Implement a unified service to orchestrate alerts across Slack, Microsoft Teams, SMS, email, and voice. Supports provider integrations, credentials management, rate limiting, retries with backoff, and delivery receipts. Uses message templates with claim context (loss details, policyholder info, SLA clocks) populated from ClaimFlow’s NLP engine. Provides channel fallbacks (e.g., Slack→SMS→voice) and de-duplication across channels. Normalizes acknowledgement callbacks from each channel and updates the claim/task in real time. Ensures consistent formatting, secure PII handling, and localized timestamps. Expected outcome: higher recipient reach and faster responses with minimal operational overhead.

Acceptance Criteria
Fallback Delivery with Acknowledgement SLA
Given an escalation alert with a configured fallback chain Slack → SMS → Voice and an acknowledgement SLA window When the primary Slack message is not delivered or not acknowledged within the SLA window Then the orchestrator sends the SMS to the same recipient And if the SMS is not delivered or not acknowledged within the SLA window Then the orchestrator initiates the automated voice call to the same recipient And only the first acknowledgement across any channel stops further fallbacks And each attempt is recorded with timestamp, channel, provider message ID, and outcome in the audit log
De-duplication Across Channels and Providers
Given the same recipient is targeted by multiple channels/providers for the same alert within a configured deduplication window When the orchestrator prepares outgoing messages Then it suppresses duplicates per recipient and alert key so that only one active awaiting-ack message exists per recipient And late delivery receipts for suppressed messages do not change the alert state And the deduplication window value is configurable and captured in the audit log
Template Rendering with Claim Context, PII Controls, and Localized Timestamps
Given a message template with placeholders for {claim_id}, {loss_summary}, {policyholder_name}, {sla_deadline_at}, and {deep_link} and a recipient with defined PII permissions and locale/time zone When the orchestrator renders the template Then all placeholders are populated from ClaimFlow data accurately And fields outside the recipient’s PII permissions are masked or omitted per policy And all timestamps are formatted in the recipient’s locale and time zone with explicit UTC offset And the rendered content conforms to channel-specific length/format limits without truncating required fields And the exact rendered payload per channel is persisted and matches what is delivered
Rate Limiting and Retry with Exponential Backoff and Jitter
Given provider rate limits of 30 requests/second and a retry policy starting at 1s backoff with factor 2, max 5 attempts, with full jitter When outgoing traffic bursts exceed 30 requests/second or transient failures (HTTP 429/5xx, timeouts) occur Then the orchestrator queues sends to comply with the limit and does not drop messages And it retries failed attempts per the policy until success or max attempts reached And retries cease immediately upon acknowledgement from any channel for the alert And metrics expose sends, throttles, retries, successes, and failures per provider
Delivery Receipts Normalization and Real-Time State Updates
Given heterogeneous delivery receipts from Slack, Teams, SMS, email, and voice providers When receipts arrive with statuses such as delivered, failed, bounced, read, or clicked Then the orchestrator normalizes them to a standard schema {delivered|failed|read|ack-triggered} And updates the alert state on the claim/task in real time with P95 latency under 2 seconds And failed receipts trigger the next fallback step immediately without waiting for the acknowledgement SLA And all receipt payloads are stored with provider message IDs for auditability
Acknowledgement and Snooze Normalization Across Channels
Given recipients can acknowledge via Slack button, Teams adaptive card, SMS reply "ACK", email action link, or DTMF "1" on voice and can submit a snooze with reason code and duration where supported When an acknowledgement or snooze is received from any channel Then the orchestrator emits a single normalized event {acknowledged|snoozed} with user_id, timestamp, channel, reason_code (nullable), and snooze_until (nullable) And the alert is closed on acknowledged or paused until snooze_until on snoozed And subsequent acknowledgements from other channels are recorded without changing the alert state And the claim/task and audit trail reflect the action within 2 seconds P95
Credentials Management and Security Controls
Given provider credentials are stored in a system secret manager with rotation every 90 days and environment scoping When the orchestrator sends or receives messages Then it retrieves credentials at runtime, never logs secrets, and uses TLS 1.2+ for all external calls And PII is redacted in logs/metrics (e.g., last 4 only) and data at rest is encrypted And sandbox/test credentials are isolated from production And access events and configuration changes are auditable with actor, timestamp, and before/after values
Acknowledgement & Reason-Coded Snooze
"As an adjuster, I want to acknowledge or snooze an escalation with a reason code so that the system knows I’m handling it and routes follow-ups appropriately."
Description

Enable recipients to acknowledge or snooze escalations directly from each channel via buttons/links, shortcodes, or IVR. Snoozes must require a standardized reason code taxonomy (configurable), a duration, and optional notes. The system records who, when, and why, applies snooze expiration logic, and updates the claim timeline and audit log. Policy rules determine whether a snooze pauses or advances the ladder and when to re-notify. Includes guardrails to prevent indefinite deferrals and visibility for supervisors to override or reassign. Expected outcome: clear accountability, fewer follow-ups, and structured reasons for delays to inform process improvements.

Acceptance Criteria
Multi-Channel Acknowledgement
- Given an escalation is delivered via Slack or Teams with interactive buttons, When the recipient clicks "Acknowledge", Then the step status changes to Acknowledged, further notifications for that step stop, and the claim timeline and audit log are updated with user identity and UTC timestamp. - Given an escalation is delivered via SMS or email with a secure, single-use tokenized link or shortcode, When the recipient clicks the link or replies with the #ACK shortcode from a recognized address/number, Then the step is marked Acknowledged and fully audited as above. - Given an escalation is delivered via voice/IVR, When the recipient selects the Acknowledge option via DTMF or voice confirmation, Then the step is marked Acknowledged and fully audited as above. - Given duplicate acknowledge inputs arrive for the same step, When the second and subsequent inputs are processed, Then the action is idempotent and no duplicate timeline entries are created (a single deduped audit note may be recorded). - Given an unrecognized identity attempts to acknowledge (e.g., unknown phone/email), When the input is received, Then the system rejects the action, returns a verification prompt, and does not alter the escalation state. - Given the acknowledge link is expired or the step has advanced, When the recipient attempts to acknowledge, Then the system displays current status and provides a path to the active owner without changing state.
Snooze With Reason Code & Duration
- Given an active escalation, When the recipient selects Snooze, Then the system requires a reason code from the configured taxonomy and a duration; notes are optional unless policy requires them for the chosen code. - Given channel-specific inputs, When the user submits Snooze details, Then the system validates per channel as follows: Slack/Teams (interactive picker components), Email/SMS (secure link to lightweight form or SMS "#SNOOZE <code> <duration> [notes]"), IVR (DTMF menu mapped to reason codes and duration); invalid or missing values are rejected with an actionable error and no state change. - Given policy-defined min/max snooze durations and allowed reason codes, When inputs are outside bounds or disabled, Then the snooze is rejected with a descriptive message and guidance to correct. - Given a valid Snooze submission, When it is accepted, Then the step state changes to Snoozed with start/end timestamps computed, and audit/timeline entries capture actor identity, channel, reason code, duration, notes, and prior/new state. - Given specific reason codes are configured to require notes, When such a code is chosen without notes, Then submission is blocked until notes are provided.
Snooze Expiration & Auto Re-Notification
- Given a step is Snoozed, When the snooze end time elapses, Then the system re-notifies according to policy (same assignee or next rung), including context with prior snooze reason, actor, and duration. - Given policy mode Pause, When a snooze is active, Then subsequent rungs and timers are suspended until expiration; on expiration, the original assignee is re-notified per cadence. - Given policy mode Advance, When a snooze is applied, Then the next configured assignee is notified while the original is marked Snoozed; on expiration, re-notification follows policy (e.g., return to original or continue). - Given the assignee acknowledges during the snooze window, When the Acknowledge action is received, Then the snooze is canceled, the step is marked Acknowledged, and no re-notification occurs. - Given guardrails define max snooze count and total snoozed time per step, When thresholds are exceeded, Then further snooze requests are blocked or require supervisor approval per policy, and auto-escalation occurs if configured. - Given notify windows (e.g., business hours) are configured, When a snooze expires outside the window, Then re-notification is deferred to the next allowed window.
Audit Trail & Claim Timeline
- On any Acknowledge or Snooze, Then an immutable audit record is written with fields: claimId, escalationId, ladderStepId, action (ack/snooze), actorUserId, actorExternalId (phone/email), channel, timestampUTC, reasonCode, durationMinutes, notes, previousState, newState, policyProfileId, and correlationId. - Then the claim timeline shows a human-readable event within seconds of the action and deep-links to the audit record. - Then audit records are queryable via UI/API by claimId, action, actor, channel, reasonCode, and date range; export to CSV/JSON preserves all fields. - Then duplicate inputs are deduplicated: only one audit entry exists per unique correlationId; subsequent duplicates are logged as deduped attempts without creating new state transitions. - Then supervisor overrides and reassignments produce separate audit entries capturing before/after values and justification notes.
Policy-Driven Ladder Behavior on Snooze
- Given policy determines ladder behavior, When a Snooze is applied with mode Pause, Then the current step's timers halt and no further rungs are engaged until expiration. - Given policy determines ladder behavior, When a Snooze is applied with mode Advance, Then the next rung is engaged while the current assignee remains Snoozed; ownership and notifications follow the configured routing. - Given re-notify cadence and channels are configured, When a snooze expires, Then the system executes the exact cadence and channel mix defined, honoring quiet hours and backoff rules. - Given reason-to-routing mappings exist, When a Snooze reason code with a mapping is selected (e.g., Awaiting Insured), Then the system routes or tags the task per mapping and reflects this on the claim timeline. - Given a policy decision log is enabled, When any policy evaluation occurs, Then inputs (reason, duration, step state) and outputs (pause/advance, target assignee, cadence) are recorded for auditability.
Supervisor Overrides, Reassignment, and Guardrails
- Given a user with Supervisor or Admin role, When they open an Unacknowledged or Snoozed step, Then they can cancel snooze, adjust duration within policy bounds, change reason code (with required note), reassign current/next rung, or force escalate; all changes require justification notes. - Given guardrails are configured (max snooze duration, max snooze count, total snoozed time), When a recipient attempts to exceed any guardrail, Then the system blocks the action or requires supervisor approval per policy and logs the event. - Given a supervisor override occurs, When the change is saved, Then affected parties are notified (original and new assignees) and the escalation state updates immediately. - Given role-based access control, When a non-privileged user attempts an override, Then the action is denied and an audit entry is recorded with 403 outcome. - Given SLA protection rules exist, When a snooze would push the step past an SLA threshold within a configurable window, Then the snooze is rejected or requires supervisor approval, and a forced escalation option is presented.
Auto-Escalate & Timeout Handling
"As a claims supervisor, I want overdue escalations to automatically move to the next rung so that critical work doesn’t stall."
Description

Automatically advance to the next ladder step when acknowledgements are not received within SLA or when snoozes expire. Supports step-specific timeouts, recipient recalculation (based on ownership/availability), and suppression of alert storms via deduplication and throttling. Respects business-hour rules and on-call schedules and can optionally notify supervisors with a summary of prior attempts. Writes outcomes to the claim timeline, updates task status, and emits metrics (time-to-ack, step counts). Expected outcome: no silent misses and reliable progression to decision-makers when frontline contacts are unavailable.

Acceptance Criteria
Auto-advance on Step SLA Breach
Given a ladder step with a configured SLA timeout T_step and business-hours enforcement setting BH When no acknowledgement is recorded for the step before T_step elapses (counting time per BH rules) Then the workflow advances to the next configured step within 5 seconds, the current step outcome is recorded as timeout, and a claim timeline entry is written with fields {claimId, stepId, timeoutAt, nextStepId, actor:"system"} And any active SLA timer for the current step is cleared And if an acknowledgement is recorded before T_step elapses, no auto-advance occurs and the timer is cleared And if the current step is the terminal step, the outcome is recorded as terminal_timeout and no further step is queued
Snooze Expiry Triggers Escalation
Given a step is snoozed with a reason code R and a duration S and no acknowledgement occurs before snooze end When the snooze expires Then the step auto-escalates to the next configured step within 5 seconds And a claim timeline entry is written with fields {claimId, stepId, snoozeReason:R, snoozeEndAt, outcome:"snooze_expired_escalated", nextStepId} And the SLA timer resumes or is recalculated per step rules And if an acknowledgement occurs during the snooze, no auto-escalation occurs at snooze end and the snooze is cleared
Recipient Recalculation at Escalation Time
Given an escalation to step N occurs and recipient recalculation is enabled When computing recipients for step N Then the recipient set is derived from current claim ownership, availability (OOO/ PTO/ calendar), and on-call rosters effective at the escalation timestamp And unavailable recipients are excluded and replaced per routing rules And if the computed recipient set is empty, the configured fallback (e.g., supervisor group) is targeted And the claim timeline records {stepId:N, recipients[], sources:["ownership","availability","on_call"], fallbackUsed:boolean} And the notification fan-out targets only the recalculated recipient set
Deduplication and Throttling Suppress Alert Storms
Given alerts are triggered for the same {claimId, stepId, channel, recipient} within a configured dedup window W When an initial alert has been sent within W Then subsequent alerts with the same dedup key are suppressed and a suppression counter is incremented And a consolidated notification (if enabled) includes the suppression count when W ends And per-recipient throttling enforces a maximum of L alerts across channels per window WT; excess are suppressed And suppression and throttling events are recorded to the claim timeline and metrics {alerts_suppressed_count, throttled_count} are emitted with tags {claimId, stepId, recipient} And at least one alert per escalation event is delivered unless globally muted by configuration
Business-Hours and On-Call Aware Timeouts
Given a step has business-hours enforcement enabled with calendar BH and an after-hours on-call route AHO configured When the SLA timer would elapse outside BH Then the timer is paused outside BH and resumes when BH opens, unless AHO is enabled And when AHO is enabled, escalation during non-BH targets the on-call recipients only and skips off-duty users And time-to-ack metrics exclude paused time and include a tag {bh_excluded:true} And claim timeline entries indicate whether escalation occurred in-hours or after-hours and which on-call roster was used
Supervisor Summary on Escalation Exhaustion
Given the ladder has attempted N steps without acknowledgement and supervisor summary is enabled When the final configured step times out Then a single summary notification is sent to the supervisor group within 15 seconds containing prior attempts {timestamps, channels, recipients, snooze reasons, outcomes} and a deep link to the claim And the summary is deduplicated per exhaustion event (one summary per event) And the claim timeline records {eventType:"escalation_exhausted", attempts:N, summarySent:true} And metrics emit {escalations_exhausted_count:1} with tags {claimId}
Audit Trail, Task Status Updates, and Metrics Emission
Given any auto-escalate, timeout, or snooze-expiry action occurs When the system processes the event Then a claim timeline entry is created with structured fields {eventId, eventType, claimId, stepId, fromStepId, toStepId, recipients[], channels[], reason, occurredAt, actor:"system"} And the related task status transitions appropriately (Pending->Escalated on auto-escalate, Pending->TimedOut on terminal timeout, Pending->InProgress on acknowledgement, InProgress->Completed on resolution) And metrics are emitted within 5 seconds: time_to_ack (ms), steps_attempted_count, escalations_count, alerts_suppressed_count with tags {claimId, stepId, environment, channel, business_hours} And operations are idempotent: retries with the same eventId do not create duplicate timeline entries, notifications, task transitions, or metric increments
Audit Trail & Compliance Logging
"As a compliance analyst, I want a complete audit trail of all escalation actions so that we can prove diligence and investigate misses."
Description

Maintain an immutable, time-stamped ledger of all escalation events including policy versions, messages (stored as redacted content with hashes), recipients, channels, delivery outcomes, acknowledgements, snoozes with reason codes, overrides, and auto-escalations. Provide search, filtering, and export (CSV/JSON) with access controls and retention policies. Surface a readable thread on the claim timeline and expose an API for audit retrieval. Align with insurer/MGA audit requirements and support eDiscovery holds. Expected outcome: demonstrable diligence, easier root-cause analysis, and faster regulatory/compliance responses.

Acceptance Criteria
Immutable Escalation Event Ledger
Given any escalation-related action occurs (create, send, deliver, fail, acknowledge, snooze, override, auto-escalate) When the system records the action Then it appends an immutable audit record containing event_id, claim_id, escalation_ladder_id, policy_version, correlation_id, actor (user/service), channel, recipients, outcome, created_at (UTC ISO 8601 with ms), and payload_hash (SHA-256) And the record cannot be updated or deleted after write And any correction is stored as a new audit record referencing the prior event_id with correction_type and correction_actor/time logged And an hourly integrity job validates that 100% of stored hashes match recomputed values and logs any mismatch as a P1 alert
Redacted Message Storage with Content Hashing
Given a message body or attachment is associated with an escalation event When the system stores the event Then only redacted_content and payload_hash (SHA-256 of original) are persisted; original content is not stored And the redaction_ruleset_id and redaction_timestamp are included in the audit record And attempts to view unredacted content are denied and logged with actor, time, and reason And when an auditor provides the original message to verify Then its SHA-256 hash matches the stored payload_hash for that event
Multi-Channel Delivery Outcomes and Acknowledgements
Given an escalation notification is sent via Slack, Teams, SMS, Email, or Voice When delivery providers return status updates Then a delivery_outcome event is logged per recipient and channel with provider_message_id, status (queued|sent|delivered|failed|bounced|read), provider_error_code (if any), and timestamps And events are correlated via correlation_id to the originating notification When a recipient acknowledges via any supported channel Then an acknowledgement event is logged with recipient identity, channel, timestamp, and device/source metadata within 5 seconds of receipt
Snooze with Reason Codes and Auto-Escalation
Given a user chooses to snooze an escalation When saving the snooze Then the system requires a reason_code from the configured set and a snooze_until in the future and logs both in the audit record with actor and timestamp When snooze_until elapses without acknowledgement Then an auto_escalation event is logged with next_rung, new_recipients/channels, and trigger_timestamp And if an authorized user overrides a snooze Then an override event is logged with actor, reason, and previous vs new values
Search, Filter, and Export with Access Controls
Given a user with Compliance Auditor role opens the Audit console When they search with filters (claim_id, date_range, event_type, policy_version, channel, recipient, outcome, reason_code, actor) Then results return within 3 seconds for up to 10,000 matching records and display only fields they are authorized to see When they export the current result set Then CSV and JSON files are generated with headers and metadata (export_id, tenant_id, filters, generated_at) and a download event is logged And exports of up to 100,000 records complete within 30 seconds And users without export permission receive a 403 and the attempt is logged And all exported message content remains redacted
Readable Claim Timeline Thread
Given a claim has escalation activity When a user views the claim timeline Then a chronological thread displays event type, channel, recipients, delivery status, acknowledgement, snooze (reason/until), overrides, and auto-escalations with timestamps in local UI time And redacted message previews show tokens only (no raw content) And each item links to the full audit record view And pagination/infinite scroll loads the next 50 events within 1 second at p95 And users without permission do not see restricted fields and a redacted placeholder is shown
Audit Retrieval API and Retention/Legal Hold Enforcement
Given an authorized client calls GET /api/v1/claims/{claimId}/audit-events with filters (date_range, event_type, channel, outcome) and pagination (cursor, limit<=500) When the request is processed Then the API returns 200 with results, total_count, and next_cursor in under 500 ms at p95 for claims with up to 10,000 events, and excludes fields the caller is not permitted to view When tenant retention policy (e.g., 7 years) is reached for eligible records Then a purge job deletes those records, writes purge_audit events, and the API no longer returns purged items When a claim or tenant is placed on eDiscovery hold Then no purges occur for held records, the API indicates hold_status=true and hold_id, and all hold create/update/remove actions are audited And unauthorized requests receive 403 with an access_denied audit event
On-Call & Business Hours Routing
"As an operations admin, I want escalations to respect business hours and on-call rotations so that the right person is alerted without waking off-duty staff unnecessarily."
Description

Incorporate calendars and rotation schedules to route escalations to on-duty staff based on time zone, business hours, holidays, and team coverage windows. Support integrations with common on-call systems or simple native rotations, with overrides and emergency contact trees. Apply rules per ladder step to target individuals, roles, or dynamic groups (e.g., current claim owner, backup adjuster, regional supervisor). Display upcoming coverage to admins and log routing decisions for audit. Expected outcome: fewer off-hours disruptions, higher first-time response rate, and correct targeting of responsible staff.

Acceptance Criteria
Local Time Zone Business-Hours Routing
Given a user profile has time zone America/Chicago with business hours 09:00–17:00 Mon–Fri, When an escalation occurs Tuesday at 10:15 America/Chicago and the ladder step targets role "Primary Adjuster", Then only on-duty users in that role whose local time is within their configured business hours are routed and off-duty users are excluded. Given an escalation occurs Saturday 14:00 America/Chicago, When the ladder step specifies after-hours routing to the "On-Call Rotation", Then business-hours-only targets are bypassed and the current on-call assignee is routed. Given an escalation occurs 06:30 America/Los_Angeles and the step targets an individual whose business hours start 08:00 local time, When resolving targets, Then routing to that individual is suppressed and the step's defined fallback target is used.
Holiday-Aware Routing by Region Calendar
Given the team's US holiday calendar marks 2025-12-25 as a holiday, When an escalation occurs that date at 10:00 local time and the step targets business-hours staff, Then the system treats the day as off-hours for US users and routes per the step's holiday/after-hours rule. Given two users in US and UK regions with distinct holiday calendars and an escalation occurs on a US-only holiday, When resolving targets, Then US business-hours users are excluded while UK users remain eligible if within their local business hours. Given the holiday calendar toggle is disabled for a team, When an escalation occurs on a previously marked holiday, Then routing proceeds as a normal business day.
Native On-Call Rotation Resolution and Shift Change
Given a native weekly rotation A→B→C with B on duty until 07:59 local time, When an escalation arrives at 07:58, Then B is routed. Given the same rotation and shift boundary at 08:00 local time, When an escalation arrives at 08:00 or later, Then C is routed. Given a user in the rotation is marked Unavailable for the current shift, When resolving on-call assignees, Then that user is skipped and the next eligible user is chosen.
On-Call Provider Integration With Fallback
Given an external on-call provider integration is connected and healthy, When an escalation occurs, Then the current on-call assignee is retrieved via API within 2 seconds and routed. Given the external API errors or times out after 3 seconds, When resolving targets, Then the system falls back to the configured native rotation without user-facing error and records the fallback reason in the audit log. Given the external schedule returns multiple on-duty assignees and the step is configured for "all", When resolving targets, Then all returned assignees are routed and listed in the audit log.
Overrides and Emergency Contact Tree Failover
Given an active override reassigns coverage from User A to User B from 2025-10-01 08:00 to 2025-10-02 08:00 local time, When an escalation occurs within that window, Then routing targets User B instead of User A. Given no eligible on-duty user is resolved after applying time zones, business hours, holidays, and overrides, When resolving targets, Then the system initiates the emergency contact tree in the configured order until an acknowledgement is received or the tree is exhausted. Given the emergency contact tree is exhausted with no acknowledgement within the step timeout, When proceeding, Then the system auto-escalates to the next ladder step and records the failure reason.
Dynamic Target Resolution by Role and Context
Given a ladder step targets "Current Claim Owner" for the escalated claim, When the escalation occurs, Then the current owner is resolved at event time and routed if on-duty; otherwise the step's fallback target is applied. Given a step targets "Backup Adjuster" and none is set on the claim, When resolving targets, Then the configured alternate (e.g., "Regional Supervisor") is used and the null reference is recorded in the audit log. Given a step targets role "Regional Supervisor" for the claim's region, When resolving targets, Then the supervisor is selected based on the claim's region field and routed if on-duty. Given a step targets a dynamic group filtered by team and license attributes, When resolving, Then only users matching the filter and on-duty are selected.
Coverage Visibility and Routing Decision Auditability
Given an admin opens the Coverage view and selects a team and date range (next 14 days), When loading the view, Then upcoming on-call and business-hours coverage is displayed by user, role, time zone, including holidays and active overrides. Given an escalation is routed, When viewing the event's audit log, Then a routing decision record shows inputs (time zone, business hours, holiday calendars, overrides, external on-call response), resolved targets, exclusions with reasons, fallbacks taken, and timestamps. Given an auditor filters the routing log by claim ID or date/time range, When executing the search, Then matching routing decision records are returned within 2 seconds for up to 10,000 records.

SLA Switchover

When breach risk spikes, automatically reroutes work to approved fast-track paths, alternate queues, or simplified checklists within compliance rules. Triggers targeted claimant nudges and DocChase requests to unblock the critical path quickly.

Requirements

Real-time SLA Risk Scoring
"As a claims manager, I want real-time predictions of SLA breach risk so that the system can proactively trigger fast-track actions before deadlines are missed."
Description

Continuously evaluates every claim and task against tenant-specific SLA definitions to predict breach risk and time-to-breach in real time. Aggregates operational signals such as task age, dependency state, claimant responsiveness, document completeness, queue load, and adjuster availability, and augments with historical baselines to produce a normalized risk score, breach ETA, and reason codes. Publishes risk events to ClaimFlow’s event bus to initiate SLA Switchover when thresholds are crossed, with debouncing to avoid thrashing. Exposes APIs for the workflow router and UI to consume current risk state, supports carrier/line/jurisdiction scoping, and operates with low latency and high availability to ensure timely intervention.

Acceptance Criteria
Continuous Risk Recalculation on Signal Change
Given an active claim with at least one open task and a configured tenant SLA When any operational signal for the claim or one of its tasks changes (taskAge, dependencyState, claimantResponsiveness, documentCompleteness, queueLoad, adjusterAvailability) Then the system recalculates both claim-level and task-level riskScore (0–100) and breachETA within 500 ms p95 and 2 s p100 And persists the updated state with a monotonic lastUpdated timestamp And exposes the new state via the Risk State API within 300 ms of recalculation
Threshold Crossing Event Publishing with Debounce
Given tenant T has risk bands {High: >=70, Critical: >=90} and a debounceWindow=10m And a claim currently below High When the claim's riskScore first crosses into High or Critical Then publish a single RiskThresholdCrossed event to the event bus within 200 ms including {claimId, riskScore, breachETA, riskBand, reasonCodes, lastUpdated, tenantId} And do not publish another event for this claim within the debounceWindow unless the riskBand increases And if the riskScore drops below 65 and later re-crosses the threshold after the debounceWindow, publish a new event
Risk State API With Carrier/Line/Jurisdiction Scoping
Given tenant T with SLA rules scoped by carrier, line, and jurisdiction When GET /risk-state?claimId={id} is called by an authorized client Then the response status is 200 and body includes {claimId, riskScore(0–100), breachETA(ISO-8601), riskBand, reasonCodes[], lastUpdated(ISO-8601), modelVersion, scope:{carrier,line,jurisdiction}} And the values reflect the SLA rules for the claim’s carrier/line/jurisdiction And p95 latency <= 150 ms for cached reads and <= 300 ms for fresh reads at 500 RPS And calls filtered by scope (carrier/line/jurisdiction) return only matching claims And cross-tenant access is prevented (requests cannot access another tenant’s data)
Aggregated Signals Influence Risk As Expected
Given a baseline claim with neutral signals and baseline score S When taskAge increases by 48h past the SLA midpoint Then riskScore increases by >=10 points relative to S When a required dependency becomes blocked Then riskScore increases by >=15 points relative to S When claimantResponsiveness remains unresponsive for 72h Then riskScore increases by >=15 points When documentCompleteness drops from 100% to 60% Then riskScore increases by >=10 points When queueLoad rises to p90 queue depth Then riskScore increases by >=5 points When assigned adjuster availability is 0 for the next 24h Then riskScore increases by >=10 points And riskScore is capped within [0,100]
Historical Baseline Augmentation and Prediction Accuracy
Given >=90 days of historical data and >=500 claims in a carrier/line/jurisdiction scope When the nightly model refresh completes Then breach prediction AUROC >= 0.80 on a holdout validation set for that scope And breach ETA MAPE <= 20% for claims that breach within 14 days And modelVersion and trainingTimestamp are included in API responses and events And if the scope has <500 samples, the system falls back to the global baseline with a metric warning emitted
Service Performance and Availability SLOs
Given production traffic of 1000 signal updates per minute and 500 API RPS sustained for 1 hour When the system operates under normal conditions Then scoring service availability over a calendar month is >=99.95% And p95 end-to-end latency from signal change to API visibility <= 800 ms And no risk state data is lost during any single node failure And regional failover RTO <= 60 s with continuous event publishing And events are delivered at-least-once with idempotency keys to prevent duplicate downstream processing
Reason Codes and Contribution Weights
Given any computed risk state When the state is returned via API or published as an event Then include the top 3 reasonCodes with human-readable labels, stable machine keys, and contributionWeights that sum to 1.0 And contributionWeights reflect local feature attribution within ±0.05 of recomputed values And each reasonCode maps to a well-defined signal (taskAge, dependencyState, claimantResponsiveness, documentCompleteness, queueLoad, adjusterAvailability, historicalBaseline) And the order of reasonCodes is descending by contributionWeight
Configurable Switchover Rules & Paths
"As an operations admin, I want to configure switchover rules and destinations so that at-risk claims are rerouted in line with business policies without engineering changes."
Description

Provides a no-code rules builder for operations admins to define when and how at-risk work should switch to fast-track workflows, alternate queues, or simplified checklists. Supports conditions on risk thresholds, claim attributes, coverage status, amount, fraud score, jurisdiction, and customer segment, and maps eligible cases to versioned workflow templates and target queues. Includes simulation and impact preview, staged rollout with feature flags, change approvals, and per-tenant scoping. Integrates with ClaimFlow’s routing engine and configuration service so updates take effect without deployments while remaining traceable and reversible.

Acceptance Criteria
Build rule with multi-attribute conditions
Given an operations admin opens the no-code rules builder When they create a switchover rule with conditions on riskThreshold >= 0.75, claimAmount > 10000, coverageStatus = "Active", fraudScore >= 600, jurisdiction in ["CA","NY"], and customerSegment = "Premium", combined with AND/OR and parentheses Then the builder validates all fields and comparators, saves the rule in Draft with a unique version ID, and displays a validation summary with zero errors And the rule evaluates true for matching test claims and false for non-matching claims in the test panel And invalid operators or unknown attributes are rejected with inline errors and the rule cannot be saved
Map eligible cases to versioned workflows and target queues
Given a saved draft switchover rule When the admin selects workflow template "FastTrack FNOL" version 3.2 and target queue "HighPriority-East" Then the mapping requires selecting an explicit template version and validates queue existence and capacity And the rule can optionally assign a simplified checklist "Fast-Checklist-v1" And if the template, version, or queue is missing or cross-tenant, the mapping is blocked with an error and cannot be published And the mapping passes a compliance guard check ensuring the selected path is permitted for the claim’s jurisdiction and coverage
Run simulation and impact preview before publish
Given one or more draft rules are selected When the admin runs a simulation against a specified dataset (e.g., last 30 days of closed and open claims) Then the system computes and displays number and percentage of claims that would switch over, projected SLA breach reduction, average cycle-time delta, and top-5 impacted queues within 60 seconds for datasets up to 100k claims And provides a downloadable list of affected claim IDs and predicted paths And no production routing is changed by simulation And simulations are versioned and stored for audit with timestamp, dataset scope, and results
Staged rollout with feature flags and safe rollback
Given an approved rule set When the admin enables the feature flag by tenant and sets rollout to 10% by claimant segment for jurisdiction = "CA" Then only eligible traffic is routed using the new rules, others remain on the baseline And toggling the flag off immediately reverts routing for new work within 60 seconds without losing in-flight tasks And rollback writes an audit entry referencing the prior version and initiator And per-environment flags (Dev, UAT, Prod) are isolated
Change approvals and auditability
Given a draft rule set created by User A When User B (with Approver role) reviews, requests changes, and finally approves the rule set Then publishing requires at least two distinct approvers or one approver plus automated policy check, per-tenant policy And every create, edit, approve, publish, rollback action is recorded with user, timestamp, diff of changes, and reason And the system allows reverting to any prior version and restores its exact mappings and conditions
Hot update via configuration service and routing engine integration
Given a rule set is published When the configuration service receives the update Then the routing engine begins evaluating new rules for newly ingested and newly progressed items within 60 seconds, and does not retroactively alter in-flight routing unless explicitly configured with a retroactiveApply flag And updates are idempotent, include a checksum, and fail closed with automatic rollback to the last good version if application fails And metrics and health indicators expose publish latency, evaluation errors, and rule hit rates
Per-tenant scoping and role-based access
Given a user is scoped to Tenant A with Config Admin role When they create or edit rules Then rules, templates, queues, and checklists visible are limited to Tenant A’s scope and line-of-business permissions And attempts to reference cross-tenant assets are blocked And users without Config Admin cannot publish or approve rules
Orchestrated Rerouting & Checklist Simplification
"As an adjuster, I want at-risk claims to move seamlessly into a fast-track flow so that I can continue work without losing context or re-entering data."
Description

Executes switchover as an atomic orchestration that pauses the current workflow, reassesses eligibility, and transitions the claim to the designated fast-track path without data loss. Reassigns ownership to qualified adjusters based on skills and capacity, updates queue placement, and swaps in a simplified checklist while preserving mandatory steps and current task state. Ensures idempotency, concurrency safety, and rollback on failure or manual cancel. Synchronizes SLA clocks and notifications, maintains full history of moves and mappings, and exposes outcome events for analytics and supervision.

Acceptance Criteria
Atomic Switchover Without Data Loss
Given an in-progress claim with active tasks, attachments, and captured fields When the SLA risk score crosses the configured threshold and switchover is triggered Then the system pauses the current workflow instance and creates a consistent snapshot of workflow, task states, and data before any changes And the switchover executes as a single atomic transaction where either all changes commit or none do And no task states, attachments, notes, or data fields are lost, duplicated, or left in an indeterminate state And no partial state is visible to any user during the transition And a switchover transaction ID is recorded and associated to all affected records
Eligibility Reassessment and Fast-Track Path Selection
Given the current published eligibility ruleset and the claim’s latest data snapshot When the switchover transaction starts Then the claim is re-evaluated deterministically against the ruleset using the snapshot inputs And if eligible, the designated fast-track path ID is selected and recorded with rule hit explanations And if not eligible, the switchover is aborted with no changes and a machine-readable reason code is logged And the ruleset version, decision outcome, and evaluation timestamp are stored in the audit log
Ownership Reassignment and Queue Placement
Given an approved skills matrix, licensing constraints, jurisdictions, and capacity scores for adjusters When a claim is fast-tracked by switchover Then ownership is reassigned to a qualified adjuster whose skills and license match the claim and whose capacity score is within the configured threshold And the claim is placed into the designated fast-track queue for that line of business and jurisdiction And previous and new owners receive notifications of the reassignment And the reassignment and queue move are completed within 2 seconds of switchover commit
Checklist Simplification with Mandatory Step Preservation
Given a base checklist with mandatory flags and a simplified fast-track checklist template with task mappings When switchover commits Then the simplified checklist replaces the base checklist for the claim And all mandatory steps from the base checklist are preserved as mandatory in the resulting checklist whether mapped or appended And in-progress tasks are mapped to their equivalents with their current completion state, evidence, and timestamps retained And non-mandatory tasks without a mapping are closed as superseded with a reason code And no user-entered data or attachments linked to tasks are orphaned
Idempotency and Concurrency Safety
Given an idempotency key is generated per switchover candidate claim When multiple switchover triggers occur concurrently or the same trigger is retried within the idempotency window Then at most one switchover transaction executes for the claim and others return the prior outcome without side effects And the final state with one or many triggers is identical to a single successful execution And lock acquisition, if any, times out within the configured timeout and is logged without deadlocks
Rollback on Failure or Manual Cancel
Given any step of switchover fails validation, encounters an execution error, or a manual cancel is requested before commit When the error or cancel is detected Then the system rolls back all provisional changes and restores the pre-switchover workflow, checklist, ownership, queues, and SLA timers from the snapshot And a failure notification is sent to designated roles with a machine-readable reason code and human-readable summary And no orphaned or duplicate tasks remain after rollback And retry is available up to the configured maximum attempts with exponential backoff, with all attempts logged
SLA Synchronization, Notifications, and Outcome Events
Given SLA timers and breach forecasts are defined per workflow path and step When switchover commits Then SLA timers are recalculated using elapsed time on the prior path and targets of the fast-track path and saved atomically with the new workflow state And breach forecasts and dashboards update within 5 seconds of commit And claimant nudges and document requests specific to the fast-track path are scheduled or sent while any obsolete notifications are canceled And a structured outcome event including transaction ID, ruleset version, path mapping, timing metrics, and result (switched, no-op, rolled-back) is emitted to the analytics and supervision topics
Targeted Claimant Nudges & DocChase
"As a claimant, I want clear, timely prompts for exactly what is needed so that I can provide it quickly and keep my claim moving forward."
Description

Automatically identifies blockers on the critical path, such as missing documents or unanswered questions, and triggers targeted outreach via SMS, email, and portal notifications with secure upload links and contextual guidance. Leverages ClaimFlow’s NLP extraction to specify exactly what is needed, supports multilingual templates, configurable cadence and quiet hours, and stops outreach when requirements are met. Integrates with DocChase to manage requests, expirations, and escalations to phone outreach when unresponsive. Captures delivery/read/upload events in the claim timeline to accelerate resolution and reduce adjuster follow-ups.

Acceptance Criteria
Missing Document Identified — Multichannel Nudge Trigger
Given a claim has a required document missing on the critical path and the claimant has at least one verified contact channel (SMS or email) or a portal account When the blocker is detected by the workflow engine Then the system generates a targeted message specifying the exact missing document, acceptable formats, and due date, and includes a secure upload link And sends via the configured primary channel within 2 minutes and posts a portal notification And associates the outreach to a DocChase request ID tied to the claim
NLP-Driven Request Specificity and Confidence Handling
Given ClaimFlow NLP identifies the missing item from intake notes, prior uploads, and form fields When composing the outreach content Then the message must name the specific document (e.g., “front and back of driver’s license”), include contextual guidance, and list acceptable alternatives And if NLP confidence is ≥ 0.80, auto-send using the specific template And if NLP confidence is < 0.80, route to a generic template and create an adjuster review task prior to send
Multilingual Template Selection and Localization
Given the claimant’s preferred language is stored on the claim (e.g., es-ES) When generating the nudge Then the system selects the matching language template and renders localized dates, currency, and timezones And if no localized template exists, it falls back to English with a prefatory line indicating the fallback And all dynamic fields (names, document types) are correctly localized without placeholder leakage
Cadence Configuration and Quiet Hours Enforcement
Given a cadence of 3 attempts at 0h, +24h, +72h and quiet hours of 20:00–08:00 claimant local time When scheduling outreach Then no messages are sent during quiet hours and sends are deferred to 08:00 And the minimum interval between attempts is respected within ±5 minutes And if the due date would be missed due to quiet hours, the final attempt is scheduled at the earliest permissible time and flagged as “at-risk” for adjuster visibility
Auto-Stop Outreach Upon Fulfillment
Given the claimant uses the provided link or portal to upload the requested item When the file passes validation (correct type, legibility score ≥ threshold, virus scan passed) Then the associated DocChase request is marked Complete And all pending/scheduled nudges for that request are canceled within 30 seconds And the claimant receives a single confirmation message; no further nudges are sent for that item
DocChase Expiration and Escalation to Phone Outreach
Given a DocChase request remains unfulfilled after the configured expiration (e.g., 72 hours) and all scheduled nudges were sent without response When the request expires Then the system creates a phone outreach task in the adjuster queue with the claimant’s best number and a scripted checklist And the claim is tagged “Phone Escalation Pending” until an outcome is logged And if two phone attempts within 24 hours are unreachable/no-voicemail, escalate to supervisor queue with an SLA timer
Timeline Event Capture for Outreach and Uploads
Given any outreach send/delivery/read event or claimant upload occurs When the event is processed Then a claim timeline entry is created within 10 seconds including UTC timestamp, channel, template ID, DocChase request ID, status (sent/delivered/read/uploaded), and actor (system/claimant) And secure link tokens are masked and PII redacted per policy And timeline filters allow adjusting view by event type and channel
Compliance Guardrails & Audit
"As a compliance officer, I want automated guardrails and full auditability so that expedited handling never violates regulations or carrier policies."
Description

Applies a policy engine that enforces carrier and jurisdictional requirements during switchover, preventing removal of mandatory steps, documents, or approvals and blocking ineligible fast-track paths. Validates that simplified checklists still meet regulatory minimums and internal controls, and requires exception approvals where needed. Records an immutable audit trail of rule versions, decisions, actors, timestamps, reasons, and supporting evidence, with exportable reports for audits and complaint handling. Monitors configurations for conflicts and flags noncompliant setups before activation.

Acceptance Criteria
Block Ineligible Fast-Track Paths Based on Jurisdiction Rules
Given a claim with jurisdiction=CA, policy_type=Auto, loss_type=BodilyInjury And fast-track path FT-1 is marked ineligible by rule R-FT-CA-01 v5 for those attributes When SLA Switchover evaluates routing due to breach risk >= High Then the system must not present or select FT-1 And the system must select an eligible path if available or retain current queue if none are eligible And the decision record includes rule_id=R-FT-CA-01, rule_version=5, evaluated_attributes, eligible_paths, and reason_code=FT_INELIGIBLE_JURISDICTION And the decision is written to the audit ledger with timestamp, actor=engine, and previous_hash And any attempt to force-select FT-1 is blocked with error_code=RULE_BLOCK and is audit-logged with user_id and reason
Prevent Removal of Mandatory Steps During Switchover
Given a workflow contains mandatory steps S1, S2, S3 mandated by carrier/regulator with approver roles assigned When a simplified checklist is proposed during switchover Then S1, S2, S3 must remain present with unchanged required artifacts and approver roles And any attempt to remove or downgrade S1–S3 is blocked with validation errors listing step_ids and governing rule references And the final checklist diff explicitly shows preserved steps and allowed modifications And the outcome is audit-logged with rule_version, validator_id, and checklist_version
Validate Simplified Checklist Meets Regulatory Minimums
Given a simplified checklist proposal for claim_category=Property, jurisdiction=NY When the compliance validator runs against rule_set RS-NY-PROP v3 Then the checklist must include all required documents, approvals, disclosures, and timebound actions defined in RS-NY-PROP v3 And validation fails if any required item is missing, outputting a missing_item list with citations And validation passes only if 100% of required items are present and mapped to responsible roles And a validation certificate with checksum, rule_set_id, rule_set_version, validator_id, and effective_date_range is stored in the audit trail
Require Exception Approvals for Policy Deviations
Given a switchover configuration deviates from internal control rule IC-APPR-02 with severity>=Minor When a user attempts to activate the configuration Then the system requires approvals per approval_matrix M (e.g., ComplianceOfficer and ClaimsManager) before activation And activation remains blocked until all required approvals are granted And approver decisions, comments, timestamps, and attached evidence are captured And pending approval requests auto-expire after SLA and notify stakeholders And the exception record is created with unique_id, deviation_details, final_disposition, and is audit-logged
Immutable Audit Trail for Rule Decisions and Actions
Given any switchover decision, rule evaluation, configuration change, or override occurs When the action is committed Then an append-only audit record is written containing: event_type, actor_id/type, claim_id, rule_ids/versions, inputs_evaluated, decision_outcome, reason_codes, evidence_refs, UTC timestamp, previous_hash, and record_hash And a read-only API exposes a chronological chain for a claim or configuration item And chain verification detects tampering by validating hash continuity And retention policy >= 7 years (configurable per carrier) is enforced with legal hold support
Exportable Audit and Complaint Handling Reports
Given a compliance officer requests a report for date_range and jurisdiction filters When the report is generated Then it must include switchover decisions, validations, exceptions, and outcomes with all audit fields and rule version snapshots And export completes within 60 seconds for up to 10,000 records to CSV and PDF And PII is redacted per role-based access rules And the report includes provenance metadata: creator_id, filters, run_timestamp, record_count, and report_hash And the generation event is audit-logged with success/failure status
Configuration Conflict Detection Before Activation
Given a new or edited switchover configuration is submitted for activation When the pre-activation compliance check runs Then the system detects conflicts including jurisdictional mandate violations, overlapping eligibility, missing approver assignments, and contradictory rule priorities And a blocking list of conflicts is presented with severity, impacted_claims_estimate, and remediation guidance And activation is prevented until all Blocker-severity conflicts are resolved And the check results, referenced rule versions, resolver actions, and final outcome are audit-logged
SLA Dashboard & Manual Override
"As a team lead, I want a live SLA dashboard with override controls so that I can manage exceptions and keep throughput high without breaching SLAs."
Description

Provides a role-based dashboard that surfaces claims approaching breach, current risk scores and ETAs, recent and pending switchovers with reason codes, and the capacity of target queues. Enables authorized users to approve, deny, trigger, or roll back a switchover, with justifications captured for audit. Offers filters by carrier, line, jurisdiction, and queue, real-time alerts via in-app and email/Slack, and export for operational reviews. Integrates with the risk service and orchestration layer to reflect live state and ensures all actions are tracked and reversible where permitted.

Acceptance Criteria
Surface Near-Breach Claims with Risk Details
Given a user with the Claims Manager role opens the SLA Dashboard for their assigned carriers When the dashboard loads with the default risk thresholds (riskScoreThreshold and breachEtaThreshold) from configuration Then the list includes all claims where riskScore ≥ riskScoreThreshold OR breachETA ≤ breachEtaThreshold And each row displays Claim ID, Carrier, Line, Jurisdiction, Current Queue, Risk Score (0–1), Breach ETA (UTC), SLA Tier, and Last Switchover State And the total count matches the risk service response for the same scope And the data auto-refreshes at the configured interval (≤ 60s) with a visible Last Updated timestamp And an empty-state message appears if no claims meet the criteria
Role-Based Controls for Switchover Actions
Given role-based access control is configured with roles: Viewer, Analyst, Operations Lead, Admin When a Viewer or Analyst opens a claim row Then Approve, Deny, Trigger Switchover, and Roll Back actions are not available (hidden or disabled with tooltip) When an Operations Lead or Admin opens the same row Then Approve, Deny, Trigger Switchover, and Roll Back actions are enabled subject to orchestration constraints And each action requires a justification text (minimum 15 characters) before submission And unauthorized action attempts are rejected with 403 and recorded in the security log
Manual Approve/Deny/Trigger/Rollback with Audit Trail
Given an authorized user performs Approve, Deny, Trigger Switchover, or Roll Back on a selected claim When the action is submitted with a reason code and justification Then an audit record is created with fields: claimId, action, previousState, newState, reasonCode, justification, actorId, actorRole, timestamp (UTC), correlationId, and sourceIP And audit records are immutable and queryable by claimId and correlationId And the orchestration layer acknowledges the command with success within 5 seconds, or the UI displays a retry/error state without duplicating the action And Roll Back is only enabled when the orchestration layer reports a reversible prior step and no irreversible external postings exist; otherwise the control is disabled with an explanatory tooltip
Filtering by Carrier, Line, Jurisdiction, and Queue
Given the dashboard is loaded with claims When the user applies filters for Carrier, Line of Business, Jurisdiction, and Queue (single or multi-select) Then the results reflect the intersection of selected filters and update within 2 seconds for datasets up to 10,000 claims (p95) And the applied filters are reflected in the URL/share link and persist across page refresh for the current user And a Clear All action resets the dataset to the default unfiltered view And the results count, pagination, and export respect the active filters
Real-Time Alerts via In-App and Email/Slack
Given a user is subscribed to SLA alerts for specified carriers/queues When a claim crosses the configured breach risk threshold or undergoes a switchover state change Then an in-app notification appears within 60 seconds and an email or Slack message is sent within 60 seconds And each alert includes claimId, carrier, queue, riskScore, breachETA, event type, reason code, and a deep link to the claim in the dashboard And duplicate alerts for the same claim/event are suppressed for 30 minutes per recipient And failed email/Slack deliveries are retried up to 3 times with exponential backoff and delivery outcome logged
Operational Export of Visible Claims
Given a user with export permission has applied filters on the dashboard When the user requests an export Then a CSV and XLSX file are generated containing only the claims visible to that user and fields: claimId, carrier, line, jurisdiction, queue, riskScore, breachETA, SLA tier, lastSwitchoverAction, reasonCode, actor, timestamp And the export includes a header with generation time (UTC), filter summary, and record count And exports complete within 60 seconds for up to 100,000 rows; if larger or slower, an asynchronous export is started, progress is shown, and the user receives an email/Slack link on completion And the exported record count matches the dashboard row count at the moment the export was initiated
Live State and Capacity Integration
Given the dashboard is connected to the risk service and orchestration layer When the page loads or refreshes Then claim risk scores, ETAs, and switchover states reflect the latest available values, and target queue capacity is displayed as availableSlots/totalCapacity And a stale-data indicator is shown if any source data is older than 2 minutes And switchover approval is blocked when target queue availableSlots ≤ 0, prompting the user to choose an alternate approved path And if any upstream service is unavailable, the UI shows a degraded mode banner, disables mutating actions, and retries with exponential backoff while preserving read-only data

Root Cause

Generates post-event analyses for near-misses and breaches, quantifying delays from integrations, assignments, or missing artifacts. Recommends fix playbooks, tracks recurrence, and spotlights systemic issues to steadily lower breach rates.

Requirements

Unified Event Timeline
"As a claims operations manager, I want a unified timeline of all intake and routing events so that I can see where delays actually occurred and compare across similar claims."
Description

Aggregates and normalizes ClaimFlow workflow events, integration callbacks, user assignments, artifact/document states, NLP extraction outcomes, and message logs into a single, ordered timeline per claim and across cohorts. Correlates disparate IDs, deduplicates events, handles late-arriving data, and preserves precise timestamps and time zones. Exposes query API and storage schema for analytics, supports idempotent ingestion and retry, and attaches rich metadata (source, latency, actor) to each event to enable reliable downstream analysis.

Acceptance Criteria
Source Coverage and Event Normalization
Given events from workflow, integration callbacks, user assignments, artifact/document states, NLP extraction outcomes, and message logs, When they are ingested, Then all are transformed into a common event model with fields eventId, claimId, occurredAt (ISO 8601), receivedAt (ISO 8601), timezone (IANA), source, eventType, actorId (nullable), actorType (nullable), correlationId (nullable), payload (JSON), latencyMs. Given a valid event from any supported source, When ingested, Then validation enforces required fields and rejects payloads missing occurredAt, source, eventType, or claimId with HTTP 400 and machine-readable error codes. Given an accepted event, When stored, Then payload is preserved losslessly and eventType is mapped to a controlled vocabulary with no unmapped values.
Per-Claim Timeline Ordering with Precise Timestamps
Given a claim with events having different time zones and identical timestamps, When the timeline is retrieved, Then events are ordered by occurredAt normalized to UTC with a stable tiebreaker of receivedAt then eventId. Given events with timezone offsets, When stored, Then the original timezone string is preserved and round-trips unchanged on retrieval. Given a date range filter, When querying GET /claims/{claimId}/timeline?from=&to=, Then only events with occurredAt within the inclusive range are returned in order.
Cross-System ID Correlation and Deduplication
Given events sharing a correlationId or an integration callback referencing a workflow step ID, When ingested, Then they are linked via a common correlationId and retrievable by filtering correlationId=. Given duplicate deliveries of the same event (same source and sourceEventId or same Idempotency-Key), When ingested, Then only one event exists in storage and subsequent retries return HTTP 200 with the original eventId. Given semantically duplicate events with identical normalized hash of (source, eventType, claimId, occurredAt, payload hash) within a 5-minute window, When ingested, Then duplicates are flagged with duplicateOf=eventId and excluded from default timeline views unless includeDuplicates=true.
Late-Arriving and Out-of-Order Event Reconciliation
Given an event with occurredAt earlier than existing events in the claim, When ingested, Then it is inserted at the correct position in the timeline within 2 minutes and any derived durations are recomputed. Given a previously missing artifact state event that arrives late, When reconciled, Then the timeline shows consistent state transitions with no overlaps for the same artifact (at most one active state at any time). Given a correction event with the same sourceEventId and a higher revision, When ingested, Then a new event is appended with type=Correction and the prior event is marked supersededBy while remaining immutable.
Idempotent Ingestion and Retry Semantics
Given a POST /events with an Idempotency-Key header, When the same request is retried within 24 hours, Then the response body is identical and no additional event is created. Given transient backend failures during ingestion, When the client retries with exponential backoff, Then at-least-once delivery does not create duplicates and the final stored event count equals the number of unique Idempotency-Keys sent. Given concurrent ingests of the same sourceEventId, When processed, Then exactly one event is persisted and others return HTTP 200 with the existing eventId.
Event Metadata Completeness and Latency Computation
Given any stored event, When retrieved, Then it includes source, actorId (nullable), actorType (nullable), occurredAt, receivedAt, timezone, latencyMs=(receivedAt-occurredAt in milliseconds), ingestionMethod, and correlationId (nullable). Given occurredAt later than receivedAt due to clock skew, When computing latency, Then latencyMs is negative and the event is flagged with latencyFlag=clock_skew. Given an event without actor information, When stored, Then actorId and actorType are null and actorPresent=false to enable analytics filtering.
Query API and Cohort Timeline Retrieval
Given a set of claims matching filters (e.g., lineOfBusiness, jurisdiction, date range), When calling GET /cohorts/timeline with pagination, Then the API returns timelines grouped by claimId with total counts and a nextPage token. Given query parameters eventType, source, actorType, and minLatencyMs, When requesting a timeline, Then results are filtered server-side accordingly and respond within p95 ≤ 500 ms for single-claim queries and p95 ≤ 1500 ms for cohort queries up to 100k events. Given a request to GET /schema/timeline, When called, Then the API returns the analytics storage schema (fields, types, enums, version) including version and change log.
Delay Decomposition & Breach Attribution
"As a claims manager, I want delays quantified by cause so that I can target the highest-impact fixes."
Description

Computes cycle time per claim and decomposes delays into standardized categories (integration latency, assignment wait, missing required artifacts, manual review, customer follow-up). Uses configurable SLAs and workflow milestones to classify near-misses versus breaches, quantifies contributions in minutes and percentage share, and supports attribution across parallel tasks. Leverages ClaimFlow artifact presence and NLP tags to detect missing items, provides human-readable explanations and confidence, and emits structured results for reporting and automation.

Acceptance Criteria
Compute Cycle Time and Decompose Delays by Standard Categories
Given standardized delay categories [integration_latency, assignment_wait, missing_required_artifacts, manual_review, customer_follow_up] and claim milestones with ISO-8601 UTC timestamps When the decomposition runs for a claim Then total_cycle_time_minutes equals the elapsed minutes between first and final workflow milestone, rounded half-up to the nearest minute And each category produces minutes >= 0 as integers And the sum of category minutes equals total_cycle_time_minutes with an absolute tolerance of 1 minute due to rounding And each category includes a percent_share rounded to one decimal place computed from minutes/total_cycle_time_minutes And categories with zero contribution are included with minutes = 0 and percent_share = 0.0
SLA-Based Classification of On-Time, Near-Miss, and Breach
Given configurable SLAs per line_of_business and per terminal milestone, and a near_miss_threshold set to 0.9 by default And a computed total_cycle_time_minutes for the claim When the classification is evaluated Then classification = "On-Time" if total_cycle_time_minutes <= SLA_minutes And classification = "Near-Miss" if total_cycle_time_minutes > near_miss_threshold * SLA_minutes and <= SLA_minutes And classification = "Breach" if total_cycle_time_minutes > SLA_minutes And the applied SLA_minutes and near_miss_threshold are included in the output for auditability
Parallel Task Attribution Without Double Counting
Given overlapping task intervals across categories (e.g., customer_follow_up overlaps manual_review) And the attribution method configured as equal_share When the decomposition allocates minutes Then the sum of category minutes within any overlapping time window does not exceed the actual elapsed minutes of that window And overlapping minutes are split equally among the overlapping categories, rounding half-up so that the global sum across all categories still satisfies the total within a 1-minute tolerance And the output records attribution_method = "equal_share" at the claim level
Missing Required Artifacts Detection via NLP and Artifact Presence
Given a required artifact checklist for the claim type and available artifacts detected via system presence checks and NLP tags from messages/photos When evaluating artifact completeness Then the missing_required_artifacts category minutes accumulate from the earliest docs_requested event until all required artifacts for the phase are present, per artifact And each missing artifact appears in output with fields: name, first_detected_at (UTC), resolved_at (UTC or null), and contributed_minutes And on a labeled validation set of ≥200 claims, artifact-missing detection achieves precision ≥ 0.90 and recall ≥ 0.85 And confidence for the missing_required_artifacts category is computed and included as a value in [0.00, 1.00] with two decimal places
Human-Readable Explanations and Confidence Scores
Given a completed decomposition for a claim When generating explanations Then each category includes an explanation string 20–240 characters that references at least one milestone name and timestamp in ISO-8601 And each category includes a confidence field in [0.00, 1.00] with two decimal places reflecting evidence strength And explanations contain no PHI/PII beyond claim IDs and milestone names configured as safe terms And explanations and confidences are present for all categories, including those with zero minutes
Structured Output Contract for Reporting and Automation
Given a completed analysis When emitting results Then the output is valid JSON containing at minimum: claimId (string), lineOfBusiness (string), totalCycleTimeMinutes (integer >= 0), classification (enum: ["On-Time","Near-Miss","Breach"]), slaMinutes (integer > 0), nearMissThreshold (number in (0,1]), attributionMethod (string), milestones (object of ISO-8601 UTC timestamps), categories (array) And each categories[i] object contains: category (enum: ["integration_latency","assignment_wait","missing_required_artifacts","manual_review","customer_follow_up"]), minutes (integer >= 0), percent (number with 1 decimal, 0.0–100.0), confidence (number with 2 decimals, 0.00–1.00), explanation (string 20–240 chars) And JSON keys use snake_case and are stable across releases And the payload size per claim is ≤ 64 KB
Time Normalization and Rounding Rules
Given milestones provided in arbitrary time zones with offsets When computing durations Then all timestamps are normalized to UTC prior to calculation And cycle and category durations are computed in minutes with half-up rounding And for claims spanning daylight saving transitions, total_cycle_time_minutes equals the true elapsed UTC minutes And the absolute difference between the sum of category minutes and total_cycle_time_minutes is ≤ 1 minute
Root Cause Inference Engine
"As an operations analyst, I want the system to surface likely root causes with evidence so that I can prioritize systemic fixes over one-off anomalies."
Description

Infers likely root causes from repeated delay attributions and context (line of business, vendor, connector, adjuster workload, time-of-day, claim complexity). Combines configurable rules with statistical patterning to rank hypotheses with confidence and supporting evidence. Supports drill-down from cohort to claim and workflow-step levels, tunable thresholds, and whitelists/blacklists to reduce noise. Produces explainable outputs suitable for review and governance and integrates with existing ClaimFlow analytics pipelines.

Acceptance Criteria
Ranked Hypotheses with Confidence and Evidence
Given a labeled test set of ≥300 incidents across ≥3 lines of business and ≥5 vendors When the engine infers root causes Then each incident returns a ranked list of hypotheses with confidence scores in [0,1] and supporting evidence (attribution counts, implicated workflow steps, timestamps, triggered rules, salient context features) And Top-3 hypotheses contain the ground-truth cause in ≥80% overall and ≥70% within each line of business And Top-1 accuracy is ≥60% overall And predictions with confidence ≥0.7 achieve precision ≥0.7, and predictions with 0.5–0.7 achieve precision ≥0.5 And each hypothesis includes a human-readable explanation listing rules fired (if any) and key features with contribution weights, plus claim_id and step_id references And median per-incident inference time is ≤300 ms on a batch of 1,000 incidents
Rules and Statistical Patterning Fusion
Given configuration flags to enable/disable the rules engine and the statistical model When both components are enabled Then the ensemble achieves Top-3 recall at least 5% relative higher than the better single component on the same validation set And per-hypothesis output exposes component scores and the final fused score When only rules are enabled Then outputs are labeled source="rules-only" and match the rules engine scores exactly (within ±1e-6) When only statistics are enabled Then outputs are labeled source="stat-only" and match the statistical model scores exactly (within ±1e-6) And fusion weights are configurable per line of business and changes are versioned and auditable
Context Utilization and Graceful Degradation
Given inputs may include line of business, vendor, connector, adjuster workload, time-of-day, and claim complexity When these fields are present Then the engine records their ingestion and shows each used context feature in the evidence when its contribution magnitude is ≥0.05 (default τ, configurable) When any context field is missing Then the engine proceeds without error, logs missingness in metadata, and ranking changes by no more than one position in ≥95% of cases compared to an imputed baseline And in counterfactual tests where a single context factor is altered to reflect a known delay pattern Then that factor appears in the top hypothesis evidence in ≥90% of cases
Cohort-to-Claim-to-Step Drill-Down
Given a cohort aggregation of incidents by root-cause hypothesis When a client requests drill-down to claim and workflow-step levels via API Then identifiers are consistent across levels (cohort_id, claim_id, step_id) and the sum of claim-level counts equals the cohort-level count within ±1% And step-level payloads include step_id, step_name, connector/vendor, timestamps, and delay duration used in evidence And average response times are ≤2 s for cohort listing (≤10,000 incidents), ≤500 ms for claim-level, and ≤300 ms for step-level endpoints And evidence entries include back-references to cohort_id, claim_id, and step_id
Threshold Tuning and Sensitivity Controls
Given configurable thresholds (confidence_min, frequency_min, min_affected_claims) at global, line-of-business, and vendor scopes When thresholds are changed via API Then the next inference run applies them and returns a change summary of added/removed hypotheses and metric deltas And a preview endpoint returns the expected impact of a proposed change without persisting it And a sensitivity report endpoint returns precision/recall at three presets: conservative, balanced, aggressive And all threshold changes are versioned with user, timestamp, scope, and reason in the audit log
Whitelist and Blacklist Noise Controls
Given whitelists and blacklists for cause codes, vendors, connectors, and claim_ids When a blacklist is applied Then blacklisted items do not appear in surfaced hypotheses or recurrence counts, and the action is recorded with scope and author When a whitelist is applied Then whitelisted items can surface even if below thresholds and are labeled as whitelisted in outputs And lists take effect within one run cycle and support rollback with before/after counts shown And application of blacklists does not change non-blacklisted hypothesis precision by more than ±2% on the validation set
Analytics Pipeline Integration and Governance
Given ClaimFlow analytics pipeline schemas and event topics are registered When the engine completes a run Then it writes a dataset "root_cause_inferences" with fields: run_id, model_version, ruleset_version, cohort_id, claim_id, step_id, hypothesis, confidence, evidence, context, thresholds_applied, and publishes an event "rc.inference.completed" containing run_id and artifact URI And re-running with the same run_id and input snapshot yields byte-identical outputs and matching checksums And an export endpoint returns JSON and CSV with PII fields redacted, and each export is logged with requester and purpose And all outputs pass schema validation and are discoverable in the analytics catalog within 2 minutes of run completion
Fix Playbook Recommendations
"As a workflow owner, I want recommended fix playbooks automatically generated and actionable so that we can implement improvements quickly and consistently."
Description

Maps identified root causes to actionable remediation playbooks (e.g., adjust connector retry/backoff, modify assignment rules, request mandatory artifacts earlier, update customer messaging). Generates step-by-step guidance with owners, SLAs, and expected impact, and can auto-create tasks in Jira/ServiceNow and ClaimFlow workflow configurations after approval. Supports carrier-specific templates, versioning, and pre/post-change metrics to validate outcomes and drive continuous improvement.

Acceptance Criteria
Map Root Cause to Playbook
Given a completed RCA with one or more root cause codes, When recommendations are generated, Then at least one remediation playbook is returned for each root cause code. Given a carrier and product line context, When mapping occurs, Then a carrier-specific playbook is selected by exact root cause match; if none exists, a global default playbook is selected. Then each recommendation includes: playbook title, rationale, confidence score (0.00–1.00), and expected impact with metric, baseline, and projected delta (absolute or %). When no mapping exists, Then the system returns a “No playbook available” result and offers an action to create a new mapping template. Then all mappings and selection decisions are recorded with timestamp and actor for auditability.
Step-by-Step Guidance with Owners, SLAs, and Impact
Given a selected recommendation, When the playbook is rendered, Then it displays ordered steps with step number, action description, owner (role or named user), SLA (duration + unit), prerequisites, and dependencies. Then field validation prevents approval if any step is missing owner or SLA, and inline errors identify the missing fields. Then each step may include deep links to system locations (e.g., connector settings, assignment rules) and these links resolve successfully for authorized users. Then the playbook summary aggregates expected impact across steps and shows the primary KPI, target threshold, and estimated completion date based on SLAs.
Approval Gating and Auto-Creation of External Tasks
Given a user with Approver role, When they approve a recommendation, Then tasks are created in the configured destinations (Jira and/or ServiceNow) and ClaimFlow workflow updates are queued per playbook steps. Then each created task includes: title, description, priority, assignee, due date derived from SLA, labels/tags (claimflow-run-id, playbook-id, playbook-version), and a backlink to the ClaimFlow recommendation. Then task creation completes within 60 seconds and returns external task IDs; idempotency ensures repeat approvals within 24 hours return the same task IDs without duplicates. When any destination creation fails, Then no partial state persists; the transaction is rolled back, a human-readable error with correlation ID is shown, and retry is available.
Carrier-Specific Templates and Overrides
Given a carrier is in context, When templates are listed, Then carrier-specific playbooks are shown first, followed by global templates. When an admin overrides a global template for a carrier, Then a new carrier-specific template is created without altering the global one, and is marked as superseding for that carrier. Then selection logic prefers the most recent Published carrier-specific version; if none exists, it falls back to the most recent Published global version. Then permissions restrict create/edit/publish to Template Admins for that carrier; other users can preview but not modify templates.
Playbook Versioning and Change History
Given a playbook is edited, When saved, Then a new version is created using semantic versioning (MAJOR.MINOR.PATCH), leaving prior versions immutable and viewable. Then each version records author, timestamp, change summary, and status (Draft, In Review, Published), and only users with Publish permission can set status to Published. Then RCA runs store the exact playbook-version used; re-runs preserve the original linkage even if newer versions exist. Then rollback is supported by allowing selection of any prior Published version for new runs without altering history.
Pre/Post-Change Metrics and Outcome Validation
Given a recommendation is approved, When the playbook is executed, Then baseline metrics are captured over a configurable window (default 30 days) prior to execution, and a post-change observation window (default 14 days) starts at task completion. Then the system computes deltas for defined KPIs (e.g., breach rate, average intake time, follow-up count) and compares actual impact with projected impact. Then if the primary KPI meets or exceeds the success threshold defined in the playbook, outcome status is set to Achieved; otherwise Not Achieved with variance reported. Then all metric inputs, windows, calculations, and sources are auditable and exportable (CSV/JSON) alongside the recommendation and playbook version used.
Recurrence Tracking & Trend Alerts
"As a head of claims, I want to monitor recurrence and get alerted to negative trends so that we can intervene before breach rates climb."
Description

Tracks recurrence and frequency of each identified cause over time, visualizes trends and heatmaps by LOB, vendor, geography, integration, and incident type, and correlates with breach rates. Provides configurable thresholds and alerting (email/Slack/Teams) with suppression windows to prevent alert fatigue. Supports weekly digests and drill-through to affected claims, enabling proactive intervention before breach rates rise.

Acceptance Criteria
Cause Recurrence Calculation by Time Window
Given claims with identified root causes and timestamps exist within the tenant scope When a user requests recurrence metrics for a selected time window (daily, weekly, monthly) and lookback period (up to 26 intervals) Then the system returns, for each interval, the count and frequency per cause normalized per 100 claims processed in that interval And soft-deleted/excluded claims are omitted and LOB/vendor/geography/integration/incident-type filters are honored And results for up to 100,000 claims over 26 intervals return with p50 latency <= 2s and p95 <= 5s via UI and API And calculations are consistent between UI and API (absolute difference <= 0.1%)
Trend and Heatmap Visualization by Dimensions
Given dimension selectors for LOB, vendor, geography, integration, and incident type are available When the user switches between trend line and heatmap views and applies any combination of the dimension filters Then charts render recurrence count and frequency per cause accurately for the selected scope And heatmap cells display a color scale, exact values, and period-over-period change in tooltip And empty segments are labeled "No data" and not treated as zero And the visualization updates with p95 latency <= 3s for datasets up to 100,000 claims
Breach Rate Correlation and Significance
Given breach outcome flags per claim are available for the selected scope When a user selects a cause and a time range of at least 8 intervals Then the system computes and displays the Pearson correlation coefficient (r) between cause frequency and breach rate across intervals, with p-value And a "Strong correlation" badge appears when |r| >= 0.6 and p < 0.05 And if fewer than 8 intervals or insufficient variation exists, the UI displays "Insufficient data" and disables the badge And the correlation overlay/regression line matches the displayed statistics (tolerance <= 0.01)
Configurable Threshold Alerts with Suppression
Given a user configures an alert rule with metric (count or rate), scope filters, comparator, threshold value, evaluation window, channel(s) (Email/Slack/Teams), and suppression window duration When the evaluated metric breaches the threshold within the window Then exactly one alert is sent per unique rule and scope during the suppression window And subsequent breaches during the active suppression window are suppressed and summarized in the next alert after the window expires And alerts include rule name, scope, metric, threshold, current value, time window, and deep link to the scoped dashboard And identical rules targeting the same scope are deduplicated (max one notification) And delivery succeeds to each configured channel or is retried up to 3 times on transient failure
Weekly Digest Delivery with Drill-Through
Given weekly digests are enabled with a default schedule of Monday 09:00 local time (configurable per workspace) When the digest is generated for the prior week Then recipients receive a single email/Slack/Teams message containing: top 5 recurring causes by rate, top 5 rising causes by week-over-week change, a heatmap snapshot, and a summary of alerts triggered And each listed item includes a deep link that opens the dashboard with identical filters/timeframe applied And users can opt in/out without affecting alert rules And digests are delivered with p95 latency <= 10 minutes from the scheduled time
Drill-Through to Affected Claims from Trends and Alerts
Given a user clicks a cause in a chart or a deep link in an alert/digest When the drill-through view opens Then a claims table is displayed filtered by the selected cause, timeframe, and dimensions from the source context And the table shows Claim ID, Policy/LOB, Vendor, Geography, Integration, Incident Type, Breach Status, and Created/Updated timestamps And the user can export the filtered list to CSV (up to 10,000 rows) and paginate in-app And the drill-through loads with p95 latency <= 4s for up to 5,000 matching claims
Alert and Threshold Audit Logging
Given alert rules are created/edited/deleted and alerts are triggered When such events occur Then an audit log entry is recorded with timestamp, actor (user/service), rule ID, before/after values (for changes), trigger scope, metric values, and delivery outcomes And audit entries are filterable by date range, actor, rule ID, and event type and exportable to CSV And audit data is retained at least 365 days and is immutable to non-admin users
Systemic Issue Spotlight Dashboard
"As an executive, I want a dashboard of systemic issues and their potential impact so that I can align teams on the most valuable improvements."
Description

Delivers dashboards highlighting top systemic issues ranked by impact (minutes saved potential, affected claims, cost) with filters for time range, LOB, carrier, integration, adjuster team, and SLA type. Enables drill-through to example claims and evidence, sharing/export, and role-based views for executives, managers, and analysts. Integrates seamlessly with ClaimFlow’s analytics UI for a consistent experience.

Acceptance Criteria
Impact-Ranked Systemic Issues List
Given data exists for the selected scope When the dashboard loads Then issues are sorted by minutes saved potential descending by default Given two issues have equal minutes saved potential When ranked Then ties are broken by affected claims descending, then by cost descending Given a user selects a different sort metric (minutes saved potential, affected claims, cost) When the selection is applied Then the list reorders accordingly within 1500 ms p95 Given the list is rendered When each issue row/card is displayed Then it includes minutes saved potential (rounded to nearest minute), affected claims count, and estimated cost impact formatted to the user’s locale Given the Top N selector is set to 10 When the page loads Then exactly 10 issues are shown and pagination appears if more than 10 issues exist
Multi-Dimensional Filtering and Persistence
Given no prior preferences exist When the dashboard is first opened Then the time range defaults to Last 30 days and all other filters are set to All Given a user selects any combination of time range, LOB, carrier, integration, adjuster team, and SLA type (including multi-select) When Apply is clicked Then the list and summary metrics update within 1500 ms p95 Given filters are applied When the page is refreshed or reopened via a copied URL Then the same filter state is restored via URL parameters Given incompatible filters yield zero results When applied Then a No issues match current filters empty state is shown within 1000 ms and a Clear filters action is available Given filters are changed When navigating away and back via browser back/forward Then the previous filter state is preserved
Drill-Through to Claims and Evidence
Given an issue is visible in the list When View examples is clicked Then a side panel opens within 1000 ms p95 listing at least 5 representative claims matching the current filters Given the examples panel is open When entries are displayed Then each shows claim ID (clickable), LOB, carrier, SLA type, assigned team, occurrence timestamp, delay source, and links to evidence artifacts (e.g., message excerpt or photo ID) Given a claim ID link is clicked When navigation occurs Then the claim opens in a new browser tab within ClaimFlow with context preserved and without losing current dashboard state Given the examples panel is closed When returning to the dashboard Then scroll position and applied filters remain unchanged
Export and Share Views
Given filters are applied When Export CSV is clicked Then a file downloads within 10 seconds including visible columns for each issue plus a stable issue identifier and the applied filters encoded in file metadata or header row Given the current view is open When Export PDF is clicked Then the PDF captures the visible ranking, charts, and filters, includes a generated-on timestamp with timezone, and paginates content without truncation Given Create share link is used When a recipient with sufficient permissions opens the link Then the exact view and filters load; recipients without permission see an access denied message Given a share link is created When 30 days elapse or the owner revokes the link Then the link no longer grants access
Role-Based Views and Data Access Controls
Given an Executive role user accesses the dashboard When the page loads Then the default view shows organization-wide top 5 issues with aggregate metrics and PII redacted Given a Manager role user accesses the dashboard When the page loads Then the default scope is limited to the manager’s teams, with drill-down to team-level issues and non-redacted data only for those teams Given an Analyst role user accesses the dashboard When the page loads Then advanced controls (custom metrics, raw export) are available and restricted to data the analyst is permitted to view Given a user lacks access to a carrier or LOB When filtering or manipulating the URL Then those options are hidden or disabled and cannot be accessed via URL tampering
Seamless Analytics UI Integration and Performance
Given the dashboard renders within ClaimFlow analytics When loaded Then global header, breadcrumbs, theming, and navigation match adjacent analytics pages for a consistent experience Given viewport widths of 320, 768, 1024, and 1440 px When viewed Then the layout is responsive without horizontal scroll and all interactive controls are usable Given initial load on a warm cache and dataset up to 100k issues When loading Then p95 time-to-interactive is ≤ 2.0 seconds and p99 is ≤ 3.5 seconds Given navigation from another analytics page When using browser back/forward Then history operates without a full page reload and without losing filter state
Data Freshness, Accuracy, and Empty States
Given the data pipeline updates hourly When the dashboard loads Then a Last refreshed timestamp is shown and is within 60 minutes of the current time Given affected claims and cost impact totals on the dashboard When validated against source data for the same filters Then totals reconcile within 0.5% or 5 claims (whichever is greater) and currency uses the user’s locale Given no data matches the selected filters When the view renders Then an empty state appears with guidance to adjust filters and no console errors are thrown Given currency impact metrics are displayed When formatting occurs Then values use the carrier’s currency and the user profile’s locale formatting
Governance, Audit & Compliance
"As a compliance lead, I want an auditable trail of analyses and decisions with appropriate data protection so that we meet regulatory requirements and internal policies."
Description

Captures a complete audit trail of analyses, attributions, recommendations, decisions, and changes applied, including who approved or overrode recommendations and why. Versions playbooks and models, enforces role-based access control and least-privilege, and redacts PHI/PII in analytics outputs. Provides exportable reports for regulators and internal audits to ensure compliance with insurer policies and applicable regulations.

Acceptance Criteria
Audit Trail Capture for Root Cause Analyses
Given a near-miss or breach analysis is created in ClaimFlow Root Cause When the analysis is saved or updated Then an audit entry is appended capturing timestamp (UTC ISO 8601), unique analysis ID, actor (user/service), source IP, input artifact references (message IDs, photo IDs), detected facts, attributions, recommendations, workflow actions, and before/after values for changed fields And prior audit entries remain immutable and queryable by analysis ID within 2 seconds for datasets up to 100k analyses And audit entries include environment (prod/stage), correlation ID, and request ID for traceability
Approval and Override Logging with Reasons
Given a recommendation is presented to an authorized user When the user approves or overrides the recommendation Then the system requires selection of Approve or Override and a reason of at least 10 characters And the audit trail records user ID, role, timestamp, decision, reason, and the affected recommendation ID And actions without a reason are blocked with a validation error And the resulting decision is linked to subsequent workflow changes in the audit trail
Playbook and Model Versioning & Traceability
Given a playbook or ML model used by Root Cause is updated When the update is published Then a new immutable version is created with semantic version, changelog, publisher, approver, and effective date And analyses record the exact playbook version, model version, model hash, and configuration parameters used And re-running an analysis with the same inputs and versions produces identical outputs (deterministic inference) and the run is linked to the original via audit And rollback to a prior version requires approver authorization and is fully audited
RBAC and Least-Privilege Enforcement
Given roles (e.g., Adjuster, Claims Manager, Compliance Officer, Admin) are configured When a user or service attempts to view, export, approve/override, or configure governance data Then access is allowed only if the permission is granted by role; otherwise a 403 is returned and the attempt is audited And permission changes (grant/revoke) are logged with actor, target, before/after, timestamp, and reason And default posture is deny-by-default with no implicit privileges for new users or services
PHI/PII Redaction in Analytics Outputs
Given analytics outputs may contain PHI/PII When outputs are rendered in UI, exported, or sent via notifications Then PHI/PII fields are redacted per policy (e.g., emails masked, phone numbers masked, names generalized, addresses truncated) for users without clearance And redaction occurs before data is persisted to logs or analytics stores And automated tests on a held-out dataset achieve at least 99.5% precision and 99.0% recall for PHI detection/redaction And cleared users must explicitly justify purpose-of-use to reveal de-identified data, which is audited
Exportable Compliance Reports
Given a compliance officer requests a governance report for a date range and filters When the report is generated Then the system produces PDF and CSV within 60 seconds containing audit event summaries, approvals/overrides with reasons, version changes, access denials, and redaction metrics And the export includes generation timestamp, preparer identity, parameter summary, file hash, and a digital signature And regenerating the report with the same parameters produces identical content
Tamper-Evident Audit Log Integrity & Retention
Given audit logs are stored in the governance subsystem When entries are appended and later validated Then each entry contains a hash pointer to the previous entry (SHA-256) to establish an integrity chain And any alteration breaks the chain and triggers an integrity alert and incident record And logs are stored on WORM-capable storage with a 7-year retention policy and deletion requires compliance approval recorded in audit

SLA Simulator

Interactive what-if modeling to forecast breach rates under staffing changes, surge volumes, stricter SLAs, or new routing rules. Outputs required headcount, queue times, and risk by step so leaders can plan confidently and avoid surprises.

Requirements

Interactive Scenario Builder
"As an operations leader, I want to configure and save staffing, volume, SLA, and routing scenarios so that I can explore outcomes without impacting production workflows."
Description

Provides a guided UI to create, edit, and compare what‑if scenarios by adjusting staffing levels per role and shift, arrival volumes (including surges and seasonality), SLA targets per workflow step, and routing rules. Pulls current workflow definitions, step names, and teams from ClaimFlow so scenarios align with live operations. Supports time windows, effective dates, business calendars, and role capacities. Persists scenarios with names, tags, and notes for reuse, includes cloning/versioning, and enforces org-level permissions. Validates inputs, highlights conflicting settings, and previews expected changes before running simulations.

Acceptance Criteria
Load Live Workflow Metadata into Scenario Builder
Given a user with "Scenario Creator" permission opens the Scenario Builder, When the page initializes, Then the builder requests current workflow definitions, step names, and teams from ClaimFlow APIs and populates selection controls within 3 seconds. Given the metadata is older than 24 hours, When the builder opens, Then the system auto-refreshes the metadata before user input and displays "Last updated <timestamp>". Given the API call fails, When the builder loads, Then a non-blocking error banner with Retry appears, dependent fields are disabled, and the last successful metadata timestamp is shown until a refresh succeeds.
Configure Staffing by Role, Shift, and Capacity
Given an active business calendar is selected, When the user sets staffing counts by role and shift with time windows and effective start/end dates, Then the system validates counts are integers between 0 and 10000, windows do not overlap for the same role, and effective dates do not precede today. Given valid inputs, When the user clicks Preview, Then the preview shows hourly coverage by role, total FTE, and utilization baseline deltas without running a full simulation. Given overlapping windows or invalid ranges, When the user attempts to save, Then inline errors highlight the conflicting fields with messages and the Save action is disabled.
Model Arrival Volumes with Seasonality and Surge Events
Given a baseline arrival profile exists (imported or manual), When the user applies weekly and monthly seasonality factors and adds a surge event with start/end and multiplier, Then the preview chart updates to show hourly/daily arrivals and displays total volume change as count and percent. Given negative volumes, empty dates, or non-numeric multipliers, When the user blurs the field, Then validation errors appear and the invalid values are not accepted. Given a surge overlaps another surge, When saving, Then the system requires the user to resolve overlaps or merges them according to a selected rule.
Define SLA Targets per Workflow Step
Given workflow steps are loaded, When the user sets SLA targets per step with units (minutes/hours/days) and selects whether SLAs follow the business calendar, Then the system enforces min/max (1 minute to 30 days) and stores targets per step. Given a target is stricter than baseline, When Preview is clicked, Then the UI flags stricter targets with warning color and shows expected breach risk range before simulation. Given a step has zero assigned capacity, When a non-zero SLA target is set, Then a conflict warning identifies the step and blocks Save until capacity is configured or the SLA is relaxed.
Edit Routing Rules and Validate Conflicts
Given existing routing rules are displayed, When the user edits conditions (team, skill, priority) and distribution percentages, Then percentages must sum to 100% per rule and each target team must exist and be active. Given a routing cycle would be created or an orphan path detected, When validating, Then the system blocks Save and lists the problematic rules with links to jump to each. Given rule changes increase expected load on a team beyond configured role capacity by more than 10%, When Preview is clicked, Then a risk banner appears summarizing impacted teams and percentage overage.
Persist, Clone, Version, and Tag Scenarios
Given a scenario name, tags, and notes are provided, When Save is clicked, Then the scenario is persisted with a unique name within the organization, an immutable version ID, creator, created/updated timestamps, and is retrievable via search by name or tag. Given a user selects Clone on an existing scenario, When confirming, Then a new scenario is created with a new version ID, a reference to the source version, and all parameters duplicated; the change log shows "Cloned from <ID>". Given multiple versions exist, When viewing history, Then earlier versions are read-only and can be restored to create a new version without altering the original.
Permissions, Sharing, and Scenario Comparison
Given org-level permissions, When a user without edit rights opens a scenario, Then all input controls are read-only and Save/Clone actions are hidden while Compare is available only if the user has compare permission. Given a user selects two or three scenarios they can access, When Compare is clicked, Then a side-by-side diff view is shown highlighting differences across staffing, arrivals, SLAs, and routing rules, with summary deltas and an option to export the diff to CSV; the view loads within 2 seconds for up to 3 scenarios. Given an owner shares or revokes access to a scenario for a team or user, When the change is saved, Then the ACL updates immediately and an audit log entry records actor, target, action, and timestamp.
Queueing Simulation Engine
"As a capacity planner, I want an accurate simulation of workflow queues so that I can forecast breach risk and cycle times under different assumptions."
Description

Implements a scalable simulation core that models ClaimFlow’s multi-step workflows as networks of queues with parallel servers, priorities, and routing probabilities. Ingests time‑varying arrivals and empirical handle‑time distributions to compute queue times, utilization, backlog, and SLA breach probabilities per step. Supports discrete‑event simulation with configurable run horizons, warm‑up periods, and replications to produce confidence bands. Handles business hours, pauses, escalations, and rework loops. Exposes a service API that the Scenario Builder invokes and returns step‑level metrics and risk summaries.

Acceptance Criteria
Multi-Step Network With Parallel Servers and Priorities
Given a workflow with three steps, routing probabilities {S1→S2:0.70, S1→S3:0.30}, Step S2 staffed with 3 parallel servers, and two priority classes (High, Normal) When simulating 100,000 arrivals with a fixed random seed and non-preemptive priority dispatching Then observed routing frequencies per edge are within ±1.0 percentage point of configured probabilities And average queue wait for High is strictly less than for Normal at every step where both appear And no Normal item begins service while any High item is waiting at the same step And reported server utilization per step is within ±0.5 percentage points of the ratio (measured busy time ÷ staffed time) And reported backlog at run end equals the count of items waiting across all steps at that timestamp And step metrics include mean, P50, P90, P95, P99 for queue wait and handle time for each priority class
Time-Varying Arrivals and Empirical Handle-Time Sampling
Given a 24-hour piecewise arrival schedule with 15-minute intervals specifying λ(t) and empirical handle-time samples per step When running 50 replications with fixed base seed and distinct sub-seeds Then mean arrivals per interval across replications are within ±3% of expected counts for at least 95% of intervals And per-step sampled handle-time mean and P90 across replications are within ±2% of the input empirical statistics And sampled handle times respect configured min/max bounds and any specified point masses And time-varying arrivals align to the scenario time zone with correct daylight saving transitions
Horizon, Warm-Up, Replications, and Confidence Bands
Given a warm-up period W and total run horizon H where H > W When computing metrics Then observations prior to W are excluded from all reported statistics and backlog snapshots And with N ≥ 10 replications, reported 95% confidence intervals per metric use Student’s t across replications and satisfy Lower ≤ Mean ≤ Upper And re-running with the same base seed reproduces identical per-replication results and aggregated intervals And with N < 2 and confidence intervals requested, the API returns a 400 error indicating insufficient replications (unless CI=false) And when warm-up has zero arrivals, the run completes without error and excludes that period from metrics
Business Hours, Pauses, Escalations, and Rework Loops
Given a step configured with business hours 09:00–17:00 local time, Mon–Fri When simulating Then no service time accrues outside business hours and queued items resume service at the next open period And if an item is paused mid-queue or mid-service, its wait/service clocks stop and resume accurately when unpaused And if an escalation rule triggers at T business minutes of wait, the item’s priority increases and future dispatching respects the new priority without preempting in-flight service And with a rework loop probability p from Step B back to Step A, observed loop-back frequency over ≥100,000 completions is within ±1.0 percentage point of p And the engine prevents unbounded cycling by enforcing a configurable max-loop safeguard and emits a warning when reached
Service API Contract and Step-Level Metrics
Given a valid scenario payload (workflow, staffing, calendars, arrivals, service distributions, SLA thresholds, replication config) When POST /simulate is called Then the response is 200 with a JSON body conforming to the published schema version And the body includes, per step and priority class: mean, P50, P90, P95, P99 queue wait; mean handle time; utilization; backlog at horizon end; SLA breach probability; and 95% confidence intervals where requested And the body includes a run_id, input echo, and timing metadata (wall time, events processed) And invalid payloads return 400 with machine-readable error codes and field-level messages; unknown fields are rejected with errors And requests are idempotent when an Idempotency-Key header is supplied
Performance and Scalability Under What-If Scenarios
Given a reference environment defined in the test harness (e.g., 16 vCPU, 32 GB RAM) When simulating a typical scenario (10 steps, 100,000 arrivals, 10 replications, modest routing/priorities) Then synchronous API P95 latency is ≤ 5 seconds and peak RSS memory ≤ 2 GB When simulating a large scenario (20 steps, 1,000,000 arrivals, 30 replications) Then the run completes within 10 minutes wall time, peak RSS memory ≤ 8 GB, and no GC-induced stalls exceed 2 seconds And throughput is ≥ 5 million processed events per minute sustained over the run And metrics are streamed or buffered such that response size ≤ 10 MB for typical scenarios
SLA Breach Probability and Risk Summary Accuracy
Given per-step SLA thresholds defined on queue wait (business time or calendar time as configured) When computing breach probabilities across N ≥ 30 replications Then reported breach probability per step equals the simulated exceedance fraction within ±1.0 percentage point And reported 95% confidence intervals for breach probability reflect replication variance and bound to [0,1] And the risk summary lists steps sorted by highest breach probability and the top 3 match the computed ordering And steps with zero observed breaches still report a valid upper confidence bound > 0 when N is finite
Baseline & Calibration Data Pipeline
"As a data analyst, I want calibrated baselines from historical operations so that simulation outputs reflect our real patterns and constraints."
Description

Builds pipelines to ingest historical arrivals, handle times, SLA outcomes, and routing paths from ClaimFlow to establish baselines by line of business, claim type, and step. Cleans and aggregates data, fits distributions, detects seasonality, and estimates time‑of‑day/day‑of‑week patterns. Provides backtesting to compare simulated vs. observed metrics and surface calibration gaps. Enables manual overrides and exclusions (e.g., outliers, holidays) with audit trails. Stores baselines versioned so scenarios can reference specific snapshots.

Acceptance Criteria
Complete Historical Data Ingestion from ClaimFlow
Given a 12-month historical export of arrivals, handle_times, SLA_outcomes, and routing_paths from ClaimFlow When the initial backfill pipeline runs end-to-end Then the ingested record count per table and per service-day matches the source within ±0.5%, or discrepancies are listed with row-level error reasons And at least 99.0% of source records are successfully ingested; failed records are retried up to 3 times and quarantined with reason codes after final retry And schema and required fields (claim_id, step_id, timestamps, LOB, claim_type) pass validation; rows failing validation are quarantined and excluded from aggregates And ingestion is idempotent: re-running the same job on the same input does not change target row counts or hashes of stored datasets And duplicate source rows (by claim_id+step_id+timestamp) are detected and de-duplicated deterministically with a logged rule
Data Cleaning and Aggregation by LOB/Claim Type/Step
Given cleaned fact tables When the aggregation job executes for each (LOB, claim_type, step) cell with N ≥ 50 observations Then it computes and persists: arrivals per hour/day, mean/median/p90/p95 handle_time, SLA success rate, and routing path frequencies with confidence intervals And null/invalid timestamps are dropped; negative or zero handle_times are excluded and counted in a data_quality table with counts by reason And extreme outliers are excluded using a configurable rule (default: outside [Q1−3*IQR, Q3+3*IQR]) and logged with counts; exclusions are reflected in metrics And aggregates include data_window_start/end, record_counts_before/after_cleaning, and exclusion_rules_applied metadata And a sample dataset unit test reproduces known expected aggregates within ±0.1% for counts and ±1% for means
Distribution Fitting for Handle Times and Interarrival
Given aggregated and cleaned observations per (LOB, claim_type, step) When fitting candidate distributions {lognormal, gamma, Weibull, exponential} for handle_times and interarrival times Then the best model is selected by minimum AIC (tie-breaker: BIC) and parameters are stored with fit diagnostics And a KS test p-value ≥ 0.05 or Anderson-Darling within acceptable bounds indicates acceptable fit; otherwise the system falls back to an empirical distribution with winsorized tails at 1st/99th percentiles And for cells with N < 200, hierarchical pooling to parent grouping (e.g., by LOB+step) is applied and documented And distribution parameters, sample size, fit_method, goodness_of_fit metrics, and fallback_reason (if any) are persisted per cell
Seasonality and Time-of-Day/Day-of-Week Patterns
Given arrivals time series at 15-minute granularity When seasonality detection runs with STL decomposition and Fourier terms Then normalized multiplicative factors are produced for hour-of-day (24) and day-of-week (7), each with mean factor ≈ 1.0 (±0.01) And model quality metrics (R² or variance explained) ≥ 0.60; if below, factors are flagged low-signal and default to flat (all 1.0) And a holiday/exclusion calendar is applied so excluded days do not influence factor estimation And daylight saving transitions are handled without duplicate or missing hour buckets And factors, quality flags, data_window, and exclusion_calendar_version are persisted
Backtesting Against Observed Metrics
Given a holdout window of the most recent 8 weeks excluded from fitting When the simulator runs using the baseline parameters for the holdout window Then per (LOB, claim_type, step) cell, SLA breach rate error meets thresholds: if observed breach ≥ 5%, MAPE ≤ 10%; else absolute error ≤ 2 percentage points And queue time percentiles (P50, P90) absolute error ≤ 10% or ≤ 2 minutes, whichever is larger And at least 90% of evaluated cells meet all thresholds; noncompliant cells are listed with suspected drivers (fit quality, data sparsity, seasonality flag) And a backtest report with pass/fail per metric, thresholds, and calibration_gap items is stored and linked to the baseline version
Manual Overrides, Exclusions, and Audit Trail
Given a user with Calibration Admin permissions When the user applies overrides (e.g., set handle_time distribution to lognormal with parameters) or exclusions (date ranges, claim_ids, holidays) Then the next recomputation reflects the changes in aggregates, fits, and backtests, and excluded records are not counted And every change creates an immutable audit log entry with user_id, timestamp, scope, before_value, after_value, reason, and affected baseline_version And the user can revert a prior change; reversion creates a new audit entry and recomputation restores prior metrics within the same tolerances And overrides take precedence over automated fits and are clearly labeled in outputs and reports
Versioned Baseline Snapshots and Scenario Referencing
Given a new baseline is published after computation When it is stored in the baseline registry Then it receives an immutable version_id (timestamp+content_hash) and metadata (created_by, created_at, data_window, overrides_digest) And previous versions remain readable; reading the same version_id yields identical content_hash across environments And SLA Simulator scenarios can reference a specific version_id and will not change behavior unless re-pointed explicitly And publishing a new baseline does not modify existing version_ids and updates the default pointer only if approved by Calibration Admin
SLA Policy and Routing Modeler
"As a workflow owner, I want to model changes to SLAs and routing rules so that I can see how policy updates affect breach rates and queue behavior before rollout."
Description

Translates ClaimFlow’s configurable SLAs, working calendars, priorities, and routing rules into simulator parameters. Supports scenario-specific overrides such as stricter SLAs, rule changes, and custom escalation paths. Validates rules for completeness and conflicts, and visualizes the resulting step network. Maintains versioned policy bundles tied to effective dates to compare current vs. proposed policies within scenarios.

Acceptance Criteria
Baseline Policy Translation to Simulator Parameters
- Given a published ClaimFlow policy bundle containing steps, SLAs, working calendars, priorities, routing rules, and escalation paths - When the user loads the bundle into the SLA Simulator with no overrides - Then 100% of entities (steps, SLAs, calendars, priorities, routing rules, escalations) are present in the generated simulator parameter set with identical identifiers and values - And compilation completes in <= 5 seconds for bundles up to 200 steps and 1,000 rules - And the generated parameter set hash remains identical across three consecutive loads of the same bundle - And the compile log reports 0 errors and 0 warnings - And unmapped entity count equals 0
Scenario-Specific Overrides Without Mutating Baseline
- Given a baseline policy bundle loaded into the simulator - When the user applies scenario overrides (e.g., tighten all SLAs by 20%, modify routing condition for Rule R42, add escalation from Step S3 to Queue Q1 for Priority High) - Then the baseline bundle remains unchanged and read-only - And the scenario parameter set reflects only the specified overrides while preserving all other baseline values - And the system displays a diff showing exactly the overridden items and count of changes - And overrides can be enabled/disabled per item, with state persisted to the scenario - And removing all overrides restores an identical parameter set hash to the baseline
Rule Completeness and Conflict Validation
- Given any policy bundle or scenario - When the user runs Validate Rules - Then the system detects and reports with severity levels: missing entry/exit paths, dead-end steps, cycles without termination, overlapping routing conditions, unreachable steps, missing calendars, duplicate SLA definitions, and conflicting priority assignments - And each finding includes the impacted step/rule IDs and a minimal reproduction path - And validation blocks compilation on Error severity and allows compilation on Warning severity - And validation completes in <= 3 seconds for bundles up to 200 steps and 1,000 rules
Step Network Visualization
- Given a successfully compiled parameter set - When the user opens Network View - Then the system renders a directed graph of steps and routing edges with visual encodings for SLA targets, calendars, priorities, and escalation paths - And users can pan, zoom, search by ID/name, and filter by queue, priority, or tag - And clicking a node or edge reveals its properties and source rule references - And the layout renders within <= 3 seconds for graphs up to 200 nodes and 1,000 edges - And users can export the view as SVG and PNG
Versioned Policy Bundles with Effective Dates and Comparison
- Given multiple policy bundle versions with effective date ranges - When the user selects a date or chooses Current - Then the system resolves the active bundle whose effective range covers the date and prevents overlapping effective ranges at save time - And published versions are immutable while drafts can be edited - And scenarios can pin to a specific version regardless of Current - And Compare Versions displays a diff of steps, SLAs, calendars, routing rules, and escalations with added/removed/changed counts
Export/Import Contract and Schema Validation
- Given a compiled parameter set or policy bundle - When the user exports to JSON - Then the output conforms to the documented schema version with a valid $schema and version field - And importing the same JSON reproduces an identical parameter set hash and passes validation with 0 errors - And the system rejects payloads that violate schema with actionable error messages including JSON pointers to offending fields
Working Calendars and Time Zone Fidelity
- Given steps mapped to working calendars with distinct business hours, time zones, and holidays - When the modeler computes SLA due times and routing availability within a scenario - Then SLA targets and queue availability reflect calendar-specific working time (pausing outside business hours) and correct time zone offsets - And cross-time-zone escalations compute elapsed working time correctly end-to-end - And changing the scenario date to a holiday adjusts due times accordingly - And unit tests assert parity with ClaimFlow runtime calculations for a suite of at least 50 representative cases
Staffing and Shift Optimizer
"As a workforce manager, I want recommendations for headcount and shift schedules so that I can staff efficiently while meeting SLAs under various demand scenarios."
Description

Provides optimization that recommends minimum headcount and shift allocations by role and time block to meet SLA targets at desired confidence levels. Accepts constraints such as budget caps, maximum utilization, skill coverage, and hiring lead times. Iterates with the simulation engine to evaluate candidate schedules and outputs recommended rosters, marginal impact of additional hires, and sensitivity to demand surges. Generates actionable staffing plans aligned to ClaimFlow team structures.

Acceptance Criteria
Optimize to meet SLA targets within budget and utilization constraints
Given a 6-week arrival forecast and an SLA of 4 hours at 95% with 90% confidence, a budget cap of $120,000/month, and max utilization of 85% per role When the optimizer is executed Then it returns a recommended roster per role and time block that meets the SLA at >=90% confidence And the total staffing cost <= $120,000/month And average utilization per role <= 85% And all required shifts obey configured min/max shift length and rest-period rules
Skill coverage and routing compatibility by time block
Given a role-skill matrix and ClaimFlow queue routing rules When a roster is generated in 30-minute time blocks Then each task type has at least one skill-qualified assignee per time block And cross-trained staff are only counted toward one skill at a time per block And no task queue is left unstaffed during its operating hours And role and queue names match existing ClaimFlow team structures
Simulation-optimization loop convergence and best-feasible selection
Given the optimizer evaluates candidates via the simulation engine with a max wall-clock of 30 minutes and a convergence threshold of <0.5% improvement over the last 10 iterations When the run is started Then the search terminates on the first of: time limit reached or convergence achieved And the returned roster is the lowest-cost schedule that satisfies SLA and constraints among evaluated candidates And the run report includes iterations run, best objective value, feasibility status, and SLA confidence estimate
Hiring lead times and start-date feasibility in recommendations
Given hiring lead times of 21 days for Adjusters and 35 days for Specialists and a target start date of the first of next month When additional headcount is recommended Then new FTE start dates are no earlier than their respective lead times allow And interim coverage uses overtime or temporary staff only if explicitly enabled and within budget and utilization caps And unmet coverage is flagged when constraints prohibit interim measures
Sensitivity to demand surges and marginal value of additional hires
Given a baseline demand forecast and a +20% surge scenario When sensitivity analysis is requested Then outputs include breach rate by step, average and p95 queue times, and risk bands for both scenarios And a marginal value curve is produced showing SLA compliance improvement per additional hire by role up to +10 FTEs And the first additional hire not required to meet the SLA is identified and annotated
Actionable roster export and reproducibility
Given a recommended roster is available When the user exports results Then a CSV and JSON are generated containing role, placeholder/agent identifier, day, start time, end time, skill tags, and cost fields And an audit report is included listing binding constraints, assumptions, and KPIs (SLA hit rate, utilization, cost) And rerunning the optimizer with identical inputs and random seed produces identical outputs
Results Dashboard and Export
"As an operations leader, I want clear visual results and exports so that I can compare scenarios and share decisions with stakeholders."
Description

Delivers interactive visualizations for each scenario: breach probability by step, queue time distributions, utilization, backlog heatmaps, and required headcount by role. Enables side‑by‑side scenario comparison and highlights deltas versus baseline. Supports exporting results to CSV/PDF and sharing read‑only links within the organization. Adds annotations, run metadata, and an audit log to support decision traceability.

Acceptance Criteria
Breach Probability by Step Chart
Given a completed simulator run exists, when the user opens the Results Dashboard for that run, then a chart displays breach probability (%) for each workflow step with visible step labels. Given the dashboard requests breach probabilities from the API, when the chart renders, then each displayed value matches the API value for the same step within ±0.1 percentage points. Given the user applies a step, role, or SLA filter, when the filter is applied, then the chart updates within 2 seconds and reflects only the filtered data. Given no data exists for a step after filtering, when the chart renders, then the step is hidden and a "No data" badge is shown in the legend. Given the user hovers a bar/point, when the tooltip appears, then it shows step name and breach probability formatted as 0.0%. Given the user resets filters, when reset is pressed, then the chart returns to the full run view within 2 seconds.
Queue Time Distributions and Utilization
Given a completed simulator run exists, when the user views Queue Time Distributions, then per-step histograms render with P50, P90, and P95 markers and units labeled in minutes. Given percentile and histogram values are returned by the API, when the visualization loads, then displayed P50/P90/P95 and histogram bin counts equal API-provided values to within rounding rules (nearest 0.1 minute). Given the user selects a time window or step subset, when applied, then the distributions update within 2 seconds and match the filtered API data. Given the user opens Utilization, when the view loads, then utilization by role is displayed as percentages with roles sorted descending by utilization. Given utilization thresholds are configured (e.g., 85% warning), when a role exceeds the threshold, then its utilization indicator is colored warning and an accessible label indicates "Above threshold". Given the data source updates (new run selected), when the user switches runs, then both distributions and utilization refresh within 2 seconds and reflect the selected run.
Backlog Heatmap and Required Headcount by Role
Given a completed simulator run exists, when the user opens Backlog, then a heatmap displays backlog counts by step over time with a visible color scale legend and UTC timestamps. Given backlog timeseries values are returned by the API, when the heatmap renders, then cell values equal API values for the corresponding time buckets. Given the user opens Required Headcount, when the view loads, then a table shows required FTE per role to meet the configured SLA targets, with values rounded up to the nearest whole FTE. Given the user changes the SLA target or arrival volume assumptions, when Apply is pressed, then the required headcount recomputes and updates within 3 seconds and reflects the new assumptions. Given a role has zero demand, when headcount is displayed, then that role shows 0 FTE and is still listed. Given the user downloads the headcount data as CSV from this view, when the file is generated, then it contains role, SLA target, assumptions snapshot, and required FTE columns and matches on-screen values.
Side‑by‑Side Scenario Comparison and Delta vs Baseline
Given at least two completed runs exist, when the user selects a baseline and up to two comparison scenarios, then the dashboard displays their key metrics side‑by‑side (breach probability by step, P50/P90 queue times, utilization by role, backlog peak, required headcount by role). Given baseline and comparison are selected, when deltas are shown, then both absolute and percentage deltas versus baseline are displayed and can be toggled by the user. Given metric improvement rules (lower is better for breach probability, queue times, backlog, and required headcount), when deltas are displayed, then improvements are indicated with a positive visual cue and regressions with a negative cue with accessible labels. Given the user sorts by delta magnitude, when a sort is chosen, then rows reorder within 1 second according to the selected delta metric. Given the API returns metric values for the selected runs, when the comparison view renders, then all values and deltas equal the computed values from the API to within defined rounding (percentages to 0.1 pp, times to 0.1 min).
Export Results to CSV and PDF
Given a completed run is open, when the user clicks Export CSV, then a UTF‑8 CSV is generated within 10 seconds containing headers and rows for: breach probability by step, queue time percentiles by step, utilization by role, backlog timeseries, and required headcount by role. Given CSV export completes, when the file is opened, then timestamps are ISO‑8601 UTC, decimals use a dot separator, and all values match the dashboard values for the same run. Given a completed run or comparison view is open, when the user clicks Export PDF, then a PDF is generated within 20 seconds that includes summary KPIs, key charts, legends, delta highlights (if comparison), annotations, and run metadata on a cover page. Given an export is initiated, when the file is saved, then the filename follows the pattern: <organization>_SLA‑Simulator_<scenario‑name>_<run‑id>_<YYYYMMDDThhmmssZ>.(csv|pdf). Given the export job fails, when the error occurs, then the user sees a descriptive error message and no partial file is downloaded.
Share Read‑Only Link Within Organization
Given a completed run exists, when the owner generates a share link, then a URL is created with an opaque token and default permissions set to read‑only. Given a share link exists, when an authenticated user from the same organization with Viewer or higher role opens it, then the dashboard loads the shared run in read‑only mode with editing controls disabled. Given a share link exists, when an unauthenticated user or a user from a different organization opens it, then access is denied (401 if unauthenticated, 403 if cross‑org) and the event is logged. Given the owner sets an expiration for the link, when the expiration time passes, then subsequent access returns 410 Gone and the link no longer resolves within 1 minute of expiry. Given the owner revokes the link, when revoke is confirmed, then the link stops working within 1 minute and all future access attempts are denied and logged.
Annotations, Run Metadata, and Audit Log
Given a completed run is open, when the user adds an annotation (title and body up to 1000 characters), then it is saved with the user, timestamp (UTC), scenario, and run IDs and appears on the dashboard within 1 second. Given annotations exist, when the user exports CSV or PDF, then all annotations for the run are included with author, timestamp, and text. Given run metadata is requested, when the Metadata panel is opened, then model version, input parameters (SLA targets, staffing assumptions, routing rules version/hash), random seed, data snapshot ID, and run start/end timestamps are displayed and match the stored values. Given an auditable action occurs (view, export, share create/revoke, annotation add/edit/delete), when the action completes, then an audit log entry is created within 5 seconds with actor, action, target, timestamp (UTC), and outcome and entries are immutable. Given an admin opens the Audit Log, when filters are applied by date range or user, then results update within 2 seconds and can be exported to CSV with values matching the on‑screen log.

Live Mask

Always-on, real-time masking of PII/PHI in screens, chat, and transcripts. Sensitive tokens auto-hide by default, with just‑in‑time reveal gated by role, consent, and purpose. Every reveal is time‑bound, reason‑coded, and audit‑logged, reducing accidental exposure while keeping adjusters fast and compliant.

Requirements

Real-time PII/PHI Detection & Masking
"As a claims adjuster, I want PII/PHI to be automatically masked in real time across all views so that I can work quickly without risking accidental exposure."
Description

Implements an always-on detection pipeline that scans all rendered UI elements, chat streams, transcripts, and attachments for sensitive tokens (e.g., SSN, DOB, driver’s license, bank/card numbers, policy/claim numbers, addresses, emails, phone numbers, medical terms) and masks them before display or transmission. Uses a hybrid approach of configurable patterns, dictionaries, NLP entity recognition, and OCR for images/PDFs to ensure high recall and precision. Guarantees sub-50ms masking latency per token for interactive views, idempotent masking on re-renders, and language/locale support. Applies redaction consistently to on-screen text, search results, copy/paste, exports, downloads, and API responses to prevent data leakage to logs, caches, or third-party tools. Provides confidence thresholds, false-positive/negative handling workflows, and telemetry to continuously tune models without exposing raw PII/PHI.

Acceptance Criteria
Interactive UI Masking Latency
Given an interactive view containing supported PII/PHI tokens, When the view renders or updates, Then per-token masking latency is <= 50ms at p99 end-to-end in the reference environment, And no unmasked PII/PHI appears in any displayed frame or transition.
Multimodal Detection Accuracy
Given a labeled validation set spanning text, chat, transcripts, and images/PDFs with SSN, DOB, driver’s license, bank/card, policy/claim, addresses, emails, phone numbers, and medical terms, When processed by the detection pipeline, Then entity-level recall is >= 0.98 overall and >= 0.95 per entity type, And precision is >= 0.97 overall and >= 0.94 per entity type, And OCR-based detections achieve entity-level recall >= 0.95 on images/PDFs.
Idempotent Masking on Re-renders and Reprocessing
Given content already masked by the pipeline, When the same content is re-rendered, re-indexed, copied, or reprocessed, Then the output is identical to the prior masked output (no additional masking artifacts, no unmasking), And applying the masker multiple times yields the same result as a single pass.
Cross-Surface Redaction Consistency (UI, Search, Copy/Paste, Export)
Given masked content visible in the UI, When a user searches, copies to clipboard, downloads, or exports the same content, Then search indexes and results contain only masked tokens, And clipboard contents and exported/downloaded artifacts contain only masked tokens, And no raw PII/PHI appears in previews, tooltips, or secondary panes.
API and Observability Egress Scrubbing
Given API responses, webhooks, event streams, logs, metrics, traces, and error reports that may include PII/PHI, When emitted or stored, Then all PII/PHI tokens are masked per policy before transmission or persistence, And no raw PII/PHI is present in application logs, caches, data exports, or third-party integrations, And contract tests validate masking for each endpoint and sensitive field.
Language and Locale Aware Detection
Given content in English (en-US) and Spanish (es-ES/es-MX) with locale-specific formats (dates, phone numbers, addresses, IDs), When processed, Then locale-aware patterns/NLP are applied correctly, And per-locale precision and recall are each >= 0.95, And admins can enable additional locales via configuration without code changes.
Confidence Thresholds, Review Workflow, and PII-safe Telemetry
Given detections with confidence scores, When a score is below the configured threshold, Then the token is masked and flagged for review without revealing raw PII/PHI, And reviewers can mark false positives/negatives without exposing raw values, And telemetry records counts, entity types, confidence distributions, outcomes, model version, and latency without storing raw PII/PHI (only masked values or non-reversible hashes).
Just-in-time Reveal with Role, Purpose, and Timebox
"As a compliance-conscious adjuster, I want to reveal specific sensitive data only when I have the right role and purpose so that access is controlled, time-limited, and auditable."
Description

Provides a policy-driven reveal flow that requires the requester to have an authorized role, select an approved purpose, and (when required) present valid consent before any sensitive token is partially or fully unmasked. Enforces principle of least privilege with granular scopes (field-level, token-type, record, time-bound window), reason codes, and step-up authentication for elevated reveals. Automatically re-masks after the timebox expires, prevents bulk or programmatic mass unmasking, and displays contextual indicators (e.g., watermarked ‘Unmasked’ state). Integrates with the authorization service, consent registry, and audit log, capturing who revealed what, why, for how long, and under which policy version.

Acceptance Criteria
Role-Gated Reveal with Approved Purpose
Given a user is authenticated and assigned the Claims Adjuster role And the authorization service maps this role to scope "Reveal:SSN.last4" on the claim record And the user selects an approved purpose "Identity Verification" When the user requests to reveal the SSN last4 token on claim CF-123 Then the system permits the reveal And the request is denied with 403 if the role lacks the mapped scope or the selected purpose is not on the approved list And the selected purpose is stored as a standardized reason code with the request
Consent Validation for PHI Reveal
Given the token type is PHI (e.g., diagnosis note) for claim CF-123 And a time-valid, unrevoked consent exists in the consent registry covering token type PHI and this claim When the user selects approved purpose "Medical Review" and requests the reveal Then the system reveals the token And if no matching consent exists or it is expired/revoked/insufficient in scope, the system blocks the reveal with error "Consent Required" and no data is exposed And the consent reference ID is bound to the reveal session and recorded
Timeboxed Unmask with Auto Re-Mask and UI Indicator
Given a reveal is approved for a token with a configured timebox of 5 minutes When the token is unmasked in the UI Then the UI displays a visible Unmasked watermark and a countdown timer And upon expiry of 5 minutes or manual re-mask, the token is automatically re-masked across all views and sessions And refreshing the page, navigating within the app, or reloading the component does not reset or extend the timebox And any screenshots/export attempts during the unmask period include the Unmasked watermark
Step-Up Authentication for Elevated Scope
Given the user requests elevated scope "Reveal:SSN.full" or "Reveal:BankAccount.full" And the user's last successful step-up MFA occurred more than 10 minutes ago When the user attempts the reveal Then the system requires step-up authentication via the configured MFA provider And upon successful step-up, the reveal proceeds; upon failure or cancellation, the reveal is denied with no data exposure And the step-up requirement and outcome are recorded with the reveal event
Prevent Bulk or Programmatic Mass Unmasking
Given default anti-bulk configuration is per-call token limit=3 and per-user-per-claim rolling window limit=10 tokens per 15 minutes When a client attempts to reveal more than 3 tokens in a single request Then the system rejects the request with error "Bulk Reveal Not Allowed" And when cumulative reveals exceed 10 tokens for the same user and claim within 15 minutes, subsequent reveal requests are throttled and blocked until the window resets And API endpoints do not support wildcard or query-based reveals; each reveal must target a specific token instance And blocked attempts are logged with reason "Anti-Bulk Policy"
Comprehensive Audit Logging with Policy Version
Given any reveal request is evaluated (permit or deny) When the decision is made Then an immutable audit record is written including user ID, role, claim ID, field path, token identifier, token type, requested scope, approved scope, purpose (reason code), consent reference ID (if applicable), step-up result, timebox duration, timestamps (requested, granted, expired), policy version, and request origin (UI/API) And the audit record is queryable within 5 seconds of the event And the audit trail includes a distinct event when the token is re-masked (timebox expiry or manual) with the exact expiration timestamp
Granular Scope Enforcement and Partial Reveal
Given the policy grants scope "Reveal:Phone.partial" (last4 only) on claim CF-123 When the user requests a full phone number reveal Then the system denies the full reveal and only exposes the last 4 digits while keeping the remainder masked And attempts to reveal fields outside the granted field(s) or outside the current claim record return 403 and leave data masked And attempts to combine multiple partial scopes to infer a full value are blocked (no cumulative reveal beyond granted scope)
Consent Capture, Validation, and Expiry
"As a claims manager, I want consent to be captured and validated prior to unmasking sensitive data so that our team complies with privacy laws and carrier policies."
Description

Captures claimant/insured consent tied to a specific purpose and scope, supporting SMS/email e-sign, web forms, and voice consent with transcript anchoring. Stores consent artifacts with versioned legal text, locale, retention period, and revocation status. Validates consent at reveal time, ensuring it is present, unexpired, and appropriate for the requested purpose and token type. Provides APIs and UI components for requesting, displaying, and renewing consent; handles multi-party scenarios (e.g., claimant and witness) and minors/representatives. Maintains tamper-evident records linked to claim IDs and integrates with policy rules and audit logs for full traceability.

Acceptance Criteria
SMS E‑Sign Consent Capture for Claimant PII Reveal
Given a claim has masked PII and the claimant’s phone number is verified When an adjuster triggers an SMS consent request specifying purpose "PII reveal for claim verification" and scope "phone number,address" Then the system sends a one-time unique link via SMS and records the request with claimId, partyId, purpose, scope, legalTextVersion, locale, requesterUserId, timestamp, and requestId And When the claimant opens the link and signs Then the system stores the signed artifact and metadata, sets consent.status="Active", sets expiry per retentionPolicy, and associates it to the claimant’s partyId And Then the system records IP, userAgent, confirmation timestamp, and computes a SHA-256 hash of the artifact for tamper evidence And When the claimant declines or the link expires Then consent.status is set to "Revoked" or "Expired" and reveals depending on this consent are blocked And Then no more than 5 consent requests may be sent per party per hour; excess attempts are rejected with HTTP 429 and no artifact is created
Voice Consent with Transcript Anchoring and Audio Hash
Given an active recorded call with a transcript generated and aligned with audio When the adjuster reads the approved legal text and the claimant verbally agrees Then the system anchors consent to a transcript span with start/end timestamps, speakerId, and text snippet, and stores audioUri and SHA-256 hash And Then the system records legalTextVersion, locale, purpose, scope, claimId, partyId, callId, adjusterId, reasonCode, and consentId And When the call ends Then consent.status becomes "Active" only if diarizationConfidence >= 0.85 and affirmation keyword match passes; otherwise status="Review Needed" and reveals are blocked until approved And Then an audit event is written including decision, metrics, and hashes
Consent Validation at PII/PHI Reveal Time
Given a user with role Adjuster attempts to reveal a masked token of type "SSN" When the system evaluates consent, policy rules, and user permissions Then reveal is permitted only if there exists an Active consent for the token owner where purpose allows "SSN reveal", scope includes "SSN", consent is unexpired at server time, and the user role is allowed by policy And Then the user must enter a reason code and justification before reveal; the reveal window is time-bound to 5 minutes and auto-re-masks after expiration And When any condition fails (missing, expired, scope mismatch, role disallowed) Then the system blocks reveal, displays the unmet condition, and offers to request/renew the required consent via UI/API And Then all outcomes are audit-logged with consentId (if any), decision, ruleVersion, requesterUserId, timestamp, and tokenType
Consent Expiry, Renewal, and Versioned Legal Text
Given an Active consent has fewer than 7 days remaining When a user initiates a renewal via email or SMS for the same claimId, partyId, purpose, and scope Then the system sends a renewal request referencing prior consentId and the latest legalTextVersion for the party’s locale And When the recipient completes the renewal Then a new consent artifact is created with a new consentId, expiry set per current retentionPolicy, previous artifact remains immutable, and previousConsentId is recorded And When legal text version has changed since the original Then the renewal uses the updated version and both versions are stored for traceability And When renewal is not completed by expiry Then the original consent transitions to "Expired" and any subsequent reveal attempts are blocked with a renewal prompt
Multi‑Party and Minor/Representative Consent Handling
Given a claim includes a claimant, a witness, and a minor passenger with a guardian When the system evaluates reveals for each party’s PII Then separate Active consents are required per party; the minor’s consent must be provided by a representative with relationshipType="Guardian" linked to the minor’s partyId And Then revealing witness contact info is blocked unless witness consent exists, regardless of claimant consent status And When representative consent is submitted Then the system validates representative age >= jurisdictionMinimum and relationshipType is allowed by policy; otherwise mark consent as "Invalid Representative" and block reveals And Then UI/API surfaces per‑party consent statuses and required next actions for any missing consents
Tamper‑Evident Storage and Chain‑of‑Custody Audit
Given any consent artifact is created, renewed, or revoked When the artifact and metadata are persisted Then the system computes and stores a content hash, writes an immutable audit event with the hash, links the artifact to claimId and partyId, and records who performed the action and why And Then any subsequent read validates the stored hash; on mismatch the system flags the consent as "Suspect", raises an integrity alert, and blocks reveals tied to that consent And When a consent is revoked Then revocation reason, revokerId, and timestamp are recorded and reveals depending on that consent are immediately blocked And Then audit export APIs produce a complete ordered chain‑of‑custody with verifiable signatures
APIs and UI Components for Consent Request and Display
Given a client calls POST /consents with partyId, claimId, channels=[sms,email], purpose, scope, and locale When the request is valid Then the API returns 201 with consentId, requestStatus per channel, legalTextVersion, expiry, and enforces a rate limit of 5 requests per party per hour And When GET /consents?claimId={id} is called Then the API returns a paginated list with status per party, latest legalTextVersion, expiry, and revocation flags And Then UI components display a consent banner showing purpose, scope, status, and expiry countdown with actions [Request, Renew, Revoke], and meet WCAG 2.1 AA accessibility And When API input is invalid (e.g., unsupported locale or unknown scope) Then the API returns 4xx with machine‑readable error codes and no consent is created
Immutable Audit Logs & Compliance Reporting
"As a compliance analyst, I want immutable logs and actionable reports so that I can demonstrate compliance and rapidly investigate potential incidents."
Description

Generates append-only, tamper-evident audit records for masking detections, attempted and successful reveals, exports, and configuration changes. Captures actor, timestamp, record context, token category, policy version, reason code, consent reference, and outcome. Stores logs with hash chaining and retention controls, and provides role-based dashboards for oversight (e.g., reveal frequency, top reason codes, time-to-remask, false-positive rate). Supports export to SIEM via syslog/HTTP, scheduled compliance reports (HIPAA/GLBA/GDPR-aligned), and anomaly alerts for suspicious behavior (e.g., repeated reveals outside business hours). Enables incident investigations with scoped replay views without exposing raw PII/PHI.

Acceptance Criteria
Tamper-Evident Hash Chain Enforcement
Given an ordered sequence of audit log entries with hash chaining when any historical entry is modified or deleted then the integrity verification job flags the chain as invalid identifies the first broken link and sets integrity_status failed for the affected partition Given an attempt to update or delete an existing audit entry via API or storage when the request is executed then the system rejects the operation with HTTP 409 Conflict persists a new tamper_attempt audit entry and leaves existing entries unchanged Given the daily integrity verification schedule when the job runs then 100 percent of partitions created in the last 24 hours are verified within 15 minutes and the results are queryable via the Integrity API and dashboard
Event Coverage and Required Field Capture
Given a masking detection occurs when the event is persisted then exactly one audit record is appended within 2 seconds capturing actor timestamp UTC ISO 8601 record_context claim_id and artifact_id token_category policy_version consent_reference null reason_code null and outcome detected Given a reveal is attempted without required reason_code or consent_reference per policy when the user submits the reveal then the reveal is blocked an audit record is appended with outcome denied_reason_required or denied_consent_required and no PII is revealed Given a reveal is approved per role consent and purpose when the user submits the reveal then an audit record is appended within 2 seconds with outcome revealed reason_code captured consent_reference captured token_category captured and a remask_expiry timestamp included Given an export of audit data is initiated when the export starts and completes then audit records are appended for export_started and export_completed with actor timestamp scope destination and outcome Given a masking policy configuration change is saved when the change is applied then an audit record is appended with actor timestamp policy_version_before policy_version_after change_summary and outcome applied
Retention Controls and Legal Hold
Given a retention policy of 365 days is configured when an audit entry age exceeds 365 days and it is not on legal hold then the purge job deletes it within 24 hours appends a purge_proof record with the entry hash and updates storage counters Given a compliance officer places a legal hold on audit entries scoped to a claim_id when the hold is active then no purge occurs for matching entries regardless of age and hold_applied and hold_released events are audit logged with actor and scope Given a retention policy update is saved when applied then an audit record is appended with old_policy new_policy actor and timestamp and the new policy takes effect for subsequent purge evaluations only
Oversight Dashboards and Anomaly Alerts
Given a user with role Compliance_Viewer signs in when they open the Oversight dashboard then they can view organization wide metrics reveal_frequency by user and time period top_reason_codes time_to_remask median and p95 and false_positive_rate without access to raw PII or PHI and users without this role receive HTTP 403 Given audit data exists for the last 30 days when the dashboard loads then metrics compute within 5 seconds and reflect data up to the last 5 minutes with a visible data freshness timestamp Given a configurable anomaly rule greater than or equal to 5 reveals by the same user outside business hours within 1 hour when the condition is met then an anomaly_alert event is generated within 60 seconds delivered to configured destinations email Slack and webhook and visible on the dashboard with status open until acknowledged
SIEM Export via Syslog and HTTP
Given a SIEM destination using syslog over TLS is configured when export is enabled for audit events then events are transmitted in JSON over TCP TLS 1.2 or higher with optional mutual TLS and a 2xx acknowledgement from the destination marks the batch as delivered Given a SIEM destination using HTTP POST is configured when network errors or 5xx responses occur then the exporter retries with exponential backoff for up to 24 hours guarantees at least once delivery and writes undelivered batches to a dead letter queue with alerting Given field mapping is configured when an event is exported then required fields actor timestamp event_type token_category policy_version reason_code consent_reference outcome and record_context are present and validated against the schema or the event is rejected and logged with outcome export_failed_schema_validation
Scheduled Compliance Reports
Given schedules are configured for HIPAA GLBA and GDPR reports when the schedule triggers then the system generates a report for the prior period with sections on access and reveal activity policy changes anomaly alerts and retention actions excluding raw PII or PHI and stores it for download Given delivery settings are configured when a report is generated then it is delivered to the specified destinations SFTP and email encrypted with configured keys and report_generated and report_delivered audit events are appended Given a report fails to generate or deliver when the failure occurs then an alert is sent to configured channels within 2 minutes and the failure is logged with error details
Scoped Replay View for Incident Investigations
Given a user with role Investigator opens a claim audit timeline when they select a time window and event types then a replay view shows the ordered sequence of masking detections reveals exports and configuration changes with timestamps actors token categories and outcomes while all raw PII or PHI values remain redacted Given the replay includes reveal events when the user attempts to view revealed content then only token metadata reason_code and consent_reference are shown and raw token values are irretrievable with a notice that content is redacted by design Given a user without Investigator or Compliance role attempts to access the replay when they request it then access is denied with HTTP 403 and a security_denied event is audit logged
Cross-Channel Mask Enforcement
"As an integration engineer, I want masking enforced across every channel and integration so that no sensitive data leaks through connected tools or workflows."
Description

Ensures masking is consistently applied across all ClaimFlow surfaces and connected systems, including case views, chat, email composer, notes, forms, attachments, OCR’d images/PDFs, and call transcripts. Provides middleware and SDKs for partner integrations (CRM, helpdesk, document storage) so only redacted content leaves the platform, with webhooks for enforcement at ingress and egress. Normalizes data from third parties, sanitizes copy/paste and clipboard operations, and applies redaction to cached previews and thumbnails. Supports mobile and desktop parity, offline queueing with local redaction, and graceful degradation if a downstream service is unavailable.

Acceptance Criteria
Cross-Surface Default Masking in UI
- Given a signed-in user with standard adjuster role, when viewing case views, chat, email composer, notes, forms, and task panes, then all detected PII/PHI tokens are masked by default and displayed as standardized placeholders. - Given a user with reveal permission, when they request a just-in-time reveal and provide a valid reason code (and consent where required), then only the specific token un-masks for that user for a maximum of 5 minutes or until navigation, after which it is automatically re-masked. - Given any reveal event, when the reveal occurs, then an audit log entry captures user ID, role, case ID, field/segment revealed, reason code, consent reference, timestamps, and duration. - Given the application runtime, when inspecting page source, network requests, and browser storage, then no unmasked PII/PHI is present unless a reveal session is active for that token, and revealed values are never persisted client-side beyond the session.
Attachments, OCR, and Transcript Redaction
- Given a user uploads an image or PDF with PII/PHI, when OCR completes, then extracted text is stored and indexed only in redacted form and the preview/thumbnail renders masked content with no recoverable original pixels. - Given a live call recording producing a transcript, when transcripts are streamed and finalized, then PII/PHI tokens are masked in real time and remain masked in the saved transcript. - Given a user attempts to download or share an attachment or transcript, when the request is processed, then only the redacted variant is available for egress; access to originals is blocked and logged.
Egress Enforcement via Middleware and SDK
- Given an outbound integration (CRM/helpdesk/document storage) configured via the SDK, when ClaimFlow sends payloads, then the middleware ensures only redacted content is transmitted and blocks any payload containing unredacted PII/PHI with a 4xx error and an audit entry. - Given an outbound webhook, when the event is emitted, then the payload includes redaction metadata (mask schema and token map references) without clear-text sensitive values and retries preserve masking. - Given a partner requests original values via API, when the request lacks explicit policy, role authorization, and consent artifacts, then the request is denied and the attempt is audit-logged.
Ingress Normalization and Sanitization
- Given inbound data arrives via webhook, API, or email ingestion, when the payload contains free text or attachments with PII/PHI, then the system normalizes encodings (e.g., base64, URL-encoded, locale formats) and masks sensitive tokens before persistence or indexing. - Given third-party structured fields that embed PII/PHI, when mapping to ClaimFlow schema, then sensitive values are tokenized/masked and only redacted variants are stored in searchable fields. - Given sanitized content is available in the UI or workflow engine, when it is consumed, then no unredacted values are rendered or propagated internally beyond a controlled, audited reveal session.
Clipboard, Copy/Paste, and Drag Export Sanitization
- Given a user selects text that includes PII/PHI, when copying to the clipboard, then the clipboard contains masked tokens unless a reveal session is active for those tokens; if revealed, only the selected revealed tokens are copied in clear text, the clipboard auto-clears within 60 seconds, and the event is audit-logged. - Given a user drags an attachment from ClaimFlow to the desktop or another app, when the drop completes, then only a redacted file is exported; export of originals is blocked and logged. - Given a user pastes external text into ClaimFlow inputs, when the paste occurs, then PII/PHI in the pasted content is detected and masked prior to saving or display.
Cached Previews and Thumbnails Redaction
- Given previews and thumbnails are generated for attachments and embedded images, when assets are rendered and cached/CDN-distributed, then only redacted variants are stored; no unredacted rendition is present in caches or storage. - Given a direct URL request to an asset, when the request is made, then it resolves only to the redacted asset with authorization enforced; any attempt to access an unredacted key returns 403/404 and is audit-logged. - Given a redaction policy change or reprocessing event, when it is applied, then previously cached assets are invalidated and regenerated within 15 minutes and no stale unredacted asset is served thereafter.
Parity, Offline Queueing, and Graceful Degradation
- Given ClaimFlow clients on mobile and desktop, when executing the masking test suite, then equivalent behaviors and results are observed on both platforms with 100% pass rate for cross-channel masking cases. - Given a device is offline during intake or chat, when content is captured, then local on-device redaction is applied before any display or queueing; queued egress remains redacted and, upon reconnection, the same redacted payload is transmitted. - Given the downstream redaction service is unavailable, when users interact with content or egress is attempted, then the system defaults to mask-all and blocks egress of unredacted data; the UI remains usable with masked placeholders and incidents are surfaced and audit-logged.
Admin Policy Configuration & Simulation
"As an admin, I want to configure and safely test masking and reveal policies so that we can adapt to each carrier’s rules without disrupting adjuster workflows."
Description

Delivers an admin console to configure sensitive token catalogs, regex patterns, ML thresholds, role mappings, purposes, reason codes, and reveal timebox durations. Supports per-tenant and per-line-of-business scoping, versioning, and change approvals with full auditability. Includes a simulation sandbox to test policies against sample or synthetic datasets, show diffs between policy versions, and estimate impact (precision/recall, latency) before promotion to production. Provides safe defaults, emergency kill switches, and migration tooling to roll out or rollback policy changes without downtime.

Acceptance Criteria
Token Catalog, Patterns, and ML Thresholds Configuration
Given a Policy Admin in tenant T with LOB L and an existing draft policy version When they add a new token type with a unique name, select detection method(s) (Regex and/or ML), supply one or more regex patterns, set an ML threshold between 0.00 and 1.00 (max two decimals), and click Save Then the system validates required fields, rejects duplicate names (case-insensitive) within scope T/L, compiles all regex patterns, and enforces the threshold bounds And invalid inputs show inline errors without losing user-entered data And on success the change is persisted to the draft version with a change delta, editor identity, timestamp, and version increment And a mask preview renders for a 1,000-character sample within 1 second with the configured patterns applied
Role–Purpose–Reason Mapping and Reveal Timebox
Given a Policy Admin with access to tenant T When they create or edit a mapping that associates role(s) with allowed purposes, reason codes, permitted token types, and a reveal timebox duration Then each mapping requires at least one purpose, at least one reason code, and a timebox between 1 and 60 minutes (default 5 minutes) And overlapping mappings for the same role–purpose–LOB are flagged with a conflict and cannot be saved until resolved And saved mappings are retrievable via API including role IDs, purpose IDs, reason codes, token type IDs, and timebox seconds And attempts to set a timebox beyond 60 minutes or use an undefined reason code are blocked with validation errors
Per-Tenant and LOB Scoped Policies
Given tenants A and B and LOBs Auto and Home When an admin in tenant A creates a policy draft scoped to Auto Then GET /admin/policies?tenant=A returns the draft and GET /admin/policies?tenant=B returns none And the effective policy resolver returns the Auto-scoped policy for Auto contexts in tenant A and the default policy for Home contexts in tenant A And cross-tenant access is denied with HTTP 403 for admins from tenant B attempting to view tenant A’s policies
Policy Versioning, Approvals, and Auditability
Given a draft policy version V2 exists for tenant T When the Policy Admin submits V2 for approval requiring 2 approvers from group Compliance Then V2 becomes read-only, approval tasks are created, and an audit record captures submitter, timestamp, and a cryptographic diff hash vs V1 And approval requires 2 distinct approvers; on approval V2 status becomes Ready for Promotion; on any rejection V2 status becomes Changes Requested with mandatory comments And the audit log is append-only and exportable (NDJSON) with event type, actor, timestamp, and change delta And attempts to promote without required approvals are blocked with HTTP 409
Simulation Sandbox, Metrics, and Version Diff
Given an admin uploads or selects a labeled dataset of up to 10,000 documents with ground-truth tags When they run a simulation comparing draft V2 against baseline V1 Then the system computes per-token precision, recall, F1, false positives, false negatives, and 95th-percentile masking latency per 100 documents, and persists the results linked to V2 And the run completes within 10 minutes with a visible progress indicator and is cancellable And a side-by-side diff view highlights added/removed/changed tokens, regex edits, threshold changes, and mapping differences between V1 and V2 And no simulated data is written to production logs or used to update live masking behavior
Safe Defaults and Emergency Kill Switch
Given a new tenant T with no custom policy When an admin opens the console Then safe defaults are preloaded: common PII/PHI tokens enabled, conservative ML thresholds (>= 0.90), reveal timebox default 5 minutes, and no role has blanket reveal permissions And a Super Admin can activate a kill switch for tenant T that forces mask-all, disables all reveals, and invalidates active reveal sessions within 60 seconds And kill switch activation and deactivation require a reason code and are fully audit-logged and reversible
Zero-Downtime Rollout and Rollback
Given policy V2 is Ready for Promotion When the admin performs a canary rollout to 10% of users in tenant T and then promotes to 100% Then no user sessions are dropped, masking remains continuous, and average masking latency does not degrade by more than 10% versus baseline during rollout And the admin can roll back to V1 within 60 seconds; rollback is atomic and restores prior behavior without downtime And all rollout and rollback actions are audit-logged with scope, percentage, initiator, and timestamps

Consent Ledger

A unified, tamper‑evident registry that binds consent to specific data, purposes, and durations at the claim and artifact level. Auto-captures consent via TapSign, propagates limits across workflows, alerts on expirations, and blocks non‑compliant access. Gives auditors a clear, exportable trail of who can see what and why.

Requirements

Tamper-Evident Consent Ledger
"As a compliance officer, I want an immutable, tamper-evident record of consents and changes so that I can prove regulatory compliance during audits."
Description

Implement an append-only, cryptographically chained store for consent records and their lifecycle events (capture, update, renewal, revocation). Each entry is time-stamped, signed, and bound to specific claim IDs, artifact hashes (photos, messages, documents), and extracted entities from ClaimFlow’s NLP engine. Provide query APIs to resolve effective consent at read time and to verify integrity proofs. Integrate with ClaimFlow services via an internal SDK and ensure idempotent writes, clock skew tolerance, and high availability to guarantee auditability and durability.

Acceptance Criteria
Append-Only Hash-Chained Ledger Entry
Given a valid consent record payload and idempotency key, When the SDK writes the entry, Then the ledger assigns a monotonically increasing sequence number and server timestamp and appends the entry without modifying prior entries. Given the ledger state at time T, When any attempt is made to update or delete a prior entry via SDK or storage API, Then the operation is rejected with HTTP 409 and no mutation occurs. Given two consecutive entries i and i+1, When verifying i+1.previousHash equals hash(i), Then verification succeeds; otherwise integrity verification returns failure code and an audit event is emitted.
Binding Consent to Claim, Artifact, and NLP Entities
Given a consent capture event for claimId C with artifact hash A and entity IDs E1..En, When the entry is written, Then the stored record contains exact match values for C, A, and set(E1..En) and a Merkle binding hash Hbinding = H(C||A||sorted(E1..En)). Given a query by claimId C and artifact hash A, When retrieving the consent record, Then the response includes the bound entities and Hbinding, and recomputation of Hbinding matches the stored value. Given an artifact whose content changes, When its recomputed hash no longer equals A, Then effective consent for that artifact is invalid and resolution returns status "artifact_mismatch".
Consent Lifecycle State Transitions
Given an existing consent record in state captured, When an update event with narrower scope is appended, Then the effective state is updated to updated with previous scope preserved in history. Given a consent with expiry at time Te, When current server time >= Te, Then the effective consent is expired and resolution returns "expired" with no access allowed. Given a renewal event before expiry, When appended, Then the new expiry supersedes the prior expiry and continuity is recorded linking to the prior sequence. Given a revocation event, When appended, Then effective consent becomes revoked immediately and any subsequent read checks return denial regardless of prior grants.
Read-Time Effective Consent Resolution API
Given a request with claimId C, artifact hash A, entityIds set E, purpose P, and requester role R at time Tr, When calling GET /consent/effective, Then the API returns allow only if there exists a non-expired, non-revoked consent whose scope includes {C,A,E} and purpose P and authorizes role R. Given multiple overlapping consents, When resolving, Then the engine computes the intersection of scopes and applies the strictest limits (deny overrides allow) and returns the decision with evaluated policy trace. Given consent expiry within configurable threshold Δ, When resolving, Then the response includes "impending_expiry" metadata with remaining seconds <= Δ. Given no matching consent, When resolving, Then the API returns deny with reason "no_consent_found".
Integrity Proof Verification API
Given a sequence number range [i, j], When calling GET /consent/proof?from=i&to=j, Then the API returns a proof object containing chain hashes that validate in O(j−i) and verify() returns true. Given a single entry with seq k, When calling GET /consent/proof?k=k, Then the proof includes the entry hash and prior hash, and verification fails if any bit of the entry payload has been altered. Given a notarized checkpoint hash Hc at time Tc, When requesting a proof to Hc, Then the API returns a path that validates the current head includes Hc or returns 404 if not in ancestry.
Idempotent Writes via SDK
Given a well-formed write with idempotencyKey K, When the same request is retried any number of times within 24h, Then exactly one ledger entry is created and all responses return the same ledger sequence and etag. Given a retry with modified payload but same K, When submitted, Then the request is rejected with HTTP 422 "idempotency_key_payload_mismatch" and no new entry is written. Given a write initiated without K, When a network timeout occurs and the SDK retries, Then the SDK reuses the original generated K for the retry and no duplicate entries are created.
Operational Resilience: Clock Skew, Ordering, and Availability
Given client clocks skewed by up to ±5 minutes, When writes are received, Then the ledger uses server time for timestamps and orders entries by sequence while preserving causality, and no write is rejected solely due to client timestamp within the skew window. Given a regional availability disruption, When the primary node is unavailable, Then writes and reads succeed via failover within 60 seconds and RPO <= 1 entry with eventual reconciliation proof. Given normal operations over a 30-day period, When measured, Then the ledger meets or exceeds 99.95% monthly read and write availability and replicates each entry to at least 3 fault domains within 1 second.
Granular Consent Binding
"As an adjuster, I want consent scoped to specific artifacts and purposes so that I only access data I’m permitted to use for my task."
Description

Model consent at multiple levels of granularity—claim-level, artifact-level, and field-level (extracted entities)—with explicit purpose limitation, recipient classes, jurisdictional basis, and duration. Bind consent to data via stable IDs and content hashes, track derivations from NLP extraction to maintain lineage, and compute inheritance/override rules across scopes. Expose UI and API views to inspect the effective consent for any claim, artifact, or field to guide downstream processing in ClaimFlow.

Acceptance Criteria
Create Claim-Level Consent via TapSign
Given a new claim CLM-123 exists and the claimant completes TapSign consent with purposes [Intake, FraudReview], recipientClasses [InternalAdjuster, ThirdPartyAssessor], jurisdictionBasis "GDPR Art.6(1)(a)", and duration P1Y When the signed payload is posted to POST /consents with scope=claim and claimId=CLM-123 Then the API responds 201 with a consentId, startAt set to TapSign signature time (UTC), expiresAt startAt+P1Y, and the record is retrievable via GET /consents?scope=claim&claimId=CLM-123 including purposes, recipientClasses, jurisdictionBasis, duration, signer, signatureRef And the consent is bound to the claim via stableId CLM-123 and the TapSign document hash, both stored immutably And the effective consent for CLM-123 returned by GET /consents/effective?scope=claim&claimId=CLM-123 matches the posted limits exactly
Artifact-Level Consent Override with Purpose Limitation
Given claim CLM-123 has an active claim-level consent allowing purposes [Intake, FraudReview] and recipientClasses [InternalAdjuster, ThirdPartyAssessor] And artifact ART-456 (photo) is uploaded to CLM-123 with contentHash H1 When a user creates an artifact-level consent override for ART-456 restricting purposes to [Intake] and removing recipientClass ThirdPartyAssessor Then GET /consents/effective?scope=artifact&artifactId=ART-456 returns purposes [Intake] and recipientClasses [InternalAdjuster] with sourceScopes [claim, artifact] And any attempt to broaden beyond the parent (e.g., add purpose "Marketing") is rejected with 422 CF-CONSENT-OVERRIDE-BROADENING and no state change And UI badge on ART-456 displays "Overrides parent: narrowed"
Field-Level Consent Binding with NLP Lineage
Given artifact ART-456 with contentHash H1 is processed by NLP, extracting field ENTITY:LicensePlate with value "7ABC123" and extractionId EXT-789 And an explicit field-level consent is created for ENTITY:LicensePlate limiting purposes to [FraudReview] and recipientClasses [InternalAdjuster] When a workflow step for purpose "Intake" requests ENTITY:LicensePlate via GET /fields/ENTITY:LicensePlate?artifactId=ART-456 Then the request is denied with 403 CF-CONSENT-DENIED and includes effectiveConsent snapshot showing purposes [FraudReview] And GET /consents/lineage?fieldId=ENTITY:LicensePlate&artifactId=ART-456 returns the derivation chain [claimConsentId, artifactConsentId, fieldConsentId=explicit] and extractionId EXT-789 linking field to ART-456 (H1) And GET /consents/effective?scope=field&fieldId=ENTITY:LicensePlate&artifactId=ART-456 shows inheritance of recipient class removal (no ThirdPartyAssessor) from artifact scope
Effective Consent API for Artifact
Given claim CLM-123 has claim-level consent C-1 and artifact ART-456 has an override consent C-2 When a client calls GET /consents/effective?scope=artifact&artifactId=ART-456 Then the API responds 200 with JSON containing fields: artifactId, allowedPurposes, allowedRecipientClasses, jurisdictionBasis (resolved), startAt, expiresAt, sourceScopes, version, etag And the etag equals SHA-256 of the canonicalized effective consent payload and the latest contributing consent record hashes And the response excludes any purpose or recipient not present in both parent and child scopes (intersection rule) And p95 latency for this endpoint is <= 200 ms under 1k rpm in staging with a dataset of 100k consents (measured via APM)
Block Non-Compliant Access and Audit
Given user U-777 in recipientClass ThirdPartyAssessor requests GET /artifacts/ART-456 where effective consent for ART-456 excludes ThirdPartyAssessor When the request is evaluated by the consent gate Then the API returns 403 CF-CONSENT-DENIED with reason "recipientClass not allowed" and does not stream artifact bytes And an audit event is written with fields: time, userId, recipientClass, subjectType=artifact, subjectId=ART-456, decision=deny, reasonCode, effectiveConsentEtag And the audit event is visible in GET /audits?subjectId=ART-456 within 2 seconds of the denial
Consent Expiration Alert and Enforcement
Given claim CLM-123 has consent C-1 expiring at 2025-12-31T00:00:00Z When the daily job runs at 02:00Z and a consent has T-7 days remaining Then notifications are sent to claim owner and DPO channels with subject "Consent expiring" and include claimId, consentId, expiresAt And upon reaching expiration, effective consent for CLM-123 transitions to state expired and access checks return 403 CF-CONSENT-EXPIRED And renewing via TapSign creates a new consent C-2 with startAt at signature time, previous C-1 marked superseded, and effective consent recomputed to reference C-2
Tamper-Evident Binding with Stable IDs and Content Hashes
Given artifact ART-456 has contentHash H1 and an associated consent bound to H1 When the artifact file is updated producing contentHash H2 Then the system requires an explicit re-bind or new consent for H2; effective consent for H2 defaults to inherited claim-level limits only, with no artifact-specific overrides applied until created And GET /consents/bindings?artifactId=ART-456 returns entries for H1 and H2 with distinct hashes and createdAt timestamps And any attempt to mutate an existing consent record in-place is rejected with 409 CF-CONSENT-IMMUTABLE; updates must create a new version with a new record hash and previous record referenced in prevHash, forming an immutable chain verifiable via GET /consents/export?format=ledger
TapSign Consent Capture Integration
"As a claimant, I want to review and sign consent on my phone with clear explanations so that I understand and authorize how my data will be used."
Description

Integrate TapSign to capture explicit, context-rich consent with digital signature and versioned notice text. Support SMS/email deep links and in-app flows with localization and accessibility. On completion, auto-write a consent record with purposes, retention, and jurisdictional terms to the ledger, linking it to the claimant and relevant artifacts. Provide fallback capture and retry when TapSign is unavailable and store evidentiary artifacts (signature hash, IP, user agent, timestamps).

Acceptance Criteria
SMS Deep Link Consent Capture via TapSign
Given a claim requires explicit consent and the claimant has a verified mobile number When ClaimFlow sends an SMS deep link to TapSign and the claimant opens it, reviews the notice, and completes the digital signature Then a consent record is written to the Consent Ledger within 3 seconds containing: claimId, claimantId, artifactIds[], channel="sms", purposes[], retention{duration,unit}, jurisdiction{code}, noticeVersionId, noticeTextHash(SHA-256), signatureHash(SHA-256), ipAddress, userAgent, tapSignTransactionId, signedAt(ISO-8601 UTC) And the ledger record is immutably linked to the claim and artifacts and is retrievable via GET /consents/{id} And an audit event "ConsentCaptured" with ledgerId is emitted
Email Deep Link Consent Capture via TapSign
Given a claim requires explicit consent and the claimant has a verified email address When ClaimFlow sends an email deep link to TapSign and the claimant opens it, reviews the notice, and completes the digital signature Then a consent record is written to the Consent Ledger containing the same evidentiary artifacts as the SMS flow with channel="email" And the deep link expires after the configured TTL; attempting to use an expired/invalid link shows a "LinkExpired" page and allows requesting a new link And an audit trail records link sent time, open time, and signature completion time
In‑App Consent Flow with Localization and Accessibility
Given the claimant initiates the in‑app consent flow with locale preferences and assistive technologies enabled When the consent screen is displayed Then all notice content and UI strings render in the claimant's locale (supporting at least en-US, es-ES, fr-CA) with fallback to en-US if a translation is missing and localeFallback=true recorded in the ledger And all interactive controls have accessible names, are keyboard-operable, preserve logical focus order, and meet WCAG 2.1 AA contrast (>=4.5:1) And screen readers announce step titles and notice headings in the correct language; zoom up to 200% does not cause loss of content or functionality And upon signature, the same evidentiary artifacts as other channels are captured with channel="in-app" and the ledger write succeeds
Versioned Notice Binding and Evidence Integrity
Given notice content varies by jurisdiction and purpose and is versioned When the notice is rendered for consent and the claimant signs Then the exact rendered payload (HTML/PDF) is hashed with SHA-256 and stored as noticeTextHash, and the displayed noticeVersionId is recorded in the ledger And the signature is cryptographically bound to noticeTextHash and signedAt; retrieving the consent returns the exact text/version shown at signing And any subsequent notice edits create a new noticeVersionId and do not alter existing ledger entries
TapSign Unavailability Fallback and Retry
Given TapSign API calls fail due to network errors, HTTP 5xx/429, or timeouts (>10s) When a claimant attempts to provide consent Then the system presents a fallback capture within 5 seconds that renders the same notice, captures a drawn or typed signature, requires a one-time verification code (SMS/email) to bind identity, and records channel="fallback" with tapSignTransactionId=null and tapSignError{code,message} And the consent is written to the ledger immediately with full evidentiary artifacts and reconciliationStatus="pending" And the system retries TapSign submission with exponential backoff up to 24 hours or 10 attempts (configurable), appending tapSignTransactionId on success and emitting "ConsentReconciled"; no duplicate ledger entries are created And if retries exhaust, reconciliationStatus="failed" is recorded and an Ops alert is sent; the fallback consent remains valid and discoverable
Jurisdictional Terms, Purpose Scope, and Access Enforcement
Given a consent ledger entry includes purposes[], retention, and jurisdiction terms and is linked to claim and artifact IDs When any user or service requests access to a linked artifact or PII Then access is granted only if the requested purpose matches purposes[] and the current time is within the retention window and jurisdiction permits access; otherwise the request is blocked with HTTP 403 and an audit event "ConsentDenied" is recorded with ledgerId and attemptedPurpose And when retention expires, access is automatically revoked within 1 minute, an alert "ConsentExpired" is emitted, and affected workflow tasks are paused with a remediation note And the consent record is exportable via API as CSV/JSON with all fields and evidentiary hashes for audit
Policy Enforcement & Access Gate
"As a claims manager, I want the system to block non-compliant access automatically so that my team cannot accidentally view or share data without proper consent."
Description

Introduce a centralized policy engine that consults the Consent Ledger at runtime to permit, deny, or redact access to data in the UI, APIs, exports, and workflow actions. Enforce purpose limitation and duration constraints, block task transitions that would violate consent, and integrate with ClaimFlow RBAC to produce combined decisions. Log every decision with rationale for auditability and support just-in-time flows to request incremental consent when needed.

Acceptance Criteria
UI and API Access Decision with Purpose Limitation and Redaction
Given a signed-in user with RBAC read access to Claim 123 and declared purpose 'Investigation' and active consent excludes fields 'SSN' and 'BankAccount' from purpose 'Investigation' When the user requests Claim 123 via the UI and the GET /claims/123 API Then the policy engine consults the Consent Ledger at runtime and returns HTTP 200 And permitted fields are returned unmodified And non-consented fields are returned with value 'REDACTED' And the response schema (set of keys) remains unchanged And attempting to access an artifact with zero permitted fields returns HTTP 403 with error_code='CONSENT_DENIED_PURPOSE'
Export Job Enforcement of Consent Scopes and Duration
Given an export job configured for purpose 'Reporting' for a set of claims and consents restrict 'Photos' to purpose 'Investigation' only and consent for Claim 150 expired When the export runs Then exported files include only records and fields with active consent for purpose 'Reporting' And fields without consent are redacted with value 'REDACTED' or omitted per export policy And records with fully expired consent are excluded from the export And the export summary reports counts for total_records, redacted_fields, and omitted_records_due_to_consent And if no records meet consent constraints the job completes with status='failed' and error_code='CONSENT_BLOCKED_EXPORT'
Workflow Transition Gate Prevents Consent Violations
Given a workflow task transition 'Share Estimate with Vendor' that requires purpose 'ThirdPartySharing' for fields 'EstimatePDF' and 'PolicyNumber' And Claim 789 lacks active consent for purpose 'ThirdPartySharing' covering those fields When a user attempts the transition Then the transition is blocked and no side effects are executed And the UI displays a blocking message listing the missing purpose and fields And the API returns HTTP 409 with error_code='CONSENT_BLOCKED_TRANSITION' And after required consent is granted the same transition succeeds (HTTP 200/204) and side effects are applied
Combined RBAC and Consent Policy Decision
Given a user requests access to PII fields on a claim When RBAC denies the action regardless of consent Then the decision is DENY with HTTP 403 and error_code='RBAC_DENY' When RBAC allows the action but consent for the declared purpose is missing or expired Then the decision is DENY with HTTP 403 and error_code='CONSENT_DENY' When RBAC allows and consent for the declared purpose is active and within duration Then the decision is PERMIT with HTTP 200 and unredacted data
Decision Audit Logging with Rationale and Evidence
Given any permit, deny, or redact decision is made by the policy engine When the decision is returned to a caller (UI, API, export, workflow) Then an audit record is written containing: timestamp (UTC), actor_id, resource_type, resource_id, action, declared_purpose, decision (permit/deny/redact), policy_version, and rationale including RBAC rule IDs and consent artifact IDs consulted And the audit record is retrievable by correlation_id and time range via the audit API and UI export And the audit log is append-only and cannot be modified via any public API
Just-in-Time Incremental Consent Request and Retry
Given an access attempt is denied solely due to missing consent for a specific purpose and scope and JIT consent is enabled When the system initiates a TapSign consent request specifying purpose, fields, and requested duration Then the end-user receives the request and can approve or decline And upon approval within 15 minutes the original action is automatically retried once and succeeds without manual refresh And upon decline or timeout the original action remains denied with HTTP 403 and error_code='CONSENT_REQUIRED' and includes a reference to the consent_request_id
Consent Expiration/Revocation Propagation and Fail-Closed Behavior
Given an active consent for Claim 321 expires at a known timestamp T When current time passes T Then subsequent access checks within 5 seconds reflect expiration by denying or redacting previously permitted data And any cached PERMIT decisions for the expired scope are invalidated within 5 seconds And if the Consent Ledger is unavailable during an access check Then the system fails closed by returning HTTP 503 with error_code='CONSENT_SERVICE_UNAVAILABLE' and no sensitive data is returned
Consent Propagation Across Workflows and Integrations
"As an operations lead, I want consent limits to follow data across internal workflows and third-party handoffs so that we never expose information beyond what was authorized."
Description

Propagate consent constraints throughout ClaimFlow workflows and to external vendors and systems. Annotate tasks with required consent scopes, trim outbound payloads to permitted fields, and attach consent metadata headers to API/webhook calls. Automatically create follow-up tasks to obtain additional consent when downstream steps or recipients require broader access, ensuring constraints follow the data end-to-end.

Acceptance Criteria
Task Annotation with Consent Scopes
Given a claim and linked artifacts with recorded consent scopes for data categories and purposes When a new workflow task is created from a task template Then the task is automatically annotated with the minimal required consent scopes based on the template and linked artifacts Given a task requires purpose P and data category set D When the linked consent does not include P or fully cover D Then the task status is set to "Blocked - Consent Required" and an alert is posted to the assignee and channel configured for the claim Given consent scopes for a claim are updated in the ledger When the update is committed Then all open tasks’ annotations refresh within 5 seconds and a history entry records timestamp, actor, previous scopes, and new scopes
Outbound Payload Trimming to Consent-Allowed Fields
Given an outbound integration mapping defines fields F = {A,B,C,D} And current consent permits only {A,B} When ClaimFlow generates the outbound payload Then only {A,B} are sent and {C,D} are omitted or set to contract-compliant nulls And the request includes a header X-Consent-Trimmed: "C,D" and X-Consent-Trim-Count: 2 Given prohibited fields exist in a fixed-schema contract When payload is constructed Then prohibited values are replaced with "REDACTED" and the payload passes schema validation for the target system Given a user attempts a manual export that would include fields outside consent When the export is initiated Then the export is blocked with a message referencing consent record ID, missing scopes, and a link to request additional consent
Consent Metadata Headers on API/Webhook Calls
Given an API/webhook call is made to an external vendor for claim data When the request is sent Then it includes headers X-Consent-Id, X-Consent-Purpose, X-Consent-Expiry (ISO 8601 UTC), X-Consent-Data-Categories, and X-Consent-Hash that match the ledger Given any payload field lies outside the allowed consent scopes When the request is prepared Then the call is blocked and a 412 Precondition Failed is logged with event type "consent_mismatch" and correlation ID Given the current time is on or after the consent expiry When preparing the call Then the system refuses to send and logs event type "consent_expired" with the consent ID and expiry timestamp
Automatic Follow-Up Consent Task Creation
Given a downstream workflow step requires broader access than current consent allows When the step is queued for execution Then an "Obtain Consent" task is auto-created with requested scopes, purpose, duration, and the impacted recipients prefilled And the original step is set to "Blocked - Awaiting Consent" Given the new consent is captured via TapSign When the ledger records the consent as active Then the blocked step automatically transitions to "Ready" and is re-queued within 10 seconds, and the task is completed with linkage to the consent record Given the consent request is declined or expires When the SLA for the blocked step elapses Then the step is auto-cancelled with reason code and all stakeholders receive notifications per routing rules
Consent Expiration Handling in Workflows and Integrations
Given a consent with expiry T is attached to artifacts and tasks When current time reaches or exceeds T Then all tasks requiring that consent transition to "Blocked - Consent Expired" and outbound calls referencing that consent are prevented And notifications are sent to task owners and the claim channel Given renewed consent is recorded with a new expiry When the ledger update is committed Then blocked tasks automatically transition back to "Ready" and an audit entry records the unblocked actions Given an integration sends batched items When any item in the batch lacks valid consent Then the batch is split to send only compliant items and a rejection report lists non-compliant item IDs and missing scopes
End-to-End Auditability and Export of Consent Propagation
Given an auditor requests a consent propagation export for claim X When the export is generated Then it includes for each outbound call: timestamp, recipient, consent ID, purpose, expiry, data categories, trimming summary (fields removed/count), headers sent, and payload hash, in both JSON and CSV, signed with a system PGP key Given any access was blocked due to consent When included in the export Then the record lists the specific rule violated, the required vs. actual scopes, the triggering step, and link to the related consent request task Given the export is produced When its checksum is computed Then a SHA-256 checksum matches the ledger’s recorded checksum for tamper-evidence
Derived Artifact Consent Inheritance and Transformations
Given a new artifact is derived from an existing artifact (e.g., OCR text from a photo) When the derived artifact is created Then it inherits the parent artifact’s consent scopes and purpose by default and the parent-child linkage is recorded in the ledger Given a transformation increases data categories (e.g., NLP extracts new PII) When the derived data becomes available Then the system evaluates consent coverage and blocks visibility and outbound transmission until additional consent is obtained if required Given a transformation reduces data categories (e.g., redaction) When the derived artifact is saved Then the artifact’s consent scopes are narrowed accordingly and the delta is logged with timestamp and actor
Expiration Monitoring & Renewal Notifications
"As a privacy coordinator, I want proactive alerts before consents expire so that I can renew them without disrupting claim processing."
Description

Continuously evaluate consent durations and jurisdictional retention rules to determine effective expiry for each consent scope. Surface banners and blockers in the UI as expirations approach, notify assigned users and privacy teams, and offer one-click renewal flows via TapSign. Record expirations and renewals to the ledger and pause or modify workflows automatically when consent lapses.

Acceptance Criteria
Effective Expiry Computation per Consent Scope
Given a consent record with scope (data types and purposes), createdAt T0, and a user-selected duration D days, and applicable jurisdictional rule maximum R days for that scope When the engine computes effectiveExpiry Then effectiveExpiry = T0 + min(D, R) And the computed effectiveExpiry is stored per-scope and per-artifact And when the jurisdictional ruleset or scope changes, the engine recalculates effectiveExpiry within 5 minutes and appends an "expiry-recalculated" event to the ledger And when no jurisdictional rule exists, effectiveExpiry = T0 + D
Pre-Expiry UI Banners and Post-Expiry Blockers
Given an effectiveExpiry timestamp T for a consent scope When now = T - 14 days (default, org-configurable) Then a yellow pre-expiry banner is displayed on the claim, artifact, and any page that accesses that scope with a countdown in days and a Renew via TapSign CTA And when now = T - 3 days (default, org-configurable) Then the banner escalates to red and actions that require the scope are marked "Requires renewal" And when now >= T Then access to affected artifacts is blocked with a modal explaining the lapse and offering the Renew via TapSign CTA And direct-link access to blocked artifacts is denied with HTTP 403 and an audit entry And when renewal succeeds, banners are removed and blockers lifted within 60 seconds
Notifications to Assignees and Privacy Team
Given an effectiveExpiry timestamp T for a consent scope on a claim with an assigned adjuster and a configured privacy team When now = T - 14 days Then the assigned adjuster and claim owner receive in-app and email notifications with a deep link to renew And when now = T - 3 days Then the privacy team receives an additional notification (email and Slack/webhook if configured) And notifications are de-duplicated per recipient per 24 hours and include current T And delivery status and read receipts (where supported) are logged to the ledger And if delivery fails, the system retries up to 3 times with exponential backoff and records a notification-failed event
One-Click Renewal via TapSign
Given a visible pre-expiry banner, blocker, or notification with a Renew via TapSign CTA for a specific consent scope When the user clicks the CTA Then TapSign opens pre-populated with the same scope, purpose, and jurisdiction, and proposes the org-default duration D' And if the user completes the signature successfully Then a new consent version is issued within 60 seconds, effectiveExpiry is recomputed, banners are cleared, blockers are lifted, and all changes are appended to the ledger with TapSign transactionId And if the user requests a duration longer than permitted by the jurisdictional rule R, the system caps to R and displays a note "Capped to policy maximum" And if signing is canceled or fails, the ledger records the failure and access remains blocked if now >= prior T
Ledger Recording of Expiry and Renewal Events
Given any expiry computation, notification dispatch, banner display, access block, renewal attempt, or renewal success/failure When the event occurs Then the system appends a tamper-evident ledger record including eventType, claimId, scopeId, artifactIds (if any), actor/system id, timestamp, jurisdiction code, ruleset version, previousConsentVersion (if any), and content hash And ledger records are immutable and returned in chronological order for audit queries And when exporting the audit trail for a claim and date range, all related expiry and renewal events are included in CSV and JSON formats
Auto-Pause and Resume of Workflows on Lapse
Given active workflow tasks that require a consent scope with effectiveExpiry T When now >= T and the consent is not renewed Then the system pauses in-flight tasks that read affected data with status "Paused: Consent Lapsed", prevents creation of new tasks requiring that scope, and pauses related SLA timers And a system comment is added to the claim and assigned users are notified And when the consent is renewed Then paused tasks automatically resume within 2 minutes and SLA timers continue, and all state transitions are logged to the ledger
Real-Time Re-evaluation on Jurisdiction or Rule Change
Given a claim whose governing jurisdiction or purpose mapping changes, or an admin updates the retention ruleset affecting the consent scope When the change is saved Then the effectiveExpiry for each impacted scope is recomputed within 5 minutes And affected users receive updated notifications only if the new effectiveExpiry alters the prior notification schedule And if the recomputation causes an immediate lapse, blockers are applied within 60 seconds and workflows are paused as per policy And the recomputation and resulting actions are recorded in the ledger with the new ruleset version
Auditor Trail Export & Reporting
"As an auditor, I want a clear, exportable trail of who accessed what data under which consent so that I can verify compliance quickly."
Description

Provide self-serve, filterable exports of consent histories, access decisions, and data lineage for a claim, portfolio segment, or time window. Include signatures, notice versions, purposes, durations, recipients, decision logs, integrity proofs, and derived-entity references. Support CSV/JSON exports, signed PDF summaries, and secure API endpoints with pagination and date filters to give auditors a clear, verifiable trail.

Acceptance Criteria
UI Export: Filter by Claim, Segment, Time Window
Given I am an authenticated user with Auditor role and portfolio scope And I can access the Export screen When I select Scope = Portfolio Segment "Midwest Auto" And Date Range = 2025-06-01T00:00:00Z to 2025-06-30T23:59:59Z And Types = Consent Histories, Access Decisions, Data Lineage And optional filters Purpose = "FNOL Intake", Recipient = "TPA Alpha" And I choose Formats = CSV and JSON And I click Generate Then a preview count displays the total records to export And the generated CSV and JSON contain only records within the selected scope and date range matching Purpose and Recipient And the exported row/item count equals the preview count And the export metadata includes selected filters and generatedAt timestamp in ISO 8601 UTC And any fields outside consent scope are redacted per policy
API Export: Secure Paginated Endpoint with Date Filters
Given an OAuth2 client with scope audit:read and permitted portfolio scope When it calls GET /api/audit/exports/consents?from=2025-06-01T00:00:00Z&to=2025-06-30T23:59:59Z&limit=500 Then the API returns 200 with payload { data:[], nextCursor, count, filters } And results are sorted by eventAt ascending and are non-overlapping across pages And limit supports 1–1000 (default 100); values >1000 are coerced to 1000 And providing nextCursor returns the next page until nextCursor is null And missing/invalid token returns 401; insufficient scope returns 403 And invalid dates or from>to return 400 with code "INVALID_DATE_RANGE" And rate limit exceeded returns 429 with Retry-After header
Content Completeness: Consent, Decisions, Lineage Fields
Rule: Each export record includes fields [claimId, portfolio, artifactId, consentId, subjectId, recipientId, recipientName, purposeCode, purposeLabel, noticeVersion, durationStartAt, durationEndAt, decision, decisionAt, decisionActor, decisionReason, accessEventId, accessAt, accessActor, lineageParentIds[], derivedEntityRefs[], integrityHash, integrityAlgo, integrityProofType, integrityProof, createdAt, updatedAt]. Rule: decision ∈ {Allow, Deny, Revoked, Expired, Blocked}. Rule: All timestamps are ISO 8601 UTC with trailing 'Z'. Rule: Optional fields are empty in CSV and null in JSON when not present. Rule: lineageParentIds[] and derivedEntityRefs[] reference known IDs in the export or include externalRef with source.
Export Formats: CSV/JSON Schema and Compression
Given a completed export job When downloading CSV Then the file is UTF-8 with LF line endings, RFC 4180 compliant, includes a header row with stable column order, and quotes fields with commas/newlines/quotes And identifiers are preserved as strings without scientific notation When downloading JSON Then the root has { schemaVersion, generatedAt, filters, count, data[] } And schemaVersion equals the current published version (e.g., "1.0") And a manifest.json includes SHA-256 checksums for each file And optional gzip compression is available via Accept-Encoding: gzip or compression=gzip
Signed PDF Summary: Verifiable Audit Summary
Given an auditor requests a PDF summary for a specific claim and date range When the PDF is generated Then it includes counts and summaries of consents, decisions, expirations, recipients, purposes, and lineage, plus notice versions And it embeds a digital signature using the organization certificate (PAdES-BES or stronger) that validates in Adobe Acrobat and open-source validators And PDF metadata includes { claimId(s), portfolio/segment, dateRange, generatedBy, generatedAt (UTC), schemaVersion, sourceDataHash (SHA-256) } And a QR code or link resolves to a verification endpoint that returns signature status and matching hashes And for up to 5,000 records the PDF size is ≤ 10 MB; larger results are split into sequenced volumes
Performance and Async Job Handling for Large Exports
Given an export request estimated at ~1,000,000 records When submitted via UI or API Then the system responds within 2 seconds with jobId and status=queued And 95th percentile completion time ≤ 5 minutes; 99th percentile ≤ 10 minutes And GET /api/audit/exports/{jobId} returns { state ∈ [queued,running,completed,failed,expired], progressPercent, startedAt, completedAt, errorReportUrl? } And upon completion a single-use HTTPS download URL is provided, valid for 1 hour and supporting HTTP range requests And partial failures produce an errorReport.csv with row-level error codes without blocking successful records
Compliance, Blocking, and Error Handling
Given export data includes fields outside consent scope Then those values are redacted as "[REDACTED]" in CSV and null in JSON, with redactionReason and policyRef included per row/item And any non-compliant accesses are recorded with decision=Blocked and blockingRuleRef When invalid filters (e.g., unknown purpose, unauthorized segment) are provided Then the system returns 400 with machine-readable codes and details.path per invalid parameter When a user without Auditor role attempts a UI export Then export controls are hidden and direct export attempts return 403 and are logged with requester, timestamp, and reason

SafeShare De‑ID

One‑click creation of share‑safe datasets and documents using tokenization, date shifting, and smart generalization. Preserves analytic value with consistent pseudonyms across claims and embeds watermarks + Proof Seal hashes. Vendors, counsel, and trainers get only what they need—nothing more—without manual redaction.

Requirements

One-click SafeShare
"As a claims manager, I want to produce a share-safe version of a claim’s files with one click so that I can quickly send necessary materials to external parties without manual redaction."
Description

Adds a single action in ClaimFlow (claim detail and bulk selection views) to generate share-safe datasets and documents from selected artifacts. The action invokes a background de-identification pipeline that performs tokenization, date shifting, and smart generalization according to a chosen policy template, preserves referential integrity with consistent pseudonyms across all included files, embeds visible watermarks and Proof Seal hashes, and assembles outputs into a versioned “Share Package.” The feature enforces role-based permissions, provides a progress HUD with cancel/retry, supports common inputs (PDF, images, emails, chats, CSV), and publishes a secure, expiring link for external recipients. Results are stored alongside the claim with lineage to source artifacts, and a workflow event is emitted so downstream automations can route the package to vendors, counsel, or training queues.

Acceptance Criteria
Authorized Access to One-Click SafeShare
Given a user with SafeShare permission on the claim When viewing Claim Detail or Bulk Selection views Then the "SafeShare" action is visible and enabled Given a user without SafeShare permission When viewing the same views Then the "SafeShare" action is hidden or disabled, and any attempt to invoke via UI or API returns 403 and no job is created Given any SafeShare invocation When the request is processed Then an audit entry records user ID, claim ID, selection scope, policy template ID, timestamp, and outcome
Policy-Driven De-Identification with Consistent Pseudonyms
Given selected artifacts and a chosen policy template When SafeShare processing completes Then all PII categories specified in the template are tokenized per template rules with 0 residual matches by the PII detector in outputs And all dates in outputs are shifted by a consistent package-level offset within the template’s allowed range And generalization rules from the template are applied to specified fields And the same real-world entity is mapped to the same pseudonym across all outputs in the package
Multi-Format Artifact Support (PDF, Images, Emails, Chats, CSV)
Given a selection containing PDFs, JPG/PNG images, EML/MSG emails (including attachments), chat transcripts (JSON/CSV), and CSV files When SafeShare runs Then outputs are produced for all supported files, with OCR applied to images and de-identification applied to email headers, bodies, attachments, and tabular text And any unsupported file types are reported with per-file errors in the job summary without failing the entire job
Share Package Assembly, Versioning, Lineage, and Event Emission
Given SafeShare completes successfully When outputs are assembled Then a Share Package with a unique ID and incremented version (vN) is created and stored alongside the claim And a manifest lists all output files, source artifact IDs, applied policy template ID, transformations applied, and the Proof Seal hash And each output file maintains lineage to its source artifact And re-running SafeShare for the same selection creates version vN+1 without overwriting prior versions And a workflow event "share_package.created" is emitted with claim ID, package ID, version, recipient scope, and link TTL for downstream automations
Watermark and Proof Seal Verification
Given SafeShare outputs are generated When reviewing output documents and images Then a visible watermark with policy-defined text is present on 100% of pages/images without obscuring core content And the package manifest contains a Proof Seal hash And verifying each file against the Proof Seal via the verification API returns "valid" for all files
Progress HUD with Cancel and Retry
Given a user launches SafeShare When the job is running Then a progress HUD displays queued, processing, packaging, and complete states with progress updates at least every 5 seconds Given the user clicks Cancel in the HUD When the system processes the request Then the job stops within 10 seconds, partial outputs are cleaned up, status is set to "Canceled," and an audit entry is recorded Given the user clicks Retry in the HUD after a failed or canceled job When processing restarts Then a new job is created using the same selection and policy, resulting in a new package version upon success
Secure Expiring Share Link Publication and Controls
Given SafeShare completes When publishing the package Then a secure, expiring link with a cryptographically strong token is generated and associated with the package And the link enforces HTTPS, expires at the configured TTL, supports manual revoke, and denies access after expiry or revoke And each access is logged with timestamp, IP, and user or recipient identifier And recipients can download the complete package contents without needing a ClaimFlow account until expiration
Deterministic Pseudonymization Service
"As a data analyst, I want consistent pseudonyms across multiple claims and exports so that I can join and trend data without exposing real identities."
Description

Implements a tenant-scoped, deterministic pseudonymization engine that replaces direct identifiers (names, emails, phone numbers, policy IDs, addresses, VINs) with consistent tokens across claims and runs. Supports scope options (per-claim, per-matter, per-tenant) to balance privacy and analytical continuity, uses salted keys stored in a KMS/HSM, and can be configured to be irreversible by default with a tightly controlled, auditable reidentification path for legally authorized users. Ensures referential integrity across documents and data tables, handles multilingual entities and domain patterns, avoids collisions, and exposes idempotent APIs for batch and streaming pipelines to keep de-identified datasets analytically useful and stable over time.

Acceptance Criteria
Tenant-Scoped Deterministic Tokens with Cross-Run Consistency
Given tenant A with keyVersion=v1 and scope=per-tenant When the service pseudonymizes the identifier "john.doe@example.com" in two separate runs Then the same token value is returned in both runs. Given tenant B (different tenant) with the same input and scope When pseudonymization is performed Then the token differs from tenant A's token. Given a corpus of 1,000,000 unique identifiers within tenant A and scope=per-tenant When each identifier is pseudonymized once Then the observed token collision count is 0.
Scope Options: Per-Claim, Per-Matter, Per-Tenant
Given scope=per-claim and claimId=C123 When the identifier "555-555-1212" appears in claims C123 and C124 Then the tokens differ between the two claims. Given scope=per-matter and matterId=M456 linking claims C123 and C124 When the same identifier appears in both claims Then the tokens are identical across those claims and differ from tokens under scope=per-tenant. Given scope=per-tenant When the same identifier appears across any claims in the tenant Then the token is identical across all appearances. Given a request without a scope parameter When processed Then the tenant-configured default scope is applied and recorded in the audit log.
KMS/HSM-Secured Salt Management and Rotation
Given the service is configured to use KMS/HSM When generating or retrieving salts/keys Then plaintext salts/keys are never logged, exported, or persisted outside the KMS/HSM boundary. Given an unauthorized principal attempts to access salts/keys When the request is made Then access is denied with HTTP 403 and the event is logged with principal, timestamp, and reason. Given tokens previously produced under keyVersion=v1 When keyVersion=v2 is activated Then requests specifying version=v1 reproduce legacy tokens and requests with version=v2 produce new tokens.
Irreversible by Default with Auditable Reidentification
Given the tenant has not enabled reidentification When any request attempts to reidentify a token Then the request is rejected with HTTP 403 and guidance to obtain legal authorization. Given the tenant enables reidentification with policy requiring role=PII_ReID, active MFA (<5 minutes), and a caseId with legal basis reference When an authorized user submits a request with a list of tokens scoped to the caseId Then the service returns only the corresponding PII for those tokens and redacts anything outside the scope. Given any reidentification request (success or denial) When processed Then an immutable audit record is written containing user, tenant, caseId, legal basis, token count, timestamps, and decision.
Idempotent Batch and Streaming APIs
Given a batch request with idempotencyKey=K1 When the identical payload is retried up to 5 times Then the response body, token outputs, and side effects are identical and no duplicate records are created. Given a streaming ingestion with messageId per record When the same messageId is delivered multiple times Then the service processes it once and acknowledges duplicates with a deduplicated status. Given API version=v1 When clients specify apiVersion=v1 Then responses conform to v1 schema and token outputs remain stable across retries and redeploys.
Referential Integrity Across Documents and Data Tables
Given a dataset comprising tables Policies, Claims, Payments and associated PDFs When identifiers are pseudonymized Then the same real-world entity maps to the same token across all tables and documents. Given foreign keys (e.g., Claims.policyId -> Policies.policyId) When pseudonymized Then the relationship remains valid using tokenized keys with zero referential integrity violations. Given a pseudonymization run completes When the service generates outputs Then a non-PII manifest is produced listing token types and counts to support downstream validation and joins.
Multilingual Entity and Domain Pattern Coverage
Given labeled test corpora in English, Spanish, and French including names, emails, phone numbers, addresses, policy IDs, and VINs When processed Then precision is >= 99.5% and recall is >= 98% for direct identifiers overall, and address recall is >= 95%. Given Unicode inputs with diacritics and non-Latin characters When processed Then tokens are produced and no identifier is left untransformed due to encoding issues. Given domain patterns for VIN (17 characters with valid check digit) When processed Then valid VINs are pseudonymized and invalid VIN-like strings are not falsely pseudonymized at a rate greater than 0.5%.
Admin Date Shift Policies
"As a compliance officer, I want to configure and enforce how dates are shifted so that shared materials remain privacy-safe while retaining analytical sequence and durations."
Description

Provides admin-configurable date shifting rules that preserve relative timelines while masking exact dates. Supports per-claim random offsets within a selectable window, fixed offsets per package, and calendar-aware adjustments (e.g., maintain weekday, avoid impossible dates, preserve intervals). Applies consistently across all artifacts in a package and logs applied offsets in a secure audit store (not included in outputs). Includes presets compliant with common privacy standards and allows policy simulation to preview impact before execution.

Acceptance Criteria
Per-Claim Random Offset Within Selectable Window
Given an admin configures a Date Shift policy with Mode=Per-Claim Random, Window=-30..+45 days, Preserve Weekday=On, Preserve Intervals=On And a package contains multiple artifacts (structured fields, messages, documents, images) linked to Claim A When SafeShare De-ID runs with this policy Then a single integer day offset k in [-30, +45] that preserves weekday is deterministically selected from a secure per-claim seed and applied to all date/time values for Claim A across all artifacts in the package And the same k is reused for every artifact and record tied to Claim A within the package; other claims in the same package receive their own independently selected k And no shifted result yields an invalid calendar date; leap-day targets on non-leap years resolve to Feb 28 And time-of-day and timezone offset components are preserved; on DST overlaps/gaps, the first valid local time is chosen And the outputs contain only shifted dates; the value of k is not present in any exported artifact
Fixed Offset Per Package
Given an admin configures a Date Shift policy with Mode=Fixed, Offset=+90 days, Preserve Weekday=On And a package contains multiple claims and artifacts When SafeShare De-ID runs with this policy Then exactly +90 days are added to every date/time value in the package, maintaining original time-of-day and timezone offset And all artifacts and claims in the package reflect the same +90-day shift And no original unshifted date/time value remains in the outputs, including embedded metadata
Calendar-Aware Interval Preservation
Given a claim contains two events with an original delta of 9 days 8 hours between their timestamps And the policy has Preserve Intervals=On When any supported offset is applied Then the delta between the two shifted timestamps equals exactly 9 days 8 hours And weekdays of shifted timestamps match original weekdays when Preserve Weekday=On And leap-day handling maps Feb 29 to Feb 28 in non-leap years without altering the preserved interval
Consistent Application Across All Artifact Types
Given a package contains structured claim fields, message threads, email headers, PDF/XMP document metadata, image EXIF, and filenames with date tokens When a Date Shift policy is executed Then every identifiable date/time value in those artifacts is shifted according to the policy’s offset rules for the associated claim or package And non-date content is unchanged And a coverage report lists the count of shifted values per artifact type; zero unshifted date/time values remain detectable by the date parser
Secure Audit Logging Without Output Leakage
Given a Date Shift job completes When inspecting the secure audit store as an Admin with Audit permission Then an immutable record exists per claim with: policy ID and version, mode (random/fixed), selected offset in days, execution timestamp, executor identity, input package ID and hash And no audit fields (including offset values or seeds) are present in any exported artifact or package manifest And attempts by non-Audit users to access the audit record are denied
Standards-Aligned Preset Policies
Given the system ships with at least three read-only presets (e.g., Research Wide Window, Vendor Fixed 90d, Minimal Shift 30d) When a preset is selected for a package Then its parameters (mode, window/offset, weekday/interval options) are locked for execution and cannot be edited in place And the preset can be cloned to a custom policy that is editable and versioned And presets are tagged with a standards note and link, and pass policy validation without conflicts
Policy Simulation Preview
Given an admin chooses Simulate on a selected policy and sample of 100 records across 3 claims When the simulation runs Then the UI shows original vs shifted samples, per-claim offset values, interval/weekday compliance checks, and anomaly flags (e.g., an invalid date would occur) And no audit log entry is written and no artifacts are modified or exported; outputs are watermarked as Simulation Only And the admin can download a CSV preview limited to 1,000 rows with masked identifiers
Smart Generalization Library
"As a privacy engineer, I want flexible generalization rules with risk scoring so that I can tailor de-identification to different sharing scenarios without destroying analytical value."
Description

Introduces configurable generalization rules for quasi-identifiers to reduce reidentification risk while preserving utility. Includes ZIP3 or county-level location, age bands, VIN truncation, license plate masking, geohash precision reduction, currency rounding/bucketing, and rare category grouping. Supports K-anonymity style thresholds, per-field policies, and an evaluation report that scores residual risk and summarizes transformations applied. Integrates with NLP-extracted entities to generalize free-text consistently across documents and datasets.

Acceptance Criteria
Age Banding with K-Threshold and Fallback
Given a dataset with an age or DOB field and a policy of 10-year bands with k >= 5 and fallback to 20-year bands When generalization is executed Then each released record contains an age band label matching the policy (e.g., 20-29, 30-39) And no equivalence class defined by {configured quasi-identifiers including age band} has size < 5 And for any classes failing k, the age band is widened to the configured fallback until k is met or the max band width is reached And the evaluation report lists banding parameters, counts per band, number of widened bands, and flags any bands still violating k
Location Generalization: ZIP5 to ZIP3/County with Text Consistency
Given records with ZIP5 and NLP-extracted location mentions and a policy ZIP->ZIP3 with fallback to county and k >= 5 When generalization runs Then all structured ZIP5 values are converted to ZIP3 And NLP-extracted ZIPs, city names, and county references in free text are replaced to match the structured generalization And ZIP3 equivalence classes with size < 5 are generalized to county per policy And no generalized value crosses state boundaries incorrectly And the evaluation report includes counts of ZIP5->ZIP3 conversions, ZIP3->county escalations, and any residual violations
VIN Truncation and License Plate Masking
Given records containing 17-character VINs and license plates and a policy to retain VIN positions 1-11 and mask positions 12-17 with 'X', and to retain first 2 plate characters and mask the remainder When generalization executes Then each VIN output has positions 12-17 replaced with 'X' and positions 1-11 unchanged And each license plate shows only the first 2 characters; the rest are replaced with 'X' preserving original length And any VIN or plate mentions in free text follow the same masks And the evaluation report lists counts of VINs and plates masked and shows 0 unmasked occurrences via pattern scans
Geohash Precision Reduction with K-Safe Cells
Given latitude/longitude fields and a policy precision p=5 with k >= 10 and a minimum precision floor p=3 When geohash generalization runs Then all points are encoded to geohash precision 5 And for any geohash cell with count < 10, precision is reduced iteratively (p-1) until count >= 10 or p=3 And no cell below the precision floor is further reduced; such cells are flagged in the report And the report lists the precision distribution, count of escalations, and number of cells failing to meet k at the floor
Currency Rounding and Bucket Aggregation
Given monetary fields with a policy to round to the nearest $100 and bucket into [$0-99], [$100-199], ... with k >= 5 on buckets When generalization is applied Then each monetary value is rounded to the nearest $100 and assigned the correct bucket label And the absolute per-record rounding error is <= $50 And bucket equivalence classes meet k >= 5; otherwise adjacent buckets are merged per policy until k is met And ordering of buckets preserves original order for monotonic analyses And the evaluation report includes rounding parameters, bucket merges performed, and counts per final bucket
Rare Category Grouping with NLP Alignment
Given categorical fields and NLP-extracted categorical mentions and a policy to group categories with global frequency < 20 into 'Other' When generalization runs Then any category with global frequency < 20 is replaced by 'Other' across structured fields And corresponding mentions in free text are replaced with 'Other' consistently And the final 'Other' frequency is reported; if 'Other' exceeds 40% of the field, a utility-loss warning is included And no original rare category labels appear in the released dataset or documents
Residual Risk Evaluation Report and API Delivery
Given a completed generalization run and a dataset identifier When the evaluation report is generated Then the report includes per-field transformations applied, k-anonymity metrics (min/median/max equivalence class size) across configured quasi-identifiers, counts of policy escalations/fallbacks, and a residual risk score on a 0-1 scale with interpretation bands And the report is available as JSON via API and as a downloadable PDF within 2 minutes for datasets up to 1M rows And the report includes the dataset ID, policy version, run timestamp (UTC), and a content hash for integrity And any residual k-violations are enumerated with field combinations and counts
Watermark and Proof Seal Embedding
"As outside counsel, I want tamper-evident, watermarked documents so that I can trust the integrity of the files and trace any leaks to a recipient."
Description

Applies recipient-specific visible watermarks (recipient, package ID, timestamp) to rendered outputs and embeds a cryptographic Proof Seal (content hash + signature) in document metadata. Generates a verification QR/link that resolves to a ClaimFlow endpoint to confirm authenticity and detect tampering by recomputing hashes. Supports PDFs and images, preserves text searchability, and records seal fingerprints in an immutable log for later verification. Watermark styles are configurable per template to balance readability and deterrence.

Acceptance Criteria
PDF Watermarking Preserves Text Searchability
Given a source PDF with known textual content and a recipient R123 with package P456 When SafeShare renders the watermarked PDF Then each page displays a visible watermark containing "Recipient: R123", "Package: P456", and a UTC timestamp in the configured format And the watermark appears in the configured style (angle, opacity, font, tiling) for the selected template And a full-text search for a known phrase returns the same number of matches as in the source PDF And copying text from the watermarked PDF does not include watermark text And the PDF opens without errors in standard viewers (e.g., Acrobat, built-in OS viewers)
Image Watermarking and QR Verification Link
Given a JPEG or PNG claim image and a recipient R123 with package P456 When SafeShare renders the watermarked image Then a visible watermark with recipient, package, and UTC timestamp is applied per template style without changing image dimensions or EXIF orientation And a QR code of at least 128x128 px is placed in the configured corner and encodes the verification URL And scanning the QR with a default iOS/Android camera resolves via HTTPS to the ClaimFlow verification endpoint
Proof Seal Embedded in Document Metadata
Given a generated PDF or image output When the Proof Seal is applied Then a content hash of the final rendered bytes (excluding the seal metadata fields) is computed and signed with the system signing key And the hash and signature are embedded in document metadata under the defined ClaimFlow schema (PDF info/XMP for PDFs; XMP for images) And the embedded metadata is readable via standard tools and matches the verification endpoint response
Verification Detects Authentic vs Tampered
Given a sealed document's verification URL When the endpoint recomputes the hash from the supplied file Then it returns "Authentic" with matching fingerprint, signature issuer, and seal timestamp when the file is unmodified And after any byte-level modification to the file (e.g., text edit, pixel change, metadata change), the endpoint returns "Tampered" and shows the computed fingerprint differing from the logged fingerprint And if the file is unknown to the log, the endpoint returns "Unknown"
Seal Fingerprints Recorded in Immutable Log
Given a successful seal creation for package P456 and recipient R123 When the operation completes Then an append-only log entry is created containing package ID, recipient ID, document ID, seal timestamp (UTC), content fingerprint, signature fingerprint, and template ID And the log enforces immutability via hash chaining of entries and rejects updates/deletes with an error And querying the log by package ID, recipient ID, or document ID returns the corresponding entry and its chain proof
Template-Specific Watermark Styles Applied
Given two document templates with different watermark style configurations When outputs are generated from each template Then the visible watermark in each output exactly matches its template configuration for angle, opacity, font, color, placement, and tiling density And updating the style in one template does not affect outputs produced from other templates And if a template lacks a style configuration, a safe default style is applied and the event is logged
Role-Scoped Share Package Builder
"As a claims supervisor, I want predefined share templates by recipient type so that staff consistently share only what’s needed with minimal setup and fewer errors."
Description

Enables creation of package templates that expose only the minimum necessary fields and artifacts for each external role (e.g., body shop, SIU, defense counsel, ML trainer). Templates define included data types, redaction level, generalization settings, watermarking, link expiration, download limits, and revocation behavior. Integrates with ClaimFlow RBAC to ensure only authorized internal users can generate and send packages, and with workflow automation to auto-route packages to recipients or queues. Provides a final review screen and policy compliance checklist before publishing.

Acceptance Criteria
Create Role-Scoped Template With Minimum Necessary Fields
Given I am an internal user with Template Manager permission and select role "Body Shop" When I create a template Then I can include only permitted data types and artifacts for that role and the system prevents adding prohibited fields Given redaction level and generalization settings are configured When I save the template Then the template stores those settings and shows a summary of included items and privacy settings Given policy rules define minimum necessary for the role When I attempt to include fields beyond allowed scope Then a blocking validation error lists offending fields and save is disallowed
RBAC Enforcement for Package Generation and Sending
Given I am an internal user without Share:Generate permission When I attempt to generate a package from any template Then the action is not available or returns a 403 and no package is created Given I have Share:Generate but not Share:Send When I generate a package Then I can preview internally but cannot send to external recipients Given I have both permissions When I generate and send a package Then the event is recorded with my user ID and role
Watermarking and Proof Seal Hash Application
Given a template has watermarking enabled and Proof Seal hashing required When I generate a package Then all included documents and images are stamped with the configured watermark text and placement and a Proof Seal manifest with hashes is included Given a recipient downloads a document When its hash is recomputed Then it matches the Proof Seal manifest Given watermarking is disabled in a template When I generate a package Then no watermark appears and the Proof Seal is included only if enabled
Link Expiration, Download Limits, and Revocation
Given a package is sent with a 7-day expiration and 3-download limit When the recipient accesses it Then the link is valid until exactly 7 days after send and is inaccessible after either 3 completed downloads or expiration, whichever occurs first Given an internal user revokes the package When the recipient tries to access the link Then access is immediately blocked with a revocation message Given downloads occur When I view audit logs Then timestamps, IP, user-agent, and counts are recorded per attempt
Final Review Screen and Compliance Checklist Gate
Given I am about to publish a package When the final review screen loads Then it displays a checklist of policy requirements derived from the template and data content, and all blocking items must be acknowledged or resolved before Publish is enabled Given the package contains PHI or PII beyond role scope When I attempt to publish Then the checklist shows a blocking item and Publish remains disabled until the item is removed or justified with a required approver Given I complete all required acknowledgements and approvals When I click Publish Then the system records the checklist state and approver identity in the audit trail
Consistent Pseudonymization Across Claims and Packages
Given tokenization is enabled for the tenant When I generate packages from different claims containing the same person or entity Then the same pseudonym appears consistently across packages for that tenant within the configured stability window Given a re-identification secret is rotated per policy When I generate new packages Then prior pseudonyms remain stable as configured and new packages use the new secret without breaking cross-package consistency within the stability window Given I download multiple artifacts in one package When I inspect identifiers Then no direct identifiers appear and generalized values meet configured thresholds
Workflow Automation Auto-Routing and Delivery
Given a workflow rule is configured to auto-route SIU packages to the SIU Intake queue When a package is generated from an SIU template Then it is automatically routed to that queue and a notification is sent to the queue owners Given a template has predefined recipient vendors When a package is published Then secure links are sent to those recipients and delivery success or failure is tracked Given an automation run fails due to a missing recipient address When the package is generated Then the system flags the package for manual assignment with a clear error and no partial notifications are sent
De-ID Audit Trail and Evidence
"As a privacy officer, I want a detailed, immutable audit of de-identification actions so that I can demonstrate compliance and investigate incidents without accessing raw PII/PHI."
Description

Captures an immutable, searchable log of every de-identification run, including policy template version, fields transformed, pseudonymization scope, date shift parameters, generalization rules, Proof Seal fingerprints, actor, time, and source-to-output lineage. Supports exportable evidence bundles for legal/regulatory review and integrates with SIEM for monitoring. Provides in-app audit views and APIs to query by claim, package, recipient, or time window, enabling traceability and compliance reporting without exposing sensitive source data.

Acceptance Criteria
Immutable Audit Log Entry Creation
Given a de-identification run completes successfully When the run finalizes Then an audit log entry is appended with fields: run_id, actor_id, actor_type, tenant_id, start_time, end_time, policy_template_id, policy_template_version, pseudonymization_scope, date_shift_parameters, generalization_rules, fields_transformed[name, source_path, method, parameters], source_object_ids, output_object_ids, proof_seal_fingerprint, previous_log_hash, current_log_hash And the log entry is immutable (write-once) via all APIs and UIs And any update/delete attempt returns HTTP 403 with reason "immutable" And current_log_hash = SHA-256(previous_log_hash || canonical_entry_json) verifies for the entry
Proof Seal Fingerprint Verification
Given an exported de-identified package and its stored proof_seal_fingerprint When a verifier recomputes the fingerprint over the package contents using the documented algorithm Then the computed fingerprint equals the stored proof_seal_fingerprint And modifying any file in the package produces a different fingerprint And the verification API/CLI returns status "valid" and references the related run_id
SIEM Event Streaming (No PHI/PII Leakage)
Given SIEM integration is configured with destination and credentials When a de-identification run starts and completes Then start and completion events are delivered to the SIEM within 60 seconds p95 with at-least-once delivery and an idempotency key And payloads contain only allowed metadata (run_id, timestamps, actor_type, policy_template_version, item_counts_by_category, proof_seal_fingerprint, severity, status) and no raw source values or PII/PHI And failed deliveries are retried with exponential backoff up to 10 attempts and generate an alert on final failure And SIEM events can be correlated back to the audit log via run_id
Evidence Bundle Export for Legal Review
Given a user with Compliance Reviewer role requests an evidence bundle for a specific run or claim When the export is generated Then the bundle includes: JSON audit record, human-readable PDF summary, proof seal artifact, SIEM event references, transformation catalog, lineage map, timestamps, and signer identity And the bundle excludes raw source data and direct identifiers; any example values are masked or tokenized And the export is generated within 30 seconds for runs up to 10k records and provided via a time-limited signed URL (24 hours) And the bundle conforms to schema evidence_bundle.v1 and passes validation
In-App Audit Views and Query APIs
Given an authorized user accesses audit views or APIs When filtering by claim_id, package_id, recipient_id, and time window with pagination and sorting Then only matching audit entries are returned with 200 status and correct total counts And responses contain metadata only; any sensitive source values are masked or omitted per policy And 95% of queries over up to 100k entries complete within 2 seconds And unauthorized access returns 403 and all access is itself audited
Source-to-Output Lineage Traceability
Given a pseudonym/token from a de-identified output When the user requests lineage for that token Then the system returns source_object_id, source_field_path, transformation method, parameter summary, and run_id without revealing the original value (only masked preview) And a lineage graph is viewable in-app and downloadable as JSON, both referencing the audit entry id And lineage coverage is present for 100% of transformed fields within the run
Pseudonymization Scope Recording and Consistency
Given a policy defines pseudonymization scope (e.g., per-claim, per-dataset, per-tenant, global) When multiple de-identification runs occur across entities in and out of that scope Then each audit entry records the scope and scope_id And pseudonyms are consistent within the declared scope and differ across out-of-scope entities And a scope consistency report can be generated; any discrepancy > 0 triggers a Failed check and emits a SIEM alert

Purpose Lock

Enforces purpose limitation end‑to‑end. Each access and export is checked against declared purpose and consent scope; off‑purpose actions prompt justification, auto‑redact, or are safely blocked. Clear in‑UI purpose banners keep teams aligned, while auditors get a defensible record of compliant use.

Requirements

Purpose Declaration & Scope Registry
"As a privacy admin, I want to define and attach data-use purposes with scoped data categories to claims so that access is automatically limited to what is necessary."
Description

Provide a central registry for declaring data-use purposes (e.g., Fraud Review, Coverage Determination, Payment Processing) with scoped data categories and permitted actions. Enable attaching an active purpose at claim, task, or user-session level, with defaults derived from ClaimFlow workflows and routing rules. Store consent scope, evidence references, effective dates, and jurisdictional constraints. Support versioning, API/SDK for programmatic updates, and mapping purposes to ClaimFlow’s NLP-derived data tags so evaluations are precise. Surface the active purpose to downstream components (gatekeeper, redaction, export) and expose a reliable source of truth used across UI, services, and integrations.

Acceptance Criteria
Create Purpose With Scoped Data And Actions
Given tenant ACME and an admin with Purpose:Manage When they POST /purposes with name "Fraud Review", permittedActions ["view","export"], dataCategories ["PII","Financial"], tagMappings ["person.name","bank.account"], consentRequirements ["claimant","thirdParty"], effectiveDateStart=T0 Then the API responds 201 with id (UUIDv4), version=1, and echoes stored fields And the purpose name is unique per tenant; duplicates return 409 PURPOSE_NAME_CONFLICT And all tagMappings are validated against the NLP taxonomy; unknown tags return 422 INVALID_TAG with the offending tag listed And GET /purposes/{id} returns the created record with ETag And an audit record exists with action=create, actor, timestamp, and payload hash
Update Purpose Versioning And Deprecation
Given an existing purpose id=P with version=1 When an editor updates permittedActions to include "export_redacted" and sets effectiveDateStart=T1 Then version=2 is created and version=1 remains read-only And GET /purposes/{id}?latest=true returns version=2 And attempts to modify version=1 return 409 IMMUTABLE_VERSION And deprecating version=2 sets deprecatedAt and deprecationReason and prevents new attachments when latest=true And GET /purposes/{id}/versions/compare?from=1&to=2 returns the field-level diff
Attach Active Purpose At Claim, Task, And Session
Given a workflow rule sets defaultPurpose="Coverage Determination" for new auto claims When claim C123 is created Then claim C123 stores activePurpose {purposeId, version, effectiveAt, source="workflow"} = "Coverage Determination" And when task T1 "Payment Processing" is spawned, T1's activePurpose = "Payment Processing" and the claim-level purpose remains unchanged And when user U opens T1, the UI banner and context API show activePurpose="Payment Processing" And updating T1's activePurpose to "Fraud Review" via PUT emits a PurposeChanged event and updates the session context within 2 seconds And GET /claims/C123/active-purpose and GET /tasks/T1/active-purpose return the persisted attachments
Consent Scope And Jurisdiction Constraints Stored And Resolved
Given consent evidence E1 allows dataCategories ["PII"] for purposes ["Coverage Determination"] in jurisdiction "EU" effective [2025-01-01, 2025-12-31] with evidenceUrl When POST /consents stores E1 linked to claim C123 and subject S1 Then GET /consents?claimId=C123 returns E1 with normalized scope and jurisdiction And GET /effective-scope?claimId=C123&purpose=Coverage%20Determination&date=2025-06-01 returns allow for "PII" and deny for other categories with reason codes And the same call with date=2026-01-01 returns deny with CONSENT_EXPIRED And POST /consents without evidenceUrl returns 400 MISSING_EVIDENCE
Programmatic API/SDK Management With Auth And Validation
Given an SDK client with API key K scoped to tenant ACME and role Purpose:Manage When the client creates, updates, and deprecates purposes via SDK/API Then requests are HMAC-signed and authorized; failures return 401 UNAUTHENTICATED or 403 UNAUTHORIZED appropriately And bodies are schema-validated; unknown/extra fields return 400 SCHEMA_VALIDATION_ERROR with JSON pointer paths And rate limits enforce 100 requests/min per key; violations return 429 with Retry-After And POST /purposes honors Idempotency-Key; retries return the original resource without duplication
Source Of Truth Surfaced To Downstream Services
Given gatekeeper, redaction, and export services need active purpose context for task T1 When they call GET /context/active-purpose?taskId=T1 Then response includes purposeId, version, consentEffectiveScope, jurisdiction, and tagMappings consistent with the registry And p95 latency <= 100 ms in-region at 100 RPS And ETag/If-None-Match returns 304 when unchanged And changes to T1's active purpose are visible via the endpoint within 3 seconds And using a stale version in requests returns 409 VERSION_CONFLICT
Purpose-To-Tag Mapping Precision And Drift Handling
Given NLP taxonomy deprecates tag "person.name" in favor of "party.name" When a purpose references a deprecated tag Then the create/update returns 422 DEPRECATED_TAG and suggests the replacement tag when available And POST /purposes/remap-tags supports dry-run returning a proposed diff without changes And executing remap creates new purpose versions with updated mappings; prior versions remain retrievable And GET /purposes/{id}/tag-mappings returns only non-deprecated tags for the latest version
Access Gatekeeper with Just-in-Time Checks
"As a claims manager, I want the system to check each data access against the active purpose and consent so that my team avoids off-purpose viewing or editing."
Description

Introduce a policy enforcement point that intercepts every read, write, search, and export across UI and API layers and evaluates them against the active purpose, consent scope, user role, jurisdiction, and data category. Implement a central decision service (policy decision point) with outcomes to allow, auto‑redact, require user justification and optional approver sign-off, or block safely. Capture justification notes, approver identity, and timestamps, and write them to the audit trail. Ensure low-latency decisions via caching and pre-computed purpose scopes, with fail-safe deny on uncertainty. Provide complete coverage for bulk operations, attachments, and third-party integrations so off‑purpose actions are consistently controlled end‑to‑end.

Acceptance Criteria
Write/Update Blocked Outside Purpose Scope and Jurisdiction
Given a user with role Adjuster and active purpose "Claims Intake" with consent excluding medical_notes and jurisdiction US-CA When they attempt to update a claim note categorized as medical_notes via UI or API Then the Gatekeeper invokes the PDP, receives decision "block", and the write is not persisted (0 bytes stored) And the user sees a standardized block message citing "Outside purpose/consent/jurisdiction" And an audit event is recorded with userId, role, purposeId, consentRef, jurisdiction, dataCategories=["medical_notes"], action="write", decision="block", timestamp, correlationId And p95 decision latency <= 60ms
API Export Auto-Redacts Off-Purpose Fields
Given an API client with active purpose "Loss Triage" and consent allowing contact_info only When requesting a CSV export that includes driver's_license and ssn fields Then the PDP returns decision "auto-redact" and the exported file contains token "***REDACTED***" for each off-purpose field and no original values And the response metadata includes redacted_field_count And an audit event records ruleId(s), redacted_fields list, decision="auto-redact", timestamp, correlationId And p95 decision latency for each export page <= 100ms
Off-Purpose Read Requires Justification and Approver Sign-Off
Given a user with role Supervisor and active purpose "Fraud Review" where consent excludes medical_notes but policy permits "justify+approve" for that category When the user attempts to view medical_notes in the UI Then a justification modal is shown requiring at least 20 characters before submission And upon submission an approver is notified; until approval no data is displayed And upon approval access is granted for this record and category only for a maximum of 2 hours; after expiry a new approval is required And the audit trail stores justification text, requesterId, approverId, decision timestamps (requested, approved/denied), and expiryAt And p95 decision latency for approved access <= 70ms with cache hit rate for purpose scopes >= 90%
Fail-Safe Deny on PDP Unavailability or Policy Ambiguity
Given the PDP is unreachable, times out, or returns an "uncertain" decision due to ambiguous policy or missing purpose When any read, write, search, or export is attempted Then the system defaults to decision "deny"; no data is returned and no side effects occur And the user sees a message citing "Fail-safe deny" And an audit event logs deny_reason ("pdp_unavailable"|"timeout"|"policy_ambiguous"), error details, and correlationId And stale cached "allow" decisions are never applied when TTL is exceeded
Bulk Search and Batch Read Enforcement Per-Record
Given a bulk search that returns 10,000 claims spanning multiple jurisdictions and data categories When assembling paginated results (pages of 500 records) Then the PDP is evaluated per record and data category; only permitted fields are returned per record and off-purpose fields are redacted or records excluded per policy And p95 decision latency per 500-record page <= 150ms and overall throughput >= 1,000 decisions/second with CPU utilization < 70% And the audit includes a batch summary (allowed_count, redacted_count, blocked_count) and retains per-record events addressable by correlationId
Attachment and Media Downloads Enforced with Redaction and Blocking
Given a request to download claim attachments (JPEG, PNG, PDF) that may contain sensitive data categories outside consent When the user requests original or thumbnail via UI or API Then the PDP decision is enforced; attachments are blocked or auto-redacted (e.g., blurred regions or pages removed) per policy; thumbnails follow the same decision And presigned URLs/CDN tokens require decision validation, expire within 5 minutes, and cannot bypass enforcement And the audit records attachmentId, contentHash, transformation ("blocked"|"blurred"|"pages_removed"), decision, and timestamp
Third-Party Integration/Webhook Enforcement and Scrubbing
Given an outbound webhook to a third-party integration (e.g., CRM) is triggered on claim update When the payload includes fields outside the current purpose, consent scope, or jurisdiction Then off-purpose fields are removed or tokenized before dispatch and headers include purposeId and decisionId And if the third party calls back to fetch off-purpose data via API, the request is denied or redacted consistently And the audit records integrationId, payload schema version, removed_fields list, decision, timestamps, delivery status, and correlationId
Dynamic Auto‑Redaction
"As an adjuster, I want sensitive fields and images auto-redacted when not needed for my purpose so that I can work efficiently without risking non-compliant exposure."
Description

Deliver policy-driven, context-aware redaction at field, document, and image levels that activates when requested data is not required for the current purpose or consent scope. Use ClaimFlow’s NLP-derived classifications and pattern libraries to mask PII/PHI and sensitive loss details; apply computer vision to blur faces, plates, and addresses in photos. Support preview and one-time unmask flows with justification and optional approval, scoping unmask visibility to the requesting session only. Persist redaction markers and lineage so that subsequent views and exports honor the same decisions. Provide developer hooks to extend redaction rules and enable human-in-the-loop corrections where ML confidence is low.

Acceptance Criteria
Auto-redact disallowed PII fields on claim view by purpose and consent
Given a claim contains fields SSN, DOB, and Address classified via NLP And the active purpose is "Initial Triage" with consent scope excluding SSN When a Claims Adjuster opens the claim in ClaimFlow Then SSN is masked with a visible [REDACTED:SSN] token and a tooltip explains the policy reason And a persistent in-UI purpose banner shows "Purpose: Initial Triage" and "Auto-redacted: SSN" And redaction is applied within 500 ms of view initiation for 95% of requests And an audit log entry is recorded with purpose ID, consent scope ID, data items redacted, timestamp, and user ID
Pattern-based PII/PHI redaction in uploaded documents
Given an uploaded PDF includes patterns matching SSN, bank account, and email And the active purpose excludes financial identifiers When the document is processed for viewing or export Then all matched spans are replaced with [REDACTED:<type>] while preserving text flow and page layout And a Redaction Preview control allows toggling show/hide without persisting unmask And the exported PDF contains the same redactions with vector text removed for redacted spans And an audit log entry lists counts per redaction type and document checksum
Computer vision redaction of faces, license plates, and addresses in photos
Given a photo in the claim shows people, a vehicle plate, and a house number And the active purpose excludes identity disclosure When the photo is opened in the viewer Then faces, license plates, and house numbers detected with confidence >= 0.80 are blurred with a Gaussian blur radius >= 12px And detections with confidence < 0.80 are flagged as "Needs Review" and outlined for user confirmation And users can adjust or add boxes in Preview and the final view/export reflects the confirmed boxes And the original image is preserved unmodified in storage with redactions applied as an overlay at render/export time
One-time unmask with justification, optional approval, and session scope
Given a user requests to view a redacted SSN during "Initial Triage" And policy requires justification and supervisor approval for SSN unmask When the user submits a justification of >= 15 characters and a supervisor approves within 30 minutes Then the SSN is unmasked only for the requester’s current session and re-redacted after 15 minutes of inactivity or session end And all other users and sessions continue to see the SSN redacted And an audit trail records requester, approver, justification text hash, TTL, data item IDs, and purpose at time of unmask
Persisted redaction markers honored in subsequent views and exports
Given redaction markers were created automatically and corrected by a reviewer When the same claim is reopened or exported to PDF, CSV, or via API Then the same redaction markers are applied consistently across channels with stable redaction IDs And one-time unmask decisions are not persisted beyond the initiating session And lineage metadata captures rule/model version, confidence score, and user override references and is retrievable via audit API
Developer hook to extend redaction rules with custom policy
Given a developer registers a custom redaction rule via the SDK with priority=90 to mask claim numbers matching regex CF-[0-9]{8} And the feature flag purpose_lock.custom_rules is enabled for the environment When a document containing CF-12345678 is processed Then the custom rule executes in the configured order, masks the match as [REDACTED:CLAIM_ID], and emits a lineage entry with rule ID and version And disabling the feature flag stops the rule from executing without affecting built-in rules And a sandbox test endpoint returns the matched spans and actions for the custom rule
Human-in-the-loop corrections for low-confidence ML detections
Given ML identified three candidate redactions with confidences 0.62, 0.77, and 0.91 And the review threshold is set to 0.80 When the reviewer opens the Redaction Review panel Then the 0.62 and 0.77 items are presented for confirmation, the 0.91 item is auto-applied And the reviewer can confirm, reject, or draw new redaction regions and see changes reflected immediately in the preview And confirmed/rejected decisions update redaction markers and are honored in exports And optional feedback artifacts (before/after snippets and labels) are appended to a training dataset without altering the live model
Export Control & Watermarked Evidence
"As a compliance officer, I want all exports to be purpose-checked and watermarked so that off-purpose sharing is prevented and compliant exports are traceable."
Description

Apply purpose and consent checks to all exports (download, print, email, SFTP, API). Enforce destination restrictions and data minimization rules; block off-purpose exports or route them to an exception workflow with justification and approval. Automatically watermark exported artifacts with purpose, claim ID, user, timestamp, and environment, and embed machine-readable metadata (e.g., JSON sidecar) for audit correlation. Generate expiring, access-scoped links and revoke access upon purpose or consent changes. Attach an export receipt to the claim record so auditors can reconstruct what was shared, why, and under which authority.

Acceptance Criteria
Unified Export Gate Across Channels and Destinations
Given a user initiates an export via download, print, email, SFTP, or API And the claim has a declared processing purpose and consent scope When the export request is created Then the system evaluates the request against the purpose and consent scope before any data leaves the system And if aligned, the export proceeds; if misaligned, the request is blocked or routed to the exception workflow with a unique export_id And destination restrictions are enforced: email recipients must match approved domains, SFTP targets must be allowlisted, API/webhook endpoints must be registered, and print requires an authenticated session And every gate decision is logged with export_id, policy_version, evaluator outcome, and timestamp_utc And attempts to invoke export endpoints without passing the gate return 403 and are logged
Data Minimization and Auto-Redaction on Export
Given a selected purpose with a defined minimal dataset and the current consent scope When the user prepares an export Then only fields permitted by purpose+consent are included by default And attempts to add out-of-scope fields either trigger auto-redaction or require routing to the exception workflow And the user is shown a pre-export preview that visually flags redacted fields and excluded sections And the generated artifacts contain no out-of-scope data, verified by comparing fields_included to the active policy And all redactions and exclusions are recorded in the export metadata for audit
Off-Purpose Exception Workflow with Justification and Approval
Given an export request fails purpose/consent or destination validation When the user provides a justification and submits for approval Then the request routes to an approver defined by policy with a time-bound SLA And approval or rejection requires a reason code and is recorded with approver_id and timestamp_utc And upon approval, the export proceeds only within the approved override scope and validity window; outside that window it is blocked And upon rejection or SLA expiry, the export is blocked with a clear error to the requester And no off-purpose export can proceed without a recorded justification and approver decision
Visible Watermarking on Exported Artifacts
Given an export is approved and generated When artifacts are produced (PDF, images, spreadsheets, and printed outputs) Then a visible watermark appears on every page or image containing: purpose, claim_id, export_id, user_id, user_display_name, timestamp_utc (ISO 8601), and environment And for CSV/XLS, a first-row banner includes the same watermark text And saving, printing to PDF, or rasterizing preserves the watermark And watermark values exactly match the export metadata and are legible without obscuring content
Machine-Readable Export Metadata Sidecar
Given an export has been generated When finalizing the export package Then a JSON sidecar named {export_id}.json is created and stored with the artifacts And it includes: export_id, claim_id, purpose_id, purpose_name, consent_scope_version, user_id, user_email, role, timestamp_utc, environment, destination_type, destination_identifier, fields_included, fields_redacted, policy_version, approval_id (nullable), link_id (nullable), and an array of artifacts with filenames, sizes, and SHA-256 hashes And computed hashes in the sidecar match the exported files And for API exports, the same metadata is also returned in the response body or headers for correlation
Expiring, Access-Scoped Share Links with Dynamic Revocation
Given a user generates a share link for an export When the link is created Then it has an explicit expiry (default 7 days, min 1 hour, max 90 days) and a defined scope of allowed artifacts, fields, and optional IP/recipient constraints And each access is token-validated or authenticated and logged with access_id, timestamp_utc, and client_ip/user_agent And if purpose/consent changes or an approval is revoked, the link is invalidated within 60 seconds And subsequent access attempts return HTTP 403 with error code PURPOSE_SCOPE_REVOKED and are logged And link renewal requires revalidation against the current purpose and consent scope
Export Receipt Attached to Claim Record
Given an export completes, is blocked, or is revoked When the outcome is determined Then an export receipt is attached to the claim record within 5 seconds And it includes: export_id, status (proceeded/blocked/revoked), initiator identity, justification (if any), approver details (if any), purpose and consent snapshot, destination details, artifact list with hashes, link details (if any), and timestamps And the receipt is immutable to end users, versioned for system updates, and shows a full audit trail of approvals, accesses, revocations, and expirations And users with Auditor permissions can retrieve the receipt and associated sidecar from the claim timeline
In‑UI Purpose Banner & Context Indicators
"As an adjuster, I want a clear on-screen banner showing the active purpose and what data is permitted so that I understand boundaries while processing a claim."
Description

Provide a persistent, unobtrusive banner that displays the active purpose, consent scope, permitted data categories, and any expirations or geographic constraints. Add field-level indicators that explain why data is visible, masked, or blocked, with tooltips that reference the governing rule. Include a permissioned purpose switcher that triggers re-evaluation by the gatekeeper and re-renders the UI accordingly. Surface warnings before users initiate actions that exceed scope, and ensure mobile-responsive layouts for adjusters in the field. All indicators should consume the same registry and decision service so UX reflects authoritative policy outcomes in real time.

Acceptance Criteria
Persistent Purpose Banner is Accurate and Unobtrusive Across Devices
Given a user opens a claim view with an active purpose, when the UI loads, then a persistent banner is displayed at the top containing: Active Purpose name, Consent scope summary, Permitted data categories, Expiration (date/time or countdown), and Geographic constraints. Given a desktop viewport (≥1024px), when the banner renders, then its height is ≤56px and it does not overlap or obscure primary navigation or claim content. Given a tablet/mobile viewport (320–768px), when the banner renders, then it collapses to a single-line summary with an expand/collapse control that reveals full details on tap, and it remains readable without horizontal scroll. Given the active purpose, consent scope, or constraints change, when the change event is received, then the banner updates within 1 second and reflects the latest values from the decision service. Given accessibility requirements, when the banner renders, then all text meets WCAG AA contrast, the expand/collapse control is keyboard-accessible, and the purpose content is announced via ARIA labels.
Field-Level Indicators Explain Visibility, Masking, or Blocking with Rule References
Given a data field is allowed by policy, when it is rendered, then a visible-state indicator (icon/badge) appears with a tooltip that states "Visible" and cites the governing rule ID/name and decision timestamp. Given a data field is masked by policy, when it is rendered, then the field shows a standardized placeholder (e.g., "Redacted"), a masked-state indicator appears, and the tooltip explains the masking reason with rule ID/name and consent reference. Given a data field is blocked by policy, when it is rendered, then the field value is not shown, a blocked-state stub appears (e.g., "Not available due to purpose restrictions"), and the tooltip cites the governing rule ID/name. Given a user copies or exports on-screen values, when a field is masked or blocked, then the copied/exported content remains masked or excluded consistently with the on-screen state. Given the decision service returns updated visibility for a field, when the UI receives the update, then the indicator and tooltip reflect the new state within 1 second.
Permissioned Purpose Switcher Triggers Re-Evaluation and UI Re-Render
Given a user without the Purpose.Switch permission, when viewing the banner, then the purpose switcher control is not visible or interactable. Given a user with the Purpose.Switch permission, when opening the purpose switcher, then only purposes authorized for the user and the current claim context are listed, each showing scope summary and expiration. Given the user selects a different purpose, when the selection is confirmed, then the client calls the gatekeeper decision service with user, claim, and purpose identifiers and awaits the response before rendering. Given a successful decision is returned, when the UI applies the result, then the banner, field indicators, and available actions re-render consistently with the decision within 1,000 ms at p95, and any previously visible off-scope data is immediately masked or hidden. Given the decision service denies the purpose change, when the user attempts to switch, then the UI shows a non-intrusive error explaining the denial and makes no state changes.
Pre-Flight Warnings for Actions That Exceed Purpose or Consent Scope
Given an action (e.g., export, share, print, bulk copy) would include data categories outside the active scope, when the user initiates the action, then a pre-flight modal warns of the scope exceedance and lists the flagged data categories and governing rule(s). Given policy permits justification, when the user proceeds, then a justification text field (min 10 characters) is required, the justification is captured, and the action proceeds only if allowed by policy and with any required auto-redactions applied. Given policy requires redaction, when the user proceeds, then a preview lists fields to be redacted and the resulting artifact excludes/redacts those fields upon confirmation. Given policy blocks the action, when the user opens the modal, then the proceed/confirm control is disabled and only Cancel/Close is available. Given the user attempts to bypass the modal via deep link or keyboard shortcut, when the action would exceed scope, then the same pre-flight enforcement is applied before any data leaves the UI.
Single Source of Truth: UI Components Consume the Same Registry and Decision Service
Given the banner, field indicators, and pre-flight checks initialize, when they request policy, then all call the same configured registry and decision service endpoint and include the same context (user, claim, purpose, consent). Given a standardized test policy response set, when injected, then the banner content, field-level states, and pre-flight outcomes are consistent with each other and match the response set exactly. Given client-side caching is enabled, when no change events occur, then cached policy is used for up to 60 seconds; when a purpose or consent change event is received, then the cache is invalidated and fresh policy is fetched immediately. Given policy evaluation latency exceeds 2 seconds, when a user attempts a gated action, then the UI blocks the action, shows a "decision pending" indicator, and resumes only after a decision arrives or times out with guidance. Given an environment misconfiguration (mismatched endpoint) occurs, when the UI attempts a call, then a single error banner is shown and all dependent components enter a safe default (most restrictive) state.
Mobile Field Use and Offline/Degraded Decision Service Handling
Given a mobile viewport (≤768px), when viewing a claim, then the purpose banner collapses into an expandable header and all field indicators are tappable with accessible tooltips. Given the device is offline or the decision service is unreachable, when the user views data or attempts gated actions, then the banner displays "Verification unavailable", fields default to the most restrictive (masked/blocked) state, and gated actions are disabled until verification succeeds. Given connectivity is restored, when the UI detects network availability, then it automatically retries policy evaluation and re-renders components to reflect current decisions. Given an adjuster in the field captures new photos/messages, when those items are added while offline, then they are tagged as "Pending policy check" and are not shareable/exportable until policy evaluation completes. Given the user taps Retry in degraded mode, when a response is received, then the latest decision is applied consistently across banner, indicators, and actions within 1 second.
Immutable Audit Trail & Auditor Portal
"As an auditor, I want an immutable log of purpose evaluations and justifications so that I can verify compliant use during audits."
Description

Create an append-only, tamper-evident log (hash-chained with time synchronization) of all access decisions, purpose changes, justifications, redactions, and exports, including user, device, IP, and context. Provide powerful search and reporting by claim, user, purpose, timeframe, and outcome, along with anomaly flags for frequent or unusual justifications. Enable export of auditor-ready evidence packages and read-only portal access for internal and third-party auditors with scoped permissions. Support retention policies, legal hold, and data subject request fulfillment without breaking integrity of the audit chain.

Acceptance Criteria
Hash-Chained Immutable Audit Log
Given any audited event (access decision, purpose change, justification submission, redaction applied, export initiated/completed) When the event occurs Then a log entry is appended within 100 ms including event_type, event_id, claim_id, user_id, role, device_id, IP, user_agent, purpose_id, consent_scope_id (if present), decision/outcome, timestamp (UTC), and context metadata. Given a new log entry When it is stored Then it includes the SHA-256 hash of its payload and the previous entry’s hash, forming a continuous chain per tenant, and chain validation API returns valid for intact chains. Given an attempt to alter or delete any prior entry When chain validation runs Then integrity failure is detected with index and hash mismatch reported, the write is blocked, and an alert entry is appended. Given NTP time synchronization When sync is healthy Then recorded clock drift is ≤ ±500 ms; When sync is degraded Then drift never exceeds ±2 s and entries are tagged time_sync_status=degraded. Given system restart or shard rollover When a new segment begins Then it starts with an anchor checkpoint signed with the server key and previous segment terminal hash.
Complete Coverage of Purpose Enforcement Events
Given any access or export decision When evaluated by Purpose Lock Then the log captures purpose_id, policy_version, consent_scope_reference, evaluation_result (permit|deny|permit_with_redaction), and justification_id/text (required and ≥10 chars for off-purpose overrides). Given a redaction is applied When content is delivered or exported Then the log records redaction_template_id, redacted_field_count, and content_preview_hash. Given any user session When an audited event is logged Then device_id, IP address, coarse_geolocation, and mfa_status are present and non-null. Given schema validation When processing events Then events missing required fields are rejected with error and no partial entries are written.
Auditor Portal Read-Only Scoped Access
Given an internal auditor with claim-scoped role When signing into the Auditor Portal Then only logs for assigned claims and timeframes are visible, and out-of-scope access returns 403 and is logged. Given a third-party auditor When using the portal Then all write operations (edit, delete, rerun, annotate) are unavailable and attempts are blocked and logged. Given viewing an entry detail When PII/PHI may be present Then content is masked per active redaction policies while metadata remains visible. Given any auditor action (view, search, export) When performed Then the action is logged as an audit_portal event with actor, scope, filters, and timestamp.
Search, Filters, and Reporting Performance
Given ≥1,000,000 log entries in a tenant When searching with combined filters (claim_id, user_id, purpose_id, timeframe, outcome) Then the first page (100 items) returns within 2 seconds with accurate total_count and stable pagination cursors. Given a saved report definition When executed Then output matches the equivalent ad hoc query byte-for-byte and can be exported to CSV and JSON with an embedded query manifest and SHA-256 checksum. Given timezone selection When a user chooses a timezone Then UI and export timestamps render in the selected timezone while stored UTC values remain unchanged.
Anomaly Detection for Justifications
Given a rolling 30-day baseline per user and purpose When a user’s off-purpose justification rate in 24 hours exceeds baseline by >3 standard deviations or ≥10 justifications/day Then an anomaly flag is created within 5 minutes linking user, purpose, and affected claims. Given justification phrase analysis When a phrase outside the top 95% frequency appears ≥5 times within 7 days Then an anomaly is recorded with phrase signature and sample references. Given an anomaly exists When viewed in user or claim context Then an anomaly badge and details are visible; dismissal requires Compliance role, captures reason, and remains in history without suppressing future detections.
Auditor-Ready Evidence Package Export
Given a query that returns up to 50,000 entries When an auditor requests an evidence package Then a bundle is produced within 60 seconds containing entries.json, chain_verification_report.txt, segment_anchor_signatures, ntp_sync_evidence.json, redaction_policy_snapshots, and manifest.json with SHA-256 checksums for every file. Given the generated package When verified offline using the manifest Then all checksums match and chain verification succeeds or a failure report identifies mismatches by file and entry index. Given scoped access for a third-party auditor When exporting a package Then contents are limited to their scope and personal data is redacted per policy with a redaction_summary.json included.
Retention, Legal Hold, and DSAR Integrity
Given a 7-year retention policy When entries expire and are not on legal hold Then cryptographic tombstones referencing purged entries are appended, storage is compacted, and chain validation remains valid with continuity preserved. Given a legal hold on a claim When retention jobs run Then entries for that claim are excluded from purge until hold release, and hold state changes are logged as events. Given a data subject access request When generating subject-scoped audit extracts Then a complete, immutable export is produced within 24 hours without altering original logs, and includes proof-of-completeness metadata.
Consent Sync & Revocation Handling
"As a privacy admin, I want consent updates and revocations to propagate instantly so that ongoing access aligns with the latest consent scope."
Description

Integrate with upstream consent capture systems (policyholder portal, contact center, e-sign, CRM) via APIs and webhooks to ingest grants, updates, expirations, and revocations with signed evidence. Map consent scopes to purposes and data categories, and reconcile jurisdictional requirements. Upon revocation or expiry, propagate changes in real time: invalidate affected sessions, re-mask data, cancel pending off-scope tasks, and notify assignees with next-best actions (e.g., request refreshed consent). Expose consent state in the banner and audit trail so users and auditors can see exactly what authority governs current access.

Acceptance Criteria
Webhook Consent Grant Ingestion with Signed Evidence
Given a valid upstream webhook payload at /integrations/consents/webhook with event_type="grant", unique event_id, consent_id, subject_id, purposes[], data_categories[], jurisdictions[], effective_at, optional expires_at, and a detached signature (algorithm, signer_id, signature, signed_at) When the payload is received Then the signature is verified against the registered source key and the endpoint returns HTTP 200 within 500 ms And a consent record is created or updated within 2 seconds including evidence (raw payload hash, signature, source_system_id) and mapped internal purpose_ids and data_category_ids And an audit entry "consent.grant.ingested" is persisted with actor=source_system_id, event_id, checksum And re-delivery of the same event_id is idempotent (no duplicate records; audit notes "duplicate_ignored") And a payload with missing/invalid signature is rejected with HTTP 400 code "signature_invalid" and no state change
Scheduled API Sync Reconciliation and Jurisdictional Conflict Resolution
Given a scheduled sync job for registered sources (CRM, portal, e-sign) fetching changes via API using changed_since When changes include multiple records for the same subject_id and purpose across jurisdictions or overlapping effective windows Then conflicts are reconciled in the same cycle using rules: latest effective_at wins within a jurisdiction; stricter jurisdictional regime takes precedence across jurisdictions; explicit revocation supersedes any grant And superseded records are marked with superseded_by consent_id and preserved for audit And the sync completes within 2 minutes at p95 for up to 10,000 records with metrics (fetched, created, updated, superseded, failed) and audit "consent.sync.completed" And 4xx responses are logged and skipped; 5xx responses are retried up to 3 times with exponential backoff, then dead-lettered without state change
Scope Mapping to Internal Purposes and Data Categories
Given a maintained mapping table scope_code -> {purpose_ids[], data_category_ids[], jurisdiction} with semantic versioning When ingesting a payload with scopes ["CLAIM_FNOL_PHOTOS", "PERSONAL_DATA", "CA_CCPA"] Then the system resolves the scopes to internal purpose_ids and data_category_ids, attaches jurisdiction(s), and stores mapping_version on the consent record And any unknown or deprecated scope_code is quarantined (no activation), a "consent.mapping.error" audit entry is created, and an alert is emitted And multilingual scope labels (EN, ES, FR) normalize to the same scope_code and pass unit tests And a mapping change does not retroactively alter previously resolved records; only new/updated events use the new mapping_version
Real-Time Revocation and Expiry Enforcement Across Sessions
Given users have active sessions viewing claim artifacts that include data covered only by a consent that will be revoked or has expired When a "revocation" or "expiry" event with effective_at <= now is ingested Then within 3 seconds all active sessions for the affected subject_id re-evaluate entitlements; sessions accessing off-purpose/off-scope data are forced to refresh and re-masked views are rendered And attempts to export or share off-scope data return HTTP 403 with code "consent_scope_blocked" and a correlation_id is logged And the in-UI banner switches to "Consent revoked/expired" with timestamp and a next-best-action link to request refreshed consent And all scheduled exports involving off-scope data are canceled with status "Blocked — Consent" and an audit entry per export
Off-Scope Task Cancellation and Next-Best Action Notifications
Given there are pending workflow tasks that depend on data categories now outside consent scope When a revocation or expiry is processed Then all such tasks transition to "On Hold — Consent Required" within 5 seconds and are linked to the governing consent_id And assigned users receive an in-app notification immediately and an email within 60 seconds containing a templated link to initiate a consent refresh request And if refreshed consent restoring scope is granted, affected tasks auto-resume to the prior status within 5 seconds and an audit "task.auto_resumed" is recorded And if no refresh occurs within 7 days, tasks escalate per configured workflow rules and appear in the Consent Exceptions report
Purpose Banner and Audit Trail Reflect Current Authority
Given a claim workspace is open for a subject_id When consent state changes (grant, update, revoke, expire) Then the purpose banner updates within 2 seconds to display current purpose(s), covered data categories, source system, effective/expiry, jurisdiction(s), and authority status And selecting the banner opens a read-only audit modal listing the last 10 consent events with filters and an export of full history (CSV and JSON) And each audit entry includes payload hash, signature algorithm, signer_id, verification status, event_id, and timestamp And users with role "Compliance" can retrieve the same history via API GET /audit/consents/{subject_id} with rate limits enforced; API results match the UI entries 1:1

RuleSync

Continuously updates redaction and retention rules by jurisdiction (HIPAA, GLBA, GDPR, state regs) with versioning and impact simulation. Test changes in a sandbox, preview what will be masked, and roll out safely. Reduces policy drift and keeps redaction accurate as laws evolve.

Requirements

Automated Regulatory Feed Ingestion
"As a compliance analyst, I want RuleSync to automatically ingest and normalize regulatory updates by jurisdiction so that our redaction and retention policies stay current without manual research."
Description

Continuously pull and normalize regulatory updates (HIPAA, GLBA, GDPR, state DOI bulletins) into a unified schema mapped to jurisdictions, data categories, and document types. Support effective/expiration dates, source provenance (URLs, digests), deduplication, conflict detection, and manual overrides. Schedule daily and on-demand fetches with retry/backoff, notifications on changes, and health monitoring. Integrate with ClaimFlow’s entity taxonomy and NLP extraction to map rules to specific fields/entities for redaction and retention enforcement.

Acceptance Criteria
Daily Scheduled Regulatory Fetch and Normalization
Given the scheduler is configured for 02:00 UTC daily and sources (HIPAA, GLBA, GDPR, state DOI endpoints) are reachable When the daily job executes Then the system fetches all available updates within 10 minutes and logs start/end timestamps. Then each fetched item is normalized into the unified schema with non-null jurisdiction, regulation_id, rule_text, source_url, source_digest, effective_date (nullable allowed), fetch_timestamp, and version. Then 100% of records failing schema validation are rejected with a machine-readable error code and included in the run summary. Then a run audit record is persisted with fetched_count, normalized_count, rejected_count, duration_ms, and job_id.
On-Demand Fetch with Retry, Backoff, and Job API
Given a user calls POST /rulefeeds/fetch with a list of sources When transient network errors occur Then the system retries up to 5 times with exponential backoff (initial 1s, max 60s) and records each attempt. When the request is accepted Then the API responds within 2 seconds with 202 Accepted and a job_id for polling at GET /rulefeeds/jobs/{job_id}. When the job completes successfully Then the job status includes fetched_count, deduped_count, inserted_count, updated_count, skipped_count, and errors=[]. When the job fails after retries Then status=failed and a notification is sent to the configured channel with error_summary and job_id.
Deduplication, Versioning, and Source Provenance
Given an incoming update whose content hash equals an existing source_digest for the same regulation_id and jurisdiction When ingestion runs Then no new version is created; last_seen_at is updated and the item is counted as deduped. Given an incoming update with a new content hash for an existing regulation_id When ingestion runs Then a new version is created with version incremented by 1, linked to the prior version_id, and change_type='content_change'. Then provenance fields source_url, source_digest, retrieved_at, and etag (if provided) are persisted for every ingested item. Then re-running the same job input produces identical state (idempotency verified by identical counts and no duplicate versions).
Effective/Expiration Date Enforcement Semantics
Given a rule with effective_date in the future When ingestion completes Then the rule is stored with status=pending and is excluded from active enforcement until the effective_date in UTC. Given a rule with expiration_date <= now(UTC) When ingestion completes Then the rule is marked inactive and removed from active enforcement while remaining queryable for audit. Given overlapping active versions for the same regulation_id When enforcement compiles Then only the latest version whose effective_date <= now(UTC) and (no expiration_date or expiration_date > now) is selected.
Conflict Detection and Manual Overrides
Given two or more active rules produce contradictory directives for the same {jurisdiction, data_category, document_type} When ingestion finalizes Then a conflict record is created with severity, conflicting_rule_ids, and detected_at. When a manual override is created via POST /rulefeeds/overrides Then enforcement selects the override over conflicting rules and all decisions are traceable with override_id. Then a notification is dispatched to the Compliance role with conflict count and links to resolve; delivery occurs within 1 minute of detection.
Mapping to ClaimFlow Entity Taxonomy and NLP Fields
Given normalized rules with data_category and document_type When mapping executes Then 100% of rules are mapped to at least one ClaimFlow entity field or flagged with status=unmapped and a mapping_reason. When NLP-based mappings produce confidence < 0.8 Then the rule is flagged for review and excluded from automatic enforcement until approved. Then a compiled redaction/retention policy artifact is emitted referencing entity_field_ids for downstream RuleSync with a reproducible policy_hash.
Health Monitoring and Change Notifications
Given the service is running When GET /rulefeeds/health is called Then it returns 200 with component statuses for scheduler, fetcher, normalizer, deduplicator, mapper, and notifier as 'UP' or 'DOWN'. When no successful daily run occurs within 26 hours Then an alert is emitted to on-call with severity=high. When new, updated, or expired rules are ingested Then a change digest is sent to subscribers with counts by jurisdiction and links to diffs before 09:00 in each subscriber's configured timezone.
Versioned Rule Repository & Rollback
"As a product owner, I want versioned rules with safe rollback so that we can quickly revert if a change causes issues."
Description

Maintain a version-controlled repository of redaction and retention rules with semantic versioning, diff views, and full change history. Enforce referential integrity, effective windows, and compatibility checks with the redaction engine and retention scheduler. Provide one-click rollback to prior versions, signed releases, and enforced review gates. Expose an API/CLI for CI/CD promotion across environments while preserving audit trails and approvals.

Acceptance Criteria
Publish New Rule Version with Semantic Versioning
Given a set of rule changes and a draft release When the release is published Then the version must match regex ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$ And Then the version must be greater than any existing version tag in the same environment/branch And Then release notes, change summary, and compatibility flag must be provided And Then the repository enforces unique version tags and rejects duplicates with HTTP 409 And Then pre-release identifiers are allowed only in non-production environments And Then the publish API responds 201 with immutable artifact hash and signature id
Display Rule Diff Between Versions
Given two versions selected When viewing the diff Then the UI displays additions, deletions, and modifications at rule and field level And Then changes to effective windows are highlighted with start/end timestamps and time zone And Then JSON/YAML whitespace-only changes are ignored if semantic diff is selected And Then diffs for up to 5 MB total rules render in <= 2 seconds on a cold load And Then a copy-to-clipboard and export-to-JSON of the diff are available And Then API GET /rules/{id}/diff?from=...&to=... returns 200 with a stable diff schema
Audit Trail Completeness for Rule Versions
Given any published or rolled-back version When retrieving its audit record Then the record includes author, approvers (min 2), timestamps (created/published), commit hash, artifact SHA-256, environment, and change reason And Then the audit event includes the CI/CD pipeline run id and source branch/tag if promoted via API/CLI And Then the audit log is immutable (append-only) and tamper-evident via chained hashes And Then audit records are filterable by date range, jurisdiction, rule type, and actor, returning results within 1 second for up to 50k records And Then exporting the audit log to CSV/JSON for a date range produces a file with a verifiable integrity hash
Validate Referential Integrity and Engine/Scheduler Compatibility
Given a draft rule set When running validation Then any rule referencing a missing redaction pattern, classifier, or dependency is flagged and publishing is blocked And Then a dry-run compile against the redaction engine succeeds with zero errors and <= 50 warnings, else publish is blocked And Then retention scheduler compatibility checks confirm all retention policies have valid durations and actions supported by the scheduler version And Then validation errors return machine-readable codes and human-readable messages with line/offset location And Then the overall validation completes in <= 30 seconds for a rule set of up to 10,000 rules
Enforce Effective Windows and Non-Overlapping Policies
Given rules for the same jurisdiction, data category, and policy key When a new version is staged Then effective windows must not overlap with active windows unless an override flag and approval by compliance role are present And Then effectiveStart must be in the future for staged releases unless performing a rollback And Then time zones are stored as IANA TZ and normalized to UTC in storage And Then the system schedules activation/deactivation precisely at boundary timestamps with no double-application or gaps And Then simulation shows which claims/messages will be affected between dates prior to activation
One-Click Rollback to Prior Signed Version
Given a selected prior version When initiating rollback Then the target environment is atomically reverted to that version and a new audit event is created linking both versions And Then the rollback release is re-signed with the current signing key and the signature is verifiable And Then pre-publish validation and compatibility checks are executed and must pass before rollback is applied And Then the rollback can be simulated to preview masked fields and retention outcomes on a sample dataset And Then total time to complete rollback for up to 5 MB of rules is <= 60 seconds, with zero downtime for read operations
CI/CD Promotion via API/CLI with Review Gates
Given a built release artifact When promoting from Sandbox to Staging or Production via API/CLI Then at least two approvers with the Compliance role must approve within a 7-day window before promotion executes And Then API requires OAuth2/OIDC with scopes rules:promote and enforces environment-level RBAC And Then promotion is idempotent; re-running with the same artifact and target environment yields 200 and no new version tag And Then the API/CLI preserves the original audit trail, including approvals, and appends promotion metadata (actor, timestamp, environment) And Then API latency for promotion requests (excluding approval wait) is <= 500 ms p95
Impact Simulation & Coverage Analytics
"As a claims operations lead, I want to simulate rule changes on real-world samples so that I can predict operational impact before rollout."
Description

Run proposed rule changes against representative datasets to quantify impact before deployment. Compute metrics such as percent of entities/fields redacted, likely over/under-redaction hotspots, retention queue changes, conflicts across jurisdictions, and downstream workflow effects. Provide side-by-side diffs, sample artifacts, and cost/time estimates for reprocessing. Store simulation reports with inputs/assumptions for audit and reuse, and enable threshold-based pass/fail gates for automated promotion.

Acceptance Criteria
Simulation Execution on Representative Dataset with Core Metrics
Given a proposed ruleset version B, a baseline ruleset A, and a representative dataset D (>= 1,000 records or full dataset if smaller), When the user runs an impact simulation, Then the system produces a report containing: (a) % of entities redacted by entity type and jurisdiction, (b) % of fields redacted per schema field, (c) record/document counts affected, and (d) deltas A→B for each metric. And the report includes a unique run ID, input hashes (ruleset IDs, dataset snapshot ID), environment, user, start/end timestamps, and software version. And results are deterministic for the same inputs (metrics variance ≤ 0.1%). And the simulation runs in read-only mode (no mutation to production rules/data). And for datasets ≤ 10,000 records the job completes in ≤ 30 minutes or provides ongoing partial results with a progress indicator updating at least every 5 seconds.
Side-by-Side Diff Preview with Sample Artifacts and Report Archival
Given baseline ruleset A and proposed ruleset B, When viewing results, Then the UI presents side-by-side diffs for at least 50 samples spanning each artifact type present in D (e.g., images, PDFs, messages), highlighting added/removed/moved redactions with per-sample counts. And users can toggle mask overlays on/off and download sanitized previews; raw unmasked content is only viewable by users with the RedactionPreview privilege. And samples are reproducible via a visible seed; users can regenerate with a new seed. And upon completion, the full simulation report (inputs, assumptions, thresholds, metrics, diffs, hotspots, cost estimates) is archived with an immutable report ID, retained ≥ 2 years, and retrievable via UI and API. And users can clone a past report to rerun with updated datasets/parameters; the cloned run links back to the parent and preserves the original unchanged.
Over/Under-Redaction Hotspots Detection and Export
Given the simulation output, When hotspot analysis runs, Then the system lists the top 10 over-redaction hotspots and top 10 under-redaction risk hotspots by magnitude of delta. And each hotspot includes: affected field/entity, jurisdiction(s), delta %, volume affected, and 3+ representative examples with preview. And a heatmap visualization is available in UI and a downloadable CSV/JSON is provided via API. And hotspot results are reproducible for identical inputs and sampling seed. And each hotspot links to the underlying records in the sample or to aggregated counts where records cannot be shown for privacy.
Retention Queue Impact and Downstream Workflow Effects
Given baseline A and proposed B, When retention impact analysis runs, Then the system reports before/after counts and deltas for retention/disposition queues by jurisdiction and policy bucket. And items moving between retention categories are enumerated with counts and example IDs (or masked surrogates) per category. And downstream workflow effects are estimated, including delta counts for manual-review tasks and steps likely to exceed configured capacity thresholds, each flagged with severity. And projected SLA impact is computed with P50/P90 added wait time (days) per queue. And all retention and workflow deltas are exportable as CSV/JSON and included in the archived report.
Cross-Jurisdiction Conflict Detection with Precedence Resolution
Given records with multi-jurisdictional applicability, When conflict analysis runs, Then the system identifies rule conflicts across HIPAA/GLBA/GDPR/state regs and outputs a conflict list with counts by conflict type. And for each conflict the applied precedence rule is shown with citations/IDs of the rule versions and the resulting effective action. And in Strict Mode the number of unresolved conflicts must equal 0; otherwise unresolved conflicts are flagged with severity and blocked by the promotion gate. And the conflict report links to affected record counts and impacted workflow steps, and is available via UI and API.
Cost/Time Reprocessing Estimates with Confidence Bands
Given configured per-record processing time and cost parameters (and historical throughput), When estimation runs, Then the system outputs total compute hours, calendar duration, and dollar cost to reprocess the affected scope. And P50 and P90 ranges are provided using historical throughput; if history < 3 comparable runs, the system falls back to a deterministic linear estimate and notes the fallback. And estimates are cross-checked against the last 3 similar completed runs; deviations > 20% trigger a warning annotation in the report. And all estimates are exportable and included in the archived report.
Threshold-Based Pass/Fail Gate and Promotion Control
Given user-configured thresholds (e.g., max over-redaction delta, max under-redaction risk, max unresolved conflicts, max estimated cost, max SLA impact), When a simulation completes, Then the system evaluates results and sets gate status to Pass only if all thresholds are met; otherwise Fail with reasons listed. And a Pass state enables one-click promotion of ruleset B to the next environment; a Fail state blocks promotion until thresholds are adjusted or results improve. And gate status and reasons are exposed via API and an event is emitted with report ID, environment, and evaluation summary. And an audit log entry captures thresholds, evaluation results, user, timestamp, and environment; manual override requires Admin role and a reason, both logged.
Isolated Sandbox Testing Environment
"As a security engineer, I want a sandbox to test rule updates without affecting production so that we can validate compliance safely."
Description

Provide an environment mirroring production schemas, NLP models, and workflow integrations to safely test rule changes. Seed with anonymized/synthetic data sets, enforce strict data egress controls, and support feature flags for targeted validation. Enable automated test suites for rules (unit/contract tests), ephemeral sandboxes per branch, and one-click promotion to staging after passing checks. Ensure sandbox activity is logged and purgeable for compliance.

Acceptance Criteria
Production Parity Mirror
- Given a sandbox is provisioned, When parity checks run, Then schema checksums match production and NLP model versions equal production's pinned versions. - Given workflow integrations in sandbox, When contract tests execute, Then 100% of endpoints pass with the same request/response shapes as production stubs. - Given production updates schemas/models, When a new sandbox is created after the update, Then it pins to the new production versions unless explicitly overridden by branch config. - Given a sandbox, When parity drift is detected, Then CI fails with a clear report listing mismatched components.
Ephemeral Sandbox Per Branch Lifecycle
- Given a new Git branch is pushed with RuleSync changes, When CI pipeline starts, Then a uniquely named sandbox namespace is created within 10 minutes containing the branch artifacts. - Given subsequent commits to the branch, When CI completes, Then the sandbox is updated atomically without data loss. - Given the branch is merged or deleted, When cleanup job runs, Then the sandbox and all associated secrets, data, and logs are destroyed within 30 minutes. - Given multiple branches, When up to 50 concurrent sandboxes exist, Then resource quotas prevent cross-sandbox interference and all SLAs above are met.
Anonymized/Synthetic Data Seeding and Validation
- Given a freshly created sandbox, When seeding executes, Then only approved anonymized or synthetic datasets are loaded and the PII detector finds 0 unmasked occurrences of SSN, DOB, address, email, or phone in plaintext. - Given jurisdictional coverage needs, When seeding completes, Then the dataset includes at least 1,000 claims spanning HIPAA, GLBA, GDPR, and 10+ state variants with label distribution within ±10% of reference. - Given seeding reports, When validation runs, Then a data provenance report and risk score (< 0.1) are generated and stored in the sandbox logs. - Given seeding detects real production identifiers, When violations > 0, Then the process fails hard and no data is retained.
Data Egress Controls and Isolation
- Given a sandbox workload, When it attempts outbound network connections, Then only allowlisted test endpoints are reachable and all others are blocked and logged. - Given a user in the sandbox UI or API, When export is attempted, Then export is allowed only for users with sandbox-export scope, is redacted per active rules, watermarked "SANDBOX", and rate limited to 100 MB/hour. - Given identities and secrets, When access tokens are issued, Then they are namespace-scoped to the sandbox and cannot access production resources. - Given multi-tenant operation, When two sandboxes run concurrently, Then no data or logs from one are accessible by principals of the other.
Feature Flags for Targeted Validation
- Given a rule change behind a feature flag, When the flag is enabled for a specific user, org, or dataset tag, Then only those targets experience the new behavior; all others follow the default. - Given flag propagation, When a flag value changes, Then the new value takes effect in the sandbox within 60 seconds and is recorded in the audit log. - Given a failure after enabling a flag, When the flag is toggled off, Then the sandbox reverts to the previous behavior without requiring a redeploy. - Given flag definitions, When no targeting is specified, Then the flag defaults to off.
Automated Rule Tests and Promotion Gate to Staging
- Given a commit to a RuleSync branch, When CI runs, Then unit tests and contract tests execute and must pass at 100% with zero critical or high-severity failures. - Given impact simulation, When tests complete, Then a diff report shows counts of masked/unmasked fields by jurisdiction with no unexpected increases in unmasked sensitive fields. - Given PR review, When a reviewer opens the PR, Then a masking preview is available for a standard sample set with side-by-side before/after. - Given all checks pass, When an authorized user clicks "Promote to Staging", Then the ruleset is deployed to staging within 5 minutes with a change ticket generated and a rollback plan captured. - Given checks fail, When promotion is attempted, Then the action is blocked with a list of failing gates.
Audit Logging and Purgeability for Compliance
- Given activity in the sandbox (provisioning, seeding, test runs, flag changes, exports), When events occur, Then logs capture who, what, when, where (IP/device), and correlation IDs and are immutable and searchable within 1 minute. - Given a compliance purge request, When an admin calls the purge API for a sandbox, Then all data and logs are deleted within 15 minutes and a signed certificate of destruction is produced. - Given retention policy settings, When no override is set, Then sandbox logs and data are retained for 30 days and automatically deleted thereafter. - Given access controls, When a user lacks log-read scope, Then they cannot view sandbox audit logs.
Staged Rollout & Scheduling Controls
"As an administrator, I want to schedule and stage rule rollouts so that I can minimize risk and business disruption."
Description

Enable controlled deployment by tenant, region, jurisdiction, and line of business with canary cohorts and time-based activation windows. Support blackout periods, rollback/pause, and optional reprocessing of in-flight claims and stored artifacts. Integrate with ClaimFlow’s workflow engine to scope new rules to new intakes versus historical backfills. Provide real-time rollout dashboards and alerts on anomalies (e.g., spike in redaction deltas).

Acceptance Criteria
Canary Rollout by Tenant, Region, Jurisdiction, and LOB with Time-Window Activation
Given ruleset version vX scheduled with activation window [t_start, t_end] in region R (timezone tzR), jurisdiction J, and line of business L, and a canary cohort size of 5% of tenants When current time t in tzR enters [t_start, t_end] Then only claims from the selected canary tenants in R/J/L are processed with vX, and all other claims continue with vW And claims received at exactly t_start are processed with vX; claims received after t_end are processed with vW And the canary cohort selection is deterministic and stable for the rollout duration and logged with cohort seed and membership And all scheduling, cohort, and version-selection decisions are recorded in an immutable audit log with operator, timestamp, scope, and versions
Enforced Blackout Periods Prevent Activations and Auto-Transitions
Given a configured blackout period [b_start, b_end] for region R (timezone tzR), jurisdiction J, and line of business L When a user attempts to schedule or auto-activate ruleset vX such that the activation window intersects [b_start, b_end] Then the scheduler rejects the request with validation error code BLK-409 and no activation is persisted And any in-progress rollout that reaches b_start is automatically paused within 60 seconds and marked "Paused—Blackout" with next eligible resume time b_end And the dashboard displays the paused rollout with blackout reason and time remaining
One-Click Pause and Rollback with Safe Reversion
Given an active rollout where vX is replacing vW When an operator issues Pause Then no additional claims switch to vX within 60 seconds, and the rollout state changes to "Paused" with a Resume control available When the operator issues Rollback Then all new claims route back to vW within 2 minutes, and a rollback event is written to audit with operator, timestamp, affected scope, and versions And items already mid-processing continue under their originally assigned version with no data loss or partial redactions
Optional Reprocessing of In-Flight Claims and Stored Artifacts
Given a rollout configured with reprocessing=true and scope filters defining in-flight states [Intake, Review] and stored artifacts matching R/J/L When the rollout starts Then all matching claims and artifacts are enqueued for reprocessing under vX within 10 minutes, with retries up to 3 times using exponential backoff on failure And the dashboard reports counts queued, succeeded, failed, and skipped by tenant, region, jurisdiction, and LOB And when reprocessing=false, no existing claims or artifacts are reprocessed; only new intakes after activation use vX
Workflow Scoping to New Intakes vs Historical Backfills
Given scope=new-intakes-only and activation time t_act When a backfill job processes claims with CreatedAt < t_act Then those claims continue to use vW, while claims with CreatedAt >= t_act use vX Given scope=include-backfills and activation time t_act When a backfill job processes claims with CreatedAt < t_act Then those claims are processed under vX And all version-selection outcomes are written to audit with claim IDs, scope, and chosen version
Real-Time Rollout Dashboard and Anomaly Alerts on Redaction Deltas
Given rollout vX is active and anomaly threshold T is configured per jurisdiction When the redaction delta rate for any cohort exceeds T for 3 consecutive 1-minute intervals Then an alert is sent within 60 seconds to configured channels (email/Slack/webhook) including cohort, jurisdiction, versions, and sample artifact metadata And the dashboard updates within 15 seconds to show adoption %, error rate, redaction delta rate, and expose Pause and Rollback controls And if auto_pause_on_anomaly=true, the rollout is automatically paused and labeled "Paused—Anomaly" with a link to an investigation view
In-Context Redaction Preview UI
"As a claims manager, I want to preview redactions within the claim viewer so that I can verify accuracy before enabling new rules."
Description

Offer a claim-centric preview showing exactly what will be masked and retained across images, PDFs, emails, and chat logs. Present side-by-side before/after with highlight overlays, entity labels, and rule citations. Allow filtering by jurisdiction, document type, and rule version, and export preview reports for stakeholder review. Support keyboard navigation, accessibility standards, and diffing between rule versions to pinpoint changes.

Acceptance Criteria
Side-by-Side Redaction Preview with Overlays
Given a claim with at least one document is opened in Preview When the user selects a document Then two panes labeled "Before" and "After" are displayed for the selected document And the "After" pane shows masked regions with highlight overlays; the "Before" pane shows outlines only And each masked region exposes an entity label and rule citation on hover and keyboard focus And zoom and pan actions are synchronized across both panes And a toggle control allows show/hide overlays without altering redaction results
Jurisdiction, Document Type, and Rule Version Filters
Given a claim contains documents across at least two jurisdictions, document types, and RuleSync rule versions available in Sandbox When the user applies selections in Jurisdiction, Document Type, and Rule Version filters Then the document list and previews update to include only items matching all selected filters within 1 second And active filters are displayed as removable chips and persist during navigation between documents When filters are cleared Then the default unfiltered view is restored If a filter combination returns no results Then a "No matching documents" message and a one-click Clear Filters action are shown
Export Preview Report
Given a claim preview is open with active filters and a selected rule version When the user selects Export Report -> PDF Then a PDF is generated and downloaded within 10 seconds containing for each document: thumbnails of Before/After, a table of redacted entities with entity label, location reference, and rule citation (jurisdiction, rule ID, version), and a total count And the report header includes claim ID, selected jurisdiction(s), document type(s), rule version, timestamp, and environment (Sandbox/Production) When the user selects Export Report -> CSV Then a CSV with one row per redacted entity and the same metadata is generated And exported files follow the naming pattern ClaimID_RuleVersion_YYYYMMDD_HHMM.{pdf|csv}
Accessibility and Keyboard Navigation
Given a user navigates the Preview UI using keyboard only When the Preview loads Then all interactive elements are reachable in a logical tab order and have visible focus indicators meeting WCAG 2.1 AA When pressing assigned shortcuts (e.g., Left/Right or J/K) Then focus moves to previous/next redacted entity and the viewport scrolls to keep it visible When pressing Enter or Space on a focused redaction Then the rule citation tooltip opens and is read correctly by screen readers via ARIA labels When opening the Keyboard Shortcuts help dialog Then it is fully operable via keyboard and dismissible with Esc, returning focus to the invoking control And overlay colors and text meet a minimum contrast ratio of 4.5:1
Rule Version Diffing
Given two RuleSync rule versions are selected for comparison When Diff mode is enabled Then added, removed, and changed redactions are visually distinguished with a legend explaining indicators And a summary displays counts of added, removed, and changed items per document and for the claim When the user enables the "Changes only" filter Then only documents and entities with differences are listed When exporting while Diff mode is active Then the report includes a diff section with the same counts and per-entity change reasons including rule IDs from both versions
Multi-Format Document Support
Given a claim includes an image (JPEG/PNG), a multi-page PDF, an email thread, and a chat log When each document is opened in Preview Then overlays align with content and masked areas preserve layout without revealing underlying data And for PDFs, page thumbnails and navigation work; redactions persist across page changes and zoom levels And for emails, headers, body, and inline/attached images are previewable with applicable redactions and citations And for chat logs, per-message redactions are supported with timestamps preserved and spacing intact If a document cannot be rendered Then a fallback message is shown with a safe-text summary and Download Original is disabled by default
Rule Citation Accuracy
Given a redacted element is hovered or focused Then its tooltip shows jurisdiction code, rule name/ID, clause reference, and rule version that triggered the redaction When multiple rules apply to the same element Then all applicable citations are listed in configured priority order When a rule is updated in Sandbox and the preview is refreshed Then citations reflect the new version number without stale values If a citation cannot be resolved Then the item is flagged "Citation unavailable" and an error event is logged with claim ID, document ID, entity type, and rule reference
Audit Trails, Approvals, and Evidence Pack
"As a compliance officer, I want auditable approvals and evidence packs so that I can demonstrate compliance to regulators and clients."
Description

Implement RBAC-controlled change workflows with multi-step approvals, rationale capture, and linkage to regulatory citations. Generate immutable, tamper-evident logs and an exportable evidence pack (PDF/JSON) including rule versions, approvers, simulation results, rollout timeline, and monitoring outcomes. Provide APIs to push compliance events to external GRC systems and retain audit artifacts per policy with legal hold support.

Acceptance Criteria
RBAC Multi-Step Approval for Rule Changes
Given a user with the Rule Editor role, When they submit a rule change, Then the system requires selection of an approval workflow with at least two distinct approving roles. Given a multi-step workflow, When an approver without the required role attempts approval, Then the action is blocked with 403 and an audit entry is created. Given defined workflow steps, When a user attempts to skip or reorder steps, Then the system prevents progression and records the attempt in the audit log. Given an approval action, When an approver approves or rejects, Then the system captures a digital signature, UTC timestamp, comment, and links them to the change in the immutable log. Given a pending approval, When the SLA threshold elapses, Then reminders and escalations are sent per notification policy and recorded. Given all steps approved, When final approval is granted, Then the change status becomes Approved and is queued for rollout with the approver chain visible to auditors.
Mandatory Rationale and Regulatory Citation Linkage
Given a proposed rule change, When a user submits it for approval, Then a non-empty rationale (min 20 characters) and at least one regulatory citation (valid jurisdiction code and regulation type: HIPAA, GLBA, GDPR, or State) are required. Given a citation entry, When the citation format is invalid, Then a validation error explains the required format and submission is blocked. Given valid citations, When the change is saved, Then citations are normalized to canonical IDs and linked to the change and the evidence pack. Given the change review screen, When approvers view the record, Then the rationale and citations are displayed and are read-only to approvers.
Immutable, Tamper-Evident Audit Logging
Given any create, update, delete, approval, rollout, retention, or export action, When the event occurs, Then an audit log entry is written containing actor ID, role, IP, user agent, RFC 3339 UTC timestamp, entity IDs, change diff hash, previous record hash, and a digital signature. Given the audit log chain, When any record is altered, Then hash-chain verification fails, a tamper event is flagged, and a security alert is emitted. Given an auditor request, When verifying a record, Then the system returns a Merkle root or chain proof for the record within 500 ms for the most recent 10,000 entries. Given clock drift > 2 seconds detected, When NTP resync occurs, Then the correction event is recorded in the audit log.
Evidence Pack Export (PDF/JSON) with Signatures
Given a finalized rollout, When an auditor exports the evidence pack, Then it includes change summary, before/after rule versions, approver chain, timestamps, rationale, citations, simulation results snapshot, rollout timeline (start/canary/full), and monitoring outcomes (masking accuracy metrics and exceptions). Given an export request with <= 500 changes, When processing starts, Then PDF and JSON artifacts are generated within 30 seconds and made available via a signed URL expiring in 24 hours. Given generated artifacts, When downloaded, Then each file includes a SHA-256 checksum and a detached signature that validates against the published public key. Given insufficient permissions, When a user without Auditor or Compliance Admin roles requests an export, Then the request is denied with 403 and an audit entry is recorded.
Sandbox Simulation and Impact Preview Capture
Given a proposed rule change, When a simulation run is executed on the sample corpus, Then the system stores the simulation configuration, dataset version, run ID, start/end time, and results summary (masked/unmasked deltas and FP/FN estimates) linked to the change. Given a preview request, When a user previews masking on a sample document, Then newly masked/unmasked fields are visually highlighted and a snapshot hash of the preview is recorded for evidence. Given an evidence pack export, When generated, Then it includes references to the latest simulation run and any prior runs associated with the change.
GRC Push API for Compliance Events
Given a configured external GRC endpoint, When a compliance event occurs (proposal, approval, rollout, exception, purge, legal hold), Then the system pushes an event containing an idempotency key, event type, payload schema version, HMAC signature, and RFC 3339 UTC timestamp. Given transient delivery failures, When the push fails, Then retries use exponential backoff with jitter for up to 24 hours and successes are recorded; failures after max attempts are sent to a dead-letter queue with alerts. Given duplicate deliveries, When the receiver processes idempotently using the key, Then no duplicate records are created and our system ceases retries upon 2xx acknowledgment. Given security requirements, When events are sent, Then TLS 1.2+ is enforced and invalid acknowledgments or signature mismatches generate alerts and audit entries.
Retention Policy and Legal Hold Compliance
Given retention policies by artifact type and jurisdiction, When audit artifacts (logs, evidence packs, simulation artifacts) are created, Then retention is assigned automatically and artifacts are stored on WORM-capable storage. Given a legal hold on a case or change, When retention expiry is reached, Then artifacts under hold are not deleted until the hold is lifted; hold placement and release capture actor, rationale, and timestamps. Given a purge window, When artifacts become eligible and are not on legal hold, Then a deletion job purges artifacts, records purge receipts with checksums, and updates the audit trail; auditors can retrieve purge receipts by ID. Given a retention policy update, When rules change, Then updates are versioned, require approval, and new effective dates are enforced without retroactive deletion of artifacts created under prior policies.

SendGuard

An outbound DLP intercept for email, chat, and system‑to‑system posts. Scans messages and attachments at send time, auto‑redacts detected PII/PHI, suggests safe alternatives, or blocks with a one‑tap fix. Prevents leaks before they leave the org, cutting rework, fines, and reputation risk.

Requirements

Unified Outbound Content Scanner
"As a claims manager, I want all outgoing messages and attachments scanned in real time so that I avoid accidentally sending sensitive data outside policy without slowing down my work."
Description

Real-time, send-time interception that scans email, chat, and system-to-system posts for sensitive content. Normalizes message bodies and extracts text from attachments (PDF, Office, images via OCR), including multi-page and embedded images. Detects PII/PHI and insurance-sensitive data (e.g., policy/claim IDs, VINs, SSNs, bank details, medical terms/codes) using a hybrid approach: validated patterns and checksums, NLP entity recognition, and ML context classifiers. Supports multilingual detection, channel adapters (SMTP/Graph/Gmail APIs, Slack/Teams, webhooks), and produces a structured finding set (entity, location, confidence) for downstream policy evaluation, with deterministic, idempotent processing.

Acceptance Criteria
Send-Time Email Scan with Multi-Attachment OCR
- Given an outbound email is sent via SMTP, Microsoft Graph, or Gmail API, When the sender clicks Send, Then the scanner intercepts before delivery and normalizes the message body (HTML to plain text, quote/signature stripping per configured rules). - Given the email includes up to 10MB of attachments across PDF, DOCX, XLSX, JPG, PNG, When scanned, Then text is extracted from all pages and embedded images, including multi-page PDFs and images inside Office files. - Given attached images at ≥150 DPI, When scanned, Then OCR returns text and bounding boxes for detected text regions. - Given a text-only email ≤256KB, When scanned, Then p95 scan latency is ≤200 ms and p99 ≤400 ms. - Given an email with attachments as above, When scanned, Then p95 scan latency is ≤2.5 s and p99 ≤5 s.
Real-Time Chat Intercept for Slack and Teams
- Given Slack and Teams adapters are configured, When a user attempts to send a message or upload a file, Then the scanner receives the content synchronously and completes scanning before the platform posts it. - Given a text-only chat message ≤16KB, When scanned, Then p95 scan latency is ≤150 ms. - Given an uploaded image or PDF ≤20MB and ≤25 pages, When scanned, Then text is extracted (including OCR for images) and p95 scan latency is ≤2.0 s. - Given a thread reply, ephemeral message, or edited message, When scanned, Then the normalized content is re-scanned and findings are updated consistently.
System-to-System Webhook Payload and Attachment Scan
- Given a POST webhook with JSON containing nested string fields and base64-encoded attachments, When scanned, Then all string fields are traversed and base64 payloads are decoded and scanned according to file type. - Given a JSON payload referencing attachments by signed URL up to 10MB each, When scanned, Then the scanner fetches each attachment within a 2 s connect+download budget and scans it; on failure it emits attachment_unavailable findings with reason and URL host. - Given a text-only JSON payload ≤128KB, When scanned, Then p95 scan latency is ≤100 ms. - Given any payload, When normalized, Then Unicode and whitespace are canonicalized (NFC, consistent line breaks) prior to detection so that semantically equivalent content yields identical findings.
Hybrid Detection of PII/PHI and Insurance-Specific Entities
- Given content containing candidate SSNs, When scanned, Then only numbers passing disallowed-range validation (no 000/666/9xx area, no 00 group, no 0000 serial) are emitted as ssn entities. - Given content containing candidate credit card numbers, When scanned, Then only numbers passing Luhn and BIN sanity checks are emitted as card_number entities. - Given content containing VINs, When scanned, Then only VINs passing ISO 3779 check digit and allowed character rules are emitted as vin entities. - Given content containing IBANs or US ABA routing numbers, When scanned, Then only values passing checksum validation are emitted as iban or aba_routing entities. - Given content containing policy IDs or claim IDs, When scanned, Then a finding is emitted only when both the configured pattern matches and the ML context classifier confidence ≥0.80 within a ±50 character window. - Given content containing medical terms and codes (ICD-10, CPT, SNOMED), When scanned, Then the NLP recognizer achieves ≥0.92 precision and ≥0.85 recall on the curated validation set.
Structured Findings Schema and Location Precision
- Given any detected entity, When a finding is emitted, Then it includes entity_type, normalized_value, confidence (0.00–1.00), channel, provider_message_id, location.path (body|attachment[index]|attachment[file_name]), page (if applicable), char_start, char_end (UTF-16), bbox (x,y,w,h,dpi when from OCR), and snippet (±32 chars). - Given multiple findings, When emitted, Then they are deterministically ordered by location.path, page, then char_start. - Given identical normalized content is scanned multiple times, When findings are emitted, Then detector_id and model_version are populated and stable across scans. - Given findings output, When validated, Then it conforms to Findings Schema v1.0.
Deterministic, Idempotent Processing
- Given byte-identical message content and attachments are scanned more than once, When scanning completes, Then the scanner returns an identical scan_id derived from a content hash and identical findings including ordering and confidences. - Given duplicate deliveries from a channel adapter with the same provider_message_id, When received, Then the scanner returns cached findings within ≤50 ms and marks idempotent=true without reprocessing. - Given semantically equivalent bodies differing only by whitespace, HTML markup, or quote delimiters, When normalized, Then resulting findings are identical.
Multilingual Detection Coverage and Fallbacks
- Given messages predominantly in English, Spanish, French, German, or Portuguese, When scanned, Then person_name, address, bank_account, iban, card_number, medical_term, and medical_code entities achieve ≥0.90 precision and ≥0.80 recall on the multilingual validation set. - Given content with mixed languages, When scanned, Then language detection occurs at paragraph level and detectors are applied per span accordingly. - Given content in unsupported languages, When scanned, Then pattern-based detectors still run and NLP/ML detectors are disabled unless language confidence ≥0.70. - Given numerals in non-Latin scripts, When scanned, Then numerals are normalized to ASCII digits for pattern-based validation.
Auto-Redaction & Safe Artifact Generation
"As an adjuster, I want sensitive fields auto-redacted before messages are sent so that I can communicate quickly without risking a data leak or manual rework."
Description

Automatic masking/redaction of detected sensitive data per policy with consistent formatting (e.g., last-4 masking, tokenization). Generates sanitized message bodies and derivative attachments that preserve layout/legibility (text burn-in for images/PDFs, content-aware whitespace for docs). Supports context-aware partial redaction to keep messages useful, plus replacement hints/placeholders. Maintains secure linkage between original and sanitized artifacts with content hashes; originals may be quarantined per policy with tightly scoped access. Ensures reversible redaction only for authorized roles and logs all transformations for auditability.

Acceptance Criteria
Email Body and PDF Attachment Auto‑Redaction per Policy
Given policy P1 with rules: SSN -> xxx-xx-####, Credit Card -> mask all but last 4, DOB -> YYYY only, MRN -> tokenized And an outbound email containing SSN 123-45-6789, CC 4111 1111 1111 1234, DOB 1990-04-21 in the body And a single 5MB PDF attachment containing the same values in selectable text When the sender clicks Send and SendGuard scans at send time Then the outbound message body is rewritten as SSN xxx-xx-6789, CC •••• •••• •••• 1234, DOB 1990 And a sanitized PDF derivative is generated with the same filename plus “_redacted” suffix and identical page count And the original email body and original attachment remain unmodified in quarantine storage per policy And the send proceeds with the sanitized body and sanitized attachment only And a redaction summary header X-SG-Redaction: policy=P1; items=4 is appended to message metadata
Layout‑Preserving Redaction for Images and PDFs
Given a PDF with selectable text and an image (JPEG) containing visible PII bounding boxes When redaction is applied Then for the PDF, PII is removed and a burn‑in black rectangle overlays each redacted region with ≥2px padding, and underlying text extraction (copy/paste) yields placeholders only And the PDF page count is unchanged and paragraph reflow differs by ≤1 line per page And for the image, a burn‑in rectangle fully covers detected PII regions with no visible bleed and cannot be programmatically removed via metadata inspection And all sanitized artifacts pass a basic OCR check showing placeholders instead of original PII
Context‑Aware Partial Redaction to Preserve Utility
Given policy P2 permitting partial redaction: card -> last4 visible, address -> city/state/ZIP visible, names -> initials, claim IDs -> unredacted And a message body: “John A. Smith at 1234 Main St, Springfield, IL 62704 used card 5555 4444 3333 1111 on 2025-08-15 for claim CLM-2025-000123.” When SendGuard applies P2 Then the output is: “J.S. at Springfield, IL 62704 used card •••• •••• •••• 1111 on 2025-08 for claim CLM-2025-000123.” And street number and apartment/unit identifiers are removed while keeping city/state/ZIP And month precision is preserved for date per policy while day is removed And no non-sensitive terms (e.g., claim ID) are altered
Replacement Hints and Placeholders
Given policy P3 requiring explicit placeholders with hints And detected SSN 123-45-6789 and patient name “Maria Lopez” in a chat message When redaction occurs Then SSN is replaced inline with [REDACTED: SSN last4=6789] And name is replaced with [REDACTED: PERSON initials=M.L.] And a footer note “Redactions applied per policy P3. Request access if required.” is appended for internal recipients only And placeholders are ASCII, bracketed, and ≤60 chars each And placeholders are consistently formatted across body and attachments
Secure Linkage, Hashing, and Quarantine Access Controls
Given any original artifact (message body or attachment) and its sanitized derivative When processing completes Then SHA-256 hashes are computed for original and sanitized artifacts and stored with a bidirectional linkage record {original_hash, sanitized_hash, policy_id, timestamp, actor} And the original artifact is moved to quarantine storage encrypted at rest with AES-256 and object-level ACLs And only roles [Privacy Officer, DLP Admin] have read access to originals; general users have access to sanitized only And attempting to dereference an original by a non-authorized principal returns 403 and is logged And deleting a sanitized artifact does not delete the original linkage record
Authorized Reversal Workflow and Auditability
Given a user in role Privacy Officer with MFA enabled and a valid business justification And a sanitized artifact linked to an original When the user requests to view original content Then access is granted in a secure viewer session that expires after 15 minutes and is watermarked with user ID, time, and case ID And any export/download action delivers only sanitized artifacts; originals cannot be exported And every reversal/view event logs {who, when, what, why, hashes, duration} and appears in the immutable audit log within 5 seconds And a user without the required role or MFA receives a denial with correlation ID and no content leakage
Send‑Time Performance and Reliability
Given an outbound email with ≤10MB total attachments and ≤200KB body When SendGuard intercepts and redacts Then end‑to‑end added latency is ≤800ms at the 95th percentile and ≤1500ms at the 99th percentile And for chat messages ≤256KB, added latency is ≤150ms p95 And for a 50MB PDF attachment, processing completes in ≤5s p95 or the message is held with a one‑tap “Send Sanitized Only” option presented to the sender And under 100 concurrent sends, the system maintains ≥99.9% success without redaction errors; any failure blocks the send and surfaces a retriable error with correlation ID And no message leaves the organization containing unredacted items detected by policy
One-Tap Fix Intercept UI
"As a sender, I want a clear prompt with one-tap fixes at send time so that I can resolve issues immediately without abandoning my message."
Description

Lightweight pre-send dialog embedded in compose flows that surfaces findings with inline highlights and proposed fixes. Offers one-tap actions: apply redactions, edit text inline, remove/replace attachments, switch to secure link delivery, or change recipients. Supports policy-aware overrides with reason codes, approver routing when required, and role-based permissions. Designed for minimal friction and accessibility (keyboard navigation, screen reader support), localized strings, and consistent behavior across email, chat, and API error responses.

Acceptance Criteria
Email Send: Auto‑Redact PII Before Dispatch
Given a user clicks Send on an email containing detected PII/PHI in body and/or attachments When SendGuard intercepts Then the One‑Tap Fix dialog renders within 500 ms and displays an itemized findings list with inline highlights in the preview Given the user selects "Apply all redactions" When the action is applied Then all detected PII/PHI is redacted in the body and supported attachments (PDF, DOCX, TXT, PNG, JPG) and a side-by-side diff is shown Given redactions are applied When validation re-runs Then zero critical findings remain and the primary action changes to "Send" enabled Given at least one critical finding remains after user actions When the user attempts to send Then send is blocked and the dialog surfaces the remaining count and locations Given the intercept occurs When the event completes (send or cancel) Then an audit event is recorded with correlationId, actor, policyId, actionsTaken, findingsCount, and outcome
Chat Message: Inline Edit With Suggested Fixes
Given a user presses Enter to send a chat message containing detected PII/PHI When the intercept appears Then the message content is editable inline with a suggestion chip per finding Given the user accepts a single suggestion When it is applied Then only that span changes and validation re-runs in under 200 ms Given all high-severity findings are resolved When the user presses Enter Then the message sends without further intercept Given policy forbids "Send anyway" for high severity When unresolved critical findings exist Then the "Send anyway" button is hidden or disabled according to the user's role Given the chat client is on mobile When the intercept opens Then it occupies no more than 80% of viewport height, supports swipe-to-dismiss, and returns focus to compose on close
Attachments: Remove, Replace, or Secure Link
Given an outbound email contains an attachment flagged with PII/PHI When the intercept opens Then the attachment is listed with severity, pages/locations, and per-file actions: Remove, Replace, Secure Link Given the user taps Remove When confirmed Then the file is removed from the draft and validation re-runs Given the user taps Replace and selects a sanitized version When upload completes Then the new file replaces the original and validation reflects the new file Given the user taps Secure Link When applied Then the file is removed and a secure link placeholder is inserted with access controls per policy (expiry, recipient allowlist), and recipients are notified in the body Given any attachment action occurs When the user proceeds Then the audit record includes fileName(s), actionType, and enforcementResult
Recipient Safety: External Recipient Changes
Given external recipients are present and policy requires warning When the intercept opens Then external domains are highlighted and a banner describes the risk with actions: "Remove externals", "Move externals to Bcc", and "Change recipients" Given the user selects "Remove externals" When applied Then all external addresses are removed from To/Cc and listed in a confirmation Given the user selects "Move externals to Bcc" When applied Then externals are moved from To/Cc to Bcc, a thread privacy warning is shown, and validation re-runs Given a recipient is on an allowlist When validation runs Then no warning is shown for that recipient Given recipients are changed in the intercept When the dialog closes Then the compose view reflects the updated recipients and focus returns to the subject field
Policy-Aware Override and Approver Routing
Given unresolved findings remain and the user has override permissions When the user selects "Override policy" Then a mandatory reason code dropdown and free-text comment (minimum 10 characters) are required before proceeding Given policy requires approver for overrides involving PHI to external domains When the user submits an override Then the message is queued, an approver is notified, and the sender sees a status chip "Pending approval" Given an approver approves within the SLA (15 minutes or less) When approval is received Then the message is automatically sent and both parties receive confirmation Given an approver rejects or the SLA expires When the decision is recorded Then the sender receives a rejection notification with reason, and the draft remains unsent Given the user lacks override permission When unresolved critical findings exist Then the override option is not visible and an info tooltip explains the required role
Accessibility: Keyboard and Screen Reader Compliance
Given a keyboard-only user triggers Send When the intercept opens Then focus is trapped within the dialog, initial focus is on the findings list, and the flow is operable via Tab, Shift+Tab, Enter, and Escape Given a screen reader user When the dialog opens Then a live region announces the intercept, the count of findings, and the next actionable control within 2 seconds Given UI controls are rendered When tested Then all actionable elements have accessible names, roles, and states per WAI-ARIA, and color contrast is at least 4.5:1 Given the user presses Escape When there are no blocking findings Then the dialog closes and focus returns to the Send button; otherwise a non-modal alert explains required actions Given localization direction is RTL When the intercept renders Then focus order and alignment respect RTL without loss of information
API Clients: Consistent Intercept Error Payload and Remediation
Given a system-to-system POST is blocked by DLP When the API responds Then it returns HTTP 422 with a JSON body containing correlationId, policyId, findings[], suggestedFixes[], allowedActions[], and a resubmitToken Given the client retries with a payload that applies suggested fixes and includes the resubmitToken When validation passes Then the API returns HTTP 202 Accepted and processes the message Given the client locale header is provided (e.g., Accept-Language) When the error is returned Then human-readable strings are localized and machine-readable codes remain stable Given the API schema version is requested via header When the response is returned Then fields conform to the requested version or include a versionMismatch notice Given rate limits are exceeded for intercepted sends When the API responds Then it returns HTTP 429 with Retry-After, and no duplicate audit events are created
Policy Configuration & Rule Engine
"As a compliance admin, I want granular, testable DLP policies so that I can enforce the right controls without disrupting critical claim communications."
Description

Administrator experience and rules service to define DLP policies by data class, channel, recipient domains, claim type/LOB, jurisdiction, and environment. Supports actions (block, warn, auto-redact, quarantine), confidence thresholds, masking formats, exception/trusted lists, legal holds, and time-bound rules. Includes versioning, staged rollout (test/simulate/enforce), dry-run simulation with historical samples, and change audit trails. Policies are evaluated deterministically with clear precedence and can be targeted to teams and workflows within ClaimFlow.

Acceptance Criteria
Deterministic Policy Precedence Resolution
Given a message that matches Policy A (precedence 90, action=block) and Policy B (precedence 80, action=warn) for the same scope When the rule engine evaluates the message Then the engine executes only Policy A's action and suppresses Policy B And the evaluation log records the ordered precedence [A,B] and the final decision "block" And repeated evaluations of the same inputs produce the identical decision and log
Scoped Targeting by Channel, LOB, Jurisdiction, Environment, Teams and Workflows
Given a policy scoped to channels=email+chat, LOB="Auto", jurisdictions=["CA","NY"], environment="Prod", teams=["FNOL"], workflows=["Intake"] And a message with metadata channel=email, claim LOB=Auto, jurisdiction=CA, environment=Prod, team=FNOL, workflow=Intake When the engine evaluates the message Then the policy applies And a second message where any one scoped attribute does not match (e.g., jurisdiction=TX) When evaluated Then the policy does not apply and the log shows "scope_mismatch: jurisdiction"
Actions and Masking Formats Enforcement
Given a policy with action=auto-redact and masking formats SSN=XXX-XX-#### and PAN=****-****-****-#### and channels=email+chat+system And a message body "SSN 123-45-6789 and Visa 4111111111111111" and a PDF attachment containing "Patient SSN: 999-88-7777" When evaluated Then the outgoing payload has body "SSN XXX-XX-6789 and Visa ****-****-****-1111" And the attachment is redacted to mask SSNs per policy with a redaction marker And the structured audit includes original span hashes, redacted spans, data classes, and mask formats applied And given the action=quarantine When triggered Then the message is not sent and is placed in quarantine with a release token linked to the violation record
Confidence Thresholds per Data Class
Given a policy with thresholds SSN>=0.90 -> block, DOB>=0.60 -> warn, PAN>=0.80 -> auto-redact And detection outputs for a message SSN=0.93, DOB=0.58, PAN=0.81 When evaluated Then the final action set includes block for SSN, auto-redact for PAN, and no action for DOB And if multiple actions exist for the same message, the configured action precedence resolves to a single enforced action, and secondary actions are recorded in the audit
Trusted Lists, Exceptions, and Legal Holds Precedence
Given a policy that would block external email with PII And the recipient domain "example.com" is in the trusted list for this policy When evaluated Then the action is downgraded to warn per the trusted list rule and the audit shows "trusted_domain_applied: example.com" And given the sender is on an explicit exception list for this policy (expires in 7 days) When sending to a non-trusted external domain Then the policy is bypassed and the audit shows "user_exception_applied" with scope and expiry And given a legal hold exists for the related claim that requires quarantine of all outbound artifacts When the same sender attempts to bypass Then the legal hold supersedes trusted and exception lists and the message is quarantined with reason "legal_hold"
Versioning, Staged Rollout (Test/Simulate/Enforce), and Auditability
Given Policy v1 is active in enforce stage and Policy v2 (with changed thresholds) is published in simulate stage When live traffic is evaluated Then v1 decisions are enforced and v2 produces parallel evaluation logs only, with no message modifications or blocks And when an admin promotes v2 to enforce and archives v1 Then v2 becomes the sole enforced version with immutable version IDs and timestamps And the change audit records who made the change, what fields changed, before/after values, reason, and approver, and is exportable And any edit to an enforced policy creates a new version; in-place edits are rejected
Dry-Run Simulation on Historical Samples
Given an admin selects a policy version and a historical sample set of 10,000 messages from a defined date range across email, chat, and system posts When the dry-run is executed Then no messages or attachments are modified, sent, or quarantined And a report is generated with counts of matches by data class and channel, projected actions, and top recipients affected And per-message trace records are available for at least 500 samples with reasons and matched spans And the simulation results are stored with an ID, policy version, date range, and execution timestamp and are retrievable for later review
ClaimFlow Integration & Workflow Routing
"As a claims supervisor, I want SendGuard outcomes recorded on the claim and to drive follow-up tasks so that we maintain traceability and unblocked workflows."
Description

Tight integration with ClaimFlow entities and automation. Associates findings, actions, and artifacts with the correct claim record, conversation thread, and user. Emits events to trigger workflow steps (e.g., create follow-up tasks on block, notify supervisor on override), and writes an entry to the claim timeline. Provides APIs/webhooks for external partner systems, idempotency keys for retried posts, and deterministic routing for system-to-system deliveries post-sanitization. Respects per-claim classification and recipient context to tailor enforcement.

Acceptance Criteria
Associate SendGuard Action to Claim, Thread, and User
Given an outbound message is intercepted by SendGuard and contains a resolvable claim reference (claimId or thread metadata), When the scan result is persisted, Then the decision record is stored with non-null claimId, threadId, and userId that validate against existing entities. Given the association cannot be resolved uniquely, When the user attempts to send, Then the send is blocked and the user is prompted to select the correct claim; When the user selects a claim, Then the association is saved and the send is re-evaluated without requiring message re-entry. Given redacted attachments and a redaction summary are produced, When the decision is stored, Then those artifacts are attached to the claim’s artifact store and appear under the correct conversation thread in ClaimFlow within 5 seconds P95. Given an API consumer queries by claimId, When retrieving SendGuard decisions, Then the API returns the most recent 100 decisions in under 300 ms P95 with pagination for more.
Create Follow-up Task on Block
Given a message is blocked due to detected PII/PHI policy, When the block decision is finalized, Then a workflow task of type "DLP Review" is created in ClaimFlow and linked to the claimId and threadId. Then the task payload includes userId, blocking rule id, reason codes, risk score, and a link to the redaction preview. Then the task is assigned per routing rules (claim owner if present else DLP team queue) with a due date of next business day and priority = High. Given retries or duplicate events, When the same idempotency_key is received within 24 hours, Then no duplicate tasks are created (existing task is returned/updated). Then task creation is recorded as an event on the claim and is visible in the workflow queue within 10 seconds P95.
Supervisor Notification on Policy Override
Given a user chooses to override a SendGuard block or mandatory redaction, When the override is confirmed, Then a supervisor notification is sent within 30 seconds via ClaimFlow in-app alert and email. Then the notification includes claimId, threadId, userId, override reason (required), original findings summary, and a diff of redactions overridden. Then an audit event "DLP_OVERRIDE" is emitted to the event stream with an idempotency_key and stored in the claim timeline. Given the notification endpoint is unavailable, When delivery fails, Then the system retries with exponential backoff for up to 6 hours and logs outcomes per attempt.
Write Intercept Entry to Claim Timeline
Given SendGuard takes an action (allow, auto-redact, block, override), When the action completes, Then a timeline entry is written including timestamp (UTC), action type, counts of detected entities, rule ids matched, actor (system/user), and outcome. Then the timeline entry includes links to stored artifacts (redacted files, decision report) and the event id. Then entries are immutable (read-only after write) and appear in correct chronological order; P95 write latency < 2 seconds. Given a duplicate event with the same idempotency_key, When received, Then no additional timeline entry is created (original entry is referenced).
External Partner Webhook Delivery with Idempotency
Given a partner webhook is configured and enabled for a claim’s line of business, When a SendGuard decision occurs, Then a POST is made to the partner endpoint with schema version=1.0 including idempotency_key, claimId, threadId, action, rule ids, reason codes, risk score, and artifact URIs. Then a 2xx response marks delivery as succeeded once; 429/5xx responses trigger exponential backoff retries for up to 24 hours with jitter; retries include the same idempotency_key. Then the system treats partner 409/duplicate-idempotency responses as success and stops retrying. Then delivery attempt history is queryable by claimId and idempotency_key via API, and contains timestamps, response codes, and final status.
Deterministic Routing for Post-sanitization System Deliveries
Given system-to-system delivery is configured, When content is sanitized, Then the destination is selected by a deterministic function f(claimId, partnerId, classification, messageType) such that identical inputs always yield the same route. Then on any retry or reprocessing with the same inputs, the chosen route and headers are identical to the original. Then the routing key, selected destination, and inputs are recorded in the audit log and timeline entry. Given configuration changes after an event is first routed, When retries occur, Then the original route is preserved (sticky routing) unless explicitly re-route is requested via admin action logged in audit.
Tailored Enforcement by Claim Classification and Recipient Context
Given claim classification in {High, Moderate, Low} and recipient context in {Internal, Trusted External, Untrusted External}, When SendGuard evaluates an outbound message, Then enforce: - High + Untrusted External: Block; require redaction or supervisor override. - High + Trusted External: Auto-redact; allow only if residual risk score <= configured threshold. - Moderate + External (Trusted/Untrusted): Auto-redact; allow if PII count <= configured max; else block. - Low + Internal: Allow; warn if PII present; log findings. Then the policy inputs, evaluated rules, final decision, and thresholds used are logged and attached to the claim timeline. Then any override requires a reason (min 15 chars) and supervisor notification; all overrides are idempotent and auditable.
Audit Logging, Alerting & Compliance Reporting
"As a compliance officer, I want comprehensive, exportable audit trails and reports so that I can demonstrate compliance and proactively address risky patterns."
Description

Immutable, tamper-evident logs of scans, detections, actions, overrides (with reasons), and policy versions applied. Configurable retention by region/regulation (e.g., HIPAA, GLBA) with encryption at rest and in transit. Real-time alerts for high-severity violations or repeated risky behavior. Export integrations to SIEM (syslog/JSON), scheduled compliance reports by team/LOB/timeframe, and dashboards showing prevented leaks, override rates, and top violation types. Access to reports and logs is role-gated and fully audited.

Acceptance Criteria
Tamper‑Evident Immutable Audit Log
Given any scan, detection, action (allow/block/redact), override, or policy evaluation occurs When the event completes Then an audit record is written containing: event_id (UUIDv4), correlation_id, tenant_id, user_id/service_id, source_channel, UTC timestamp (ISO 8601), event_type, findings, action_taken, policy_version_id, override_flag, override_reason (if any), request_hash, response_hash, and outcome. Given an audit record is written When it is persisted Then it is chained via previous_hash and signed with an HSM-backed key, marked WORM, and any update attempt creates a new correction record and emits a tamper_warning event. Given an auditor verifies integrity for a time window When chain verification runs Then 100% of records validate their hash chain and signature, and a verification report (checksum + range) is produced and stored. Given peak load of 10k events/min When logging occurs Then P95 write latency ≤ 200 ms and no data loss is observed; back-pressure does not drop events (at-least-once).
Role‑Gated Access and Access Auditing
Given RBAC is configured with roles Admin, Compliance Auditor, Team Manager, and Adjuster When users request access to audit logs or reports Then permissions are enforced: only Admin and Compliance Auditor can access org-wide logs; Team Manager sees only their teams; Adjuster sees only personal activity. Given any access attempt (success or failure) When it occurs Then an access_audit record is logged with user_id, role, ip, user_agent, justification (required for privileged views), resource, filters, UTC timestamp, and decision. Given a user without permission attempts to export logs When the export is initiated Then the request is denied with 403, the attempt is logged, and the response contains no data. Given a privileged export is requested When the user passes MFA Then the export link is single-use, watermarked with requester identity, expires within 24 hours, and the download event is logged.
Configurable Regional Retention and Encryption
Given retention policies are defined per region/regulation When events are stored Then data residency is enforced to the region of the data subject/tenant, and data is encrypted at rest with AES-256 and in transit with TLS 1.2+. Given the retention period elapses When nightly purge runs Then eligible records are permanently deleted within 24 hours, purge actions are logged by count and range, and deleted content is unrecoverable except where legal_hold=true. Given a legal hold is applied to a scope When purge executes Then records in scope are retained until hold removal, and hold changes are fully audited. Given a policy version changes When saved Then the new version is timestamped, does not retroactively reduce existing retention, and prospective application is reflected in subsequent storage decisions.
Real‑Time Alerts for High‑Severity and Repeated Violations
Given a high-severity violation is detected When the action is determined (block or redact) Then an alert is dispatched to configured channels (email, Slack, webhook) within 60 seconds P95, containing redacted summary, event_id, team, policy, severity, and a link to the audit record; no raw PII/PHI is included. Given multiple risky events by the same user meet a threshold When the threshold is crossed Then an escalation alert is sent to the manager and compliance, and rate-limited to 1 every 30 minutes per user. Given alert delivery fails When the first attempt fails Then the system retries with exponential backoff for up to 24 hours, logs failures, and raises a health alert if delivery remains unsuccessful. Given duplicate detections for the same event When alerts are generated Then deduplication prevents sending more than one alert per event_id per channel.
SIEM Export Integrations (Syslog/JSON) with Delivery Guarantees
Given a SIEM destination is configured When connection test runs Then syslog over TCP/TLS (RFC5425) and JSON over HTTPS both validate connectivity and certificate trust, and return a success/failure result with diagnostics. Given streaming export is enabled When events are generated Then each event is emitted in the documented schema with stable event_id, at-least-once delivery, P95 end-to-end latency ≤ 2 minutes, and ordering preserved per correlation_id. Given the SIEM endpoint throttles or is unavailable When backpressure occurs Then the exporter retries with exponential backoff, buffers up to the configured limit, exposes queue depth metrics, and routes excess to a dead-letter queue visible to admins. Given an administrator requests a backfill When a date range is selected Then events for that range are re-exported idempotently, marked as replay=true, and progress is trackable; cancellation is supported.
Scheduled Compliance Reports by Team/LOB/Timeframe
Given a compliance report is scheduled When the schedule triggers Then the system generates a report for the specified team/LOB/timeframe in PDF and CSV, including prevented leaks count, override rate, top violation types, trend charts, and definitions. Given time zones differ across recipients When the report is produced Then the timeframe respects the configured time zone, and the zone is displayed on the report. Given a report is delivered by email When recipients are notified Then a secure link is sent, expiring within 48 hours, accessible only to users with RBAC permission; all opens and downloads are logged. Given 100k events in the period When the report is generated Then generation completes within 5 minutes P95, and aggregate counts reconcile to audit logs within 0.5%. Given a scheduled run fails When an error occurs Then an alert is sent to admins with failure details, and the job auto-retries once.
Dashboards: Prevented Leaks, Override Rates, Top Violations
Given a compliance user opens the dashboards When data loads Then metrics display within 3 seconds P95 with a data freshness indicator ≤ 2 minutes old, and no PII/PHI is visible. Given filters are applied (date range, team, policy, severity) When applied Then all widgets update consistently, and counts match filtered audit logs within 0.5%. Given a user drills down from a chart When a point is clicked Then the user is taken to a list of underlying events with links to their audit records. Given an export is requested When the dashboard is exported Then PNG and CSV exports are generated, watermarked with requester identity, and access-controlled via RBAC. Given monthly uptime SLO is 99.9% When availability is measured Then the dashboard service meets or exceeds the SLO, and outages are recorded and reportable.
Low-Latency & High-Availability Intercept SLOs
"As a sender, I want SendGuard to be fast and always available so that my legitimate communications are not delayed while still protecting sensitive data."
Description

Service-level objectives and architecture to ensure send-time responsiveness and reliability. 95th percentile decision latency under 500 ms for messages ≤5 MB; streaming/chunked scanning for larger payloads up to 50 MB with progress feedback; hold-and-release flows for very large attachments. Horizontal autoscaling, regional processing, and 99.9% monthly availability with health checks, circuit breakers, and graceful degradation (safe default to block or hold per policy on critical failures). Backpressure handling, retry with exponential backoff, and clear user/system error messaging. All processing remains in-region with strict data minimization.

Acceptance Criteria
P95 ≤500ms Decision Latency for ≤5MB Payloads
Given a send event for email, chat, or API post with total payload size ≤ 5 MB and all dependencies healthy When the message is submitted to SendGuard within the same region as the sender Then the decision (allow/redact/block) is emitted within 500 ms at the 95th percentile over a rolling 30-day window, measured from first byte received to decision emitted And no more than 0.1% of such requests time out; any timeout results in the safe default per policy and emits error code SG-DEC-TMO And latency SLO compliance is visible per-region on the ops dashboard with p50/p95 values and sample size
Streaming Scan with Progress for 5–50MB Payloads
Given a send event with total payload size > 5 MB and ≤ 50 MB When scanning begins Then content is processed in streaming chunks without buffering the full payload in memory And progress feedback is emitted via UI callback or webhook at least every 2 seconds or 10% increments, whichever occurs sooner, including bytes processed and estimated percent complete And the final decision is emitted upon completion with a single correlation ID consistent across all progress events
Hold-and-Release Flow for Very Large Attachments
Given a send event with one or more attachments exceeding the policy-defined hold threshold (default 50 MB) or an estimated scan time exceeding the policy-defined limit When the user attempts to send Then SendGuard holds the message before egress and presents a hold notification with options: remove attachment(s), request asynchronous scan/release, or cancel send And when an asynchronous scan completes successfully within the policy-defined TTL Then the message is automatically released and sent without user resubmission, and the user receives a release confirmation And if scanning fails or TTL expires Then the message is blocked per policy, the user is notified with remediation guidance, and an audit log records hold reason, outcome, timestamps, and correlation ID
99.9% Monthly Availability and Graceful Degradation
Given production operations in each region When monthly availability is calculated as (total minutes − unplanned downtime minutes)/total minutes per region Then availability is ≥ 99.9% for SendGuard decisioning endpoints And during dependency failures or timeouts Then a circuit breaker trips after the configured consecutive failure threshold, traffic is shifted to graceful-degrade mode, and each decision request receives the safe default (block or hold per policy) within 250 ms with error code SG-GD-APPLIED And health and readiness endpoints expose status suitable for orchestrator health checks with ≤ 100 ms response time, and synthetic probes run at 1-minute intervals per region with results retained for SLO audits
Backpressure Handling and Client Retry with Exponential Backoff
Given sustained traffic surges that exceed provisioned capacity or queue thresholds When backpressure is applied Then SendGuard responds to new requests with HTTP 429 (or channel-equivalent) within 100 ms including a Retry-After hint and correlation ID, without dropping accepted requests And clients (SDKs/webhooks) perform retries with exponential backoff and jitter for at least 3 attempts, honoring Retry-After, and include idempotency keys to prevent duplicate processing And upon retry success Then the original correlation ID is preserved in logs and metrics, and overall decision latency SLOs for ≤ 5 MB payloads remain within target excluding explicitly signaled 429 responses
In-Region Processing and Data Minimization
Given any send event in region R When SendGuard processes the message and attachments Then all compute and storage operations occur in region R; no cross-region or cross-border data transfer is observed in dependency traces or network egress logs And no message body or attachment contents are persisted to durable storage; only minimal metadata (timestamp, decision code, redaction counts, sizes, correlation ID) is logged per data minimization policy, with content-derived artifacts limited to non-reversible hashes for deduplication And data retention for operational logs follows the organization’s minimization policy and deletion is verifiable via automated retention jobs with audit evidence
Horizontal Autoscaling Maintains Latency SLOs
Given a sustained increase in request rate and payload mix representative of production When load rises from baseline to burst levels Then the autoscaler increases capacity within the configured window so that the p95 decision latency for ≤ 5 MB payloads remains ≤ 500 ms and error rates remain ≤ 0.1%, with zero failed in-flight requests during scale-out And when load decreases Then the system scales in without terminating in-flight requests and without breaching availability or latency SLOs

Role Composer

Visual, drag‑and‑drop builder for least‑privilege roles. Start from carrier‑size blueprints, toggle field‑level read/edit/mask, and layer conditions by line of business, jurisdiction, and claim state. Inheritance and test users let admins assemble precise roles in minutes, reducing misconfigurations and onboarding time.

Requirements

Drag-and-Drop Role Builder Canvas
"As an admin, I want to visually assemble roles by dragging permissions so that I can create precise least-privilege roles quickly without memorizing permission codes."
Description

A visual canvas to compose roles from reusable permission blocks with drag-and-drop, grouping, and search. Provides real-time validation and an at-a-glance summary of effective permissions to guide least-privilege design. Supports undo/redo, autosave of drafts, and responsive, accessible UI. Persists roles to the ClaimFlow RBAC store and synchronizes with existing user/groups. Integrates with the admin console navigation and respects tenant boundaries.

Acceptance Criteria
Drag-and-Drop Composition and Grouping
Given an empty role draft and a visible permission block library When the admin drags a block onto the canvas and releases Then the block is added to the role draft at the drop position and visually snaps to the grid within 150 ms And When the admin drags a block to reorder within a group or between groups Then the order updates and is persisted to draft state And When the admin drags one block onto another Then a new group is created (or the target group expands) and both blocks are grouped And When the admin drags a block over an invalid drop zone Then a no-drop indicator is shown and the drop is prevented And Unique-only blocks cannot be added more than once; attempting to drop a duplicate shows a non-blocking warning
Permission Block Search and Insert
Given a library with at least 200 permission blocks containing name, tags, and description When the admin types a search query of 2 or more characters Then results are filtered by name, tag, or description with p95 response time <= 300 ms and matching text is highlighted And When the admin presses Enter with a result focused Then the focused block is inserted onto the canvas at the default drop zone And Clearing the query restores the full list and resets scroll to top And Search is case-insensitive and supports partial matches and fuzzy matching (Levenshtein distance <= 1 for words >= 4 characters)
Real-Time Validation and Publish Gate
Given a role draft on the canvas When two blocks create a conflicting permission or violate a rule (e.g., mutually exclusive or missing required dependency) Then an inline validation appears within 200 ms, offending blocks are badged, and a detailed message is listed in the validation panel And While any Error-severity validation exists Then the Publish action is disabled with an accessible tooltip explaining the blocking issues And Clicking a validation item scrolls and focuses the first offending block on the canvas And Warnings (non-blocking) allow publish but require explicit confirmation via a modal listing all warnings
Effective Permissions Summary Accuracy
Given a role draft composed of N blocks When the admin adds, removes, groups, or reorders blocks Then the Effective Permissions Summary updates within 200 ms to reflect the resolved permission set And The summary displays counts by resource and action and supports a diff against a selected comparator role And For a curated test set of 10 role compositions, the summary output exactly matches the RBAC evaluation engine (0 mismatches) And Hovering or focusing a summary item highlights its contributing blocks on the canvas
State Management: Undo/Redo and Autosave Draft Recovery
Given a sequence of at least 25 canvas operations (add, remove, group, reorder, rename) When the admin presses Ctrl+Z repeatedly Then each operation is undone in order up to the initial state; further undo is disabled And When the admin presses Ctrl+Shift+Z or Ctrl+Y Then operations redo in order up to the latest state And The undo/redo stack persists across in-app navigation and soft page refresh And Draft changes are autosaved within 3 seconds of inactivity and on blur; closing and reopening within 24 hours restores the latest draft with a "Draft restored" notification And If autosave fails due to network error, the system retries with exponential backoff up to 4 attempts and shows a non-blocking warning
Responsive and Accessible Canvas
Given device widths from 320 px to 1440+ px When the admin opens the canvas Then the layout remains usable at 320 px and exhibits no horizontal scroll at >= 1280 px And Primary interactions (drag, drop, search, publish, undo/redo) are reachable and operable via keyboard with visible focus indicators And Draggable and droppable elements expose ARIA roles/states and announce pick-up, move, group, drop, and validation changes via a live region And All text and controls meet WCAG 2.1 AA contrast (>= 4.5:1), have accessible names/labels, and remain functional at 200% zoom without content loss or overlap
Persistence to RBAC Store, Tenant Isolation, and Admin Console Integration
Given a tenant-scoped admin with permissions to manage roles When the admin clicks Publish on a valid draft Then the role is created/updated in the ClaimFlow RBAC store with a new version, audit metadata (actor, timestamp, changeset), and the draft is marked as published And Within 60 seconds, assigned users/groups reflect updated permissions on next authorization check; the UI advises re-authentication to refresh tokens And The role appears in the Admin Console Roles list for the same tenant and is accessible via deep link; cross-tenant access attempts return HTTP 403 with a Not authorized message And All API calls for publish/read/write include the tenant identifier and no cross-tenant data is read or written
Field-Level Permissions and Data Masking Toggles
"As a compliance-focused admin, I want to configure field-level read, edit, and mask permissions so that sensitive data is protected while teams can still complete their tasks."
Description

Fine-grained controls to set read, edit, and mask at the field level across Claim, Policy, Party, Payments, Documents, and Notes entities. Masking displays obfuscated values with optional just-in-time reveal workflows and reason capture. Includes bulk toggle, per-field tooltips from the data dictionary, conflict detection with higher-level permissions, and mapping to API/exports. Aligns with privacy/compliance needs and logs accesses for audit.

Acceptance Criteria
Toggle Field Read/Edit/Mask per Entity and Scope
Given I am an admin in Role Composer with access to role "Adjuster - Auto" And I open field toggles for "Payments.BankAccountNumber" And the scope is set to Line of Business = Auto, Jurisdiction = CA, Claim State = Open When I set permissions to Read = true, Edit = false, Mask = true And I save the role And I impersonate the test user for this role Then in UI modules (Claim, Policy, Party, Payments, Documents, Notes), the field renders as masked (e.g., ****1234) wherever displayed And the field input is disabled or absent in any edit form And any attempt to update the field via UI or API responds with 403 Forbidden and no change is persisted And the effective permission is visible in the role summary and version history
Just-in-Time Reveal with Reason Capture and Auto-Remask
Given I am a user with role "Supervisor - Auto" and reveal permission for masked fields And "Party.SSN" is masked for my role When I click Reveal on "Party.SSN" Then I am prompted to select a reason from a configured list or enter free text (minimum 10 characters) And I must confirm for a configured reveal window duration And upon confirmation, the full value is visible for the reveal window and redacted again after expiry And a reveal audit record is created with user, role, field, entity, claim ID, timestamp, reason, and window duration And if approval is required by policy, the reveal remains hidden until an approver approves in the workflow; if denied or expired, the value stays masked and an audit record is written And users without reveal permission cannot access the reveal action; attempts are blocked and audited
Bulk Toggle Across Multiple Fields with Preview and Undo
Given I am an admin in Role Composer editing role "TPA - Property" And I select 50 fields across Claim, Policy, and Party entities When I apply a bulk action "Mask = true" within scope LOB = Property, All jurisdictions, Claim States = Open, Closed Then a preview lists the count of fields to be updated and any conflicts detected And on confirm, the action is applied to all selected fields within the specified scope and a success summary is displayed (updated count, skipped count, conflict count) And I can undo the bulk change in the current session to revert all affected fields And a change log entry records the before/after state for each field and who performed the bulk action
Conflict Detection with Higher-Level Permissions and Least-Privilege Resolution
Given a higher-level role policy denies editing the Payments entity And at field level "Payments.BankAccountNumber" is set to Edit = true When I attempt to save the role Then the UI flags a conflict indicating higher-level deny overrides field-level edit And the effective permission resolves to Edit = false per least-privilege And the conflict is listed in the role validation report with entity, field, source of conflict, and resolved outcome And the role can be saved only after I acknowledge the resolution, with the resolved effective permissions shown
Per-Field Data Dictionary Tooltips
Given I hover the info icon next to "Party.SSN" in Role Composer When the tooltip opens Then it displays the field label, technical name, data type, sample format, PII/PHI designation, default mask pattern, and API/Export mapping And the content is sourced from the system data dictionary And if a dictionary entry is missing, the tooltip shows "Definition unavailable" and a link to request an entry
Permissions Enforced in API Responses and Exports
Given a test user token for role "Adjuster - Auto" where "Party.SSN" is Read = true, Mask = true, Edit = false When I call GET /claims/{id} and download a CSV export for the claim Then the API returns "Party.SSN" in masked form and rejects write attempts to the field with 403 Forbidden And the CSV export shows the masked representation for "Party.SSN" and excludes any fully non-readable fields from the file And the masking pattern in API and exports matches the configured mask pattern
Audit Log of Masked Field Access and Reveal Events
Given masked fields exist for a role and users interact with them When a user views a page with masked fields, attempts a reveal, is approved/denied, or attempts an unauthorized edit Then an immutable audit entry is recorded for each event including user, role, action, field, entity, claim ID, timestamp, reason (if any), outcome, and channel (UI/API) And audit entries are searchable by field, user, claim ID, and date range via the audit UI or API And the system prevents tampering by disallowing delete/update on audit records except via system retention processes, with retention governed by org policy
Conditional Access Rules by Context
"As a claims operations lead, I want role permissions to vary by jurisdiction and claim state so that users only see and do what’s appropriate for the cases they handle."
Description

A rule builder to apply permissions conditionally by line of business, jurisdiction, claim state, severity, channel, and team. Supports include/exclude lists, time-bound rules, and precedence with clear evaluation order. Provides a context-aware preview to test rules against sample claims. Caches compiled rules for low-latency evaluation in UI and APIs and integrates with workflow routing to ensure task visibility matches permissions.

Acceptance Criteria
Apply LOB + jurisdiction conditions to field-level permissions
Given a role "Auto Adjuster" has a conditional rule: include LOB = Auto AND jurisdiction IN [CA, NY] granting Edit on field Payout.Amount and Mask on field Claimant.SSN And the same role has an exclude list: jurisdiction IN [QC] When a user with this role views a claim with LOB = Auto and jurisdiction = CA Then Payout.Amount is editable, Claimant.SSN is masked, and no other fields gain elevated access And the same results are returned via the permissions API for that user and claim When the user views a claim with LOB = Auto and jurisdiction = QC Then access is denied for Payout.Amount (no edit) and Claimant.SSN remains masked due to exclude precedence When the user views a claim with LOB ≠ Auto (e.g., Homeowners) and jurisdiction = CA Then default deny applies for Payout.Amount (no edit) and Claimant.SSN is masked only if a masking baseline exists
Gate actions by claim state and severity
Given a rule allows the action ApprovePayment when claim_state = "Ready for Approval" AND severity <= 3 When a user with the role opens a claim with claim_state = "Ready for Approval" and severity = 2 Then the ApprovePayment action is enabled in UI and permitted by API (200) When the same user opens a claim with claim_state = "Investigation" and severity = 2 Then the ApprovePayment action is disabled in UI and API returns 403 When the user opens a claim with claim_state = "Ready for Approval" and severity = 4 Then the ApprovePayment action is disabled in UI and API returns 403
Time-bound include rules with channel and timezone support
Given a rule grants ReadOnly access for channel IN [Messaging, Email] between 18:00 and 06:00 America/New_York And current time is 19:30 America/New_York on a standard time day When a user accesses a Messaging-origin claim Then fields are readable but not editable and API returns permissions reflecting read-only When current time is 05:59 America/New_York Then the rule still applies (inclusive start/end), read-only persists When current time is 06:01 America/New_York (including DST transition days) Then the rule no longer applies and permissions revert according to other matching rules or default deny
Conflict resolution and precedence across overlapping rules
Given Rule A: include Team = Intake grants Read on Incident.Details And Rule B: exclude jurisdiction = TX denies all on Incident.Details And Rule C: include LOB = Auto AND jurisdiction = TX grants Edit on Incident.Details When evaluating a claim with Team = Intake, LOB = Auto, jurisdiction = TX Then Rule B (exclude) takes precedence and Incident.Details is not readable or editable When evaluating a claim with Team = Intake, LOB = Auto, jurisdiction = CA Then Rule A applies and Incident.Details is readable (not editable) And the system documents and enforces evaluation order: excludes override includes; more-specific rules override less-specific within the same allow/deny type; denials override grants when specificity is equal
Context-aware preview shows effective permissions and matched rules
Given an admin opens the Context Preview for a sample claim (LOB = Auto, jurisdiction = NY, claim_state = "Ready for Approval", severity = 2, channel = Messaging, team = Intake) When the preview is executed Then the UI lists matched rules in evaluation order with their conditions, allow/deny effect, time-window status (active/inactive), and the final effective permissions per field/action And the preview indicates which rule determined each permission (rule ID/version) And the preview result matches the runtime engine outputs for the same sample via API
Compiled rules cache performance and invalidation
Given compiled rules are cached for evaluation in UI and APIs When evaluating permissions for 1,000 distinct claim contexts under a warmed cache Then p95 evaluation latency per request is <= 25 ms and p99 <= 100 ms for both UI and API endpoints When an admin publishes any change to conditional rules Then all affected compiled caches are invalidated and refreshed within <= 5 seconds And subsequent evaluations reflect the change (no stale decisions beyond 5 seconds)
Workflow task visibility honors permissions
Given workflow routing assigns tasks based on claim context And a rule denies Read on claims where jurisdiction = TX for users in Team = Intake When such a user views their task queue Then tasks tied to TX claims are not visible or assignable When the rule is updated to allow Read for jurisdiction = TX Then the user’s queue reflects newly visible tasks within 60 seconds and direct task-open via UI and API returns 200 And while denied, attempting to open a hidden task via deep link returns 403 and does not reveal claim data
Role Inheritance and Targeted Overrides
"As an admin, I want to build specialized roles by inheriting from base roles and overriding a few items so that I can maintain consistency with minimal ongoing maintenance."
Description

Enable roles to inherit from one or more base roles with clear visualization of the inheritance tree and effective permissions. Allow targeted overrides at permission, field, and condition levels with deterministic conflict resolution. Include cloning and templating to reduce duplication, cycle detection, and guardrails that flag risky overrides before publish.

Acceptance Criteria
Multi-Base Role Inheritance with Effective Permissions Visualization
Given an admin creates role R inheriting from base roles A and B, When R is saved, Then the system computes effective permissions for R using the conflict resolution policy and stores them. Given role R, When the admin opens the Effective Permissions view, Then a tree shows R, A, and B with inheritance edges and each permission displays its source, intermediate values, and final effective value. Given a role with 1,000 or more permissions, When opening the Effective Permissions view, Then it renders within 2 seconds for the 95th percentile in the staging dataset. Given the admin hovers or clicks a permission P in R, Then the UI shows a trace explaining how P was resolved including bases, overrides, and the policy step applied.
Deterministic Conflict Resolution and Permission-Level Overrides
Rule: Conflicts are resolved in this order: (1) Child override > Base role value; (2) At the same level, Deny > Allow; (3) Among multiple bases at the same level, priority follows the base order configured in R (top to bottom). Given base A allows P and base B denies P and no child override, When base order is [A,B], Then effective P is Deny; When base order is [B,A], Then effective P is Deny. Given base A allows P and base B allows P and a child override sets P to Deny, Then effective P is Deny and the Effective Permissions view marks P as "Overridden by R". Given a child override for P is cleared, Then effective P recalculates immediately according to bases and policy and an audit log entry records actor, timestamp, and before/after values.
Field-Level Read/Edit/Mask Overrides by Condition
Given role R inherits field F=SSN as Read, When the admin adds a condition Jurisdiction=CA with Mask override for F, Then users with R viewing CA claims see F masked and see F unmasked for non-CA claims. Given overlapping conditions exist for field F, When priorities are ordered top-to-bottom, Then the first matching condition determines F's effective access and the others are ignored. Given a test claim with LineOfBusiness=Auto and State=TX and ClaimState=Open, When the admin previews as role R, Then field F access matches the configured conditional override exactly (Read-only, Editable, or Masked).
Inheritance Cycle Detection and Prevention
Given roles A, B, and C, When the admin attempts A→B, B→C, and C→A inheritance, Then the system blocks save, highlights A, B, and C, and displays "Inheritance cycle detected: A→B→C→A". Given any inheritance cycle is detected, Then Publish is disabled until the cycle is removed and validation passes without errors. Given a near-cycle (A inherits B, B inherits A) is introduced via clone or import, Then the system detects and blocks it prior to saving and offers a remediation link to remove one inheritance edge.
Role Cloning and Templating without Cross-Linkage
Given role R has multiple base roles, 15 permission overrides, and 3 conditional rules, When the admin clones R as R2, Then R2 is created with identical configuration, a new unique ID, reset version history, and no references back to R. Given a template T is created from R, When the admin generates role R3 from T and edits R3, Then changes to R3 do not affect T or R and vice versa. Given clone or template generation occurs, Then all overrides and conditions are preserved; any unresolved references are flagged and must be mapped before Publish can proceed.
Risky Override Guardrails and Pre-Publish Warnings
Given a role reduces access from Allow to Deny for permissions tagged Critical (e.g., ApprovePayment, EditPolicy), When attempting to Publish, Then a warning lists affected permissions and explicit confirmation is required to proceed. Given an override results in a role with zero read access to claim records, Then Publish is blocked and the message "Role has no claim read access" is shown with guidance to fix. Given child overrides disagree with more than 30% of inherited permissions, Then a "High override density" warning displays with count and percentage on the Publish checklist. Given an override sets Edit or Unmask on PII-tagged fields, Then a justification text is required and recorded in the audit log before Publish can complete.
Blueprint Templates Library
"As a new customer admin, I want to start from vetted role templates so that I can get to a compliant, working configuration in minutes."
Description

A curated library of prebuilt role blueprints for common personas (Adjuster, Senior Adjuster, SIU, Manager, External IA, Vendor) and organizational scales. Blueprints encode field-level controls and contextual rules aligned with industry practices and can be customized before publishing. Supports import/export (JSON/YAML), versioned updates, and a guided onboarding wizard to accelerate safe initial setup.

Acceptance Criteria
Curated Persona Blueprints Available
Given an admin with access to Role Composer When they open the Blueprint Templates Library Then they see prebuilt blueprints for Adjuster, Senior Adjuster, SIU, Manager, External IA, and Vendor And each blueprint displays name, description, persona, organizational scale tags (if any), version, and last updated date And each blueprint contains field-level controls (read/edit/mask) and contextual rules placeholders for line of business, jurisdiction, and claim state
Organizational Scale Variants
Given the admin selects the Adjuster blueprint When they choose the organizational scale "Small" Then the variant label "Small" is applied and visible And the effective permission set equals the Small variant definition Given the admin switches the variant to "Mid" or "Large" When they review the diff Then the delta in permissions is displayed And the selected variant's permissions are applied to the draft
Customize Blueprint Before Publishing
Given a selected blueprint When the admin toggles field-level read/edit/mask and edits contextual rules Then the changes are saved to a draft without modifying the source blueprint And a validation run marks any missing or conflicting rules Given the draft has validation errors When the admin attempts to publish Then publishing is blocked with specific error messages Given the draft passes validation When the admin publishes with a unique role name Then a new role is created in the tenant with a reference to the source blueprint and version
Contextual Rules Evaluation
Given a blueprint containing rules for line of business = Auto, jurisdiction = CA, claim state = Open When evaluated against a claim context matching those attributes Then fields with read permission are visible, edit permission are editable, and mask permission are obfuscated as defined Given a claim context not matching any rule When evaluated Then the fallback rule set applies as defined in the blueprint
Import and Export Blueprints
Given an existing blueprint in the library When the admin exports it as JSON Then the output validates against the current blueprint schema version and includes metadata (name, persona, version, rules, field controls) Given the same blueprint is exported as YAML When compared to the JSON export Then both represent the same data and can be re-imported losslessly Given an import file with schema violations When the admin attempts import Then the import is rejected with line and field-level error messages Given a valid JSON or YAML blueprint When imported Then it is added as a draft blueprint with its original version and marked as "Imported"
Versioned Updates and Diff
Given a prebuilt blueprint at version 1.2.0 is in use When version 1.3.0 becomes available from the library Then the admin is notified and can view a human-readable diff and a machine-readable changelog Given the admin accepts the update When the blueprint is upgraded Then existing published roles derived from 1.2.0 are not auto-changed And an option to create a new draft based on 1.3.0 is offered Given the admin declines the update When they dismiss the notice Then the current blueprint remains at 1.2.0 with a record of the deferral
Guided Onboarding Wizard
Given a first-time tenant with no roles published When the admin launches the onboarding wizard Then the wizard recommends at least three persona blueprints with organizational scale suggestions based on tenant inputs (lines of business, jurisdictions, team size) And the wizard requires review of field-level controls and contextual rules before proceeding And completion creates published roles or drafts according to admin choice and provides a downloadable export
Test User Simulator and Permission Preview
"As an admin, I want to simulate a user’s permissions on real scenarios so that I can validate roles before rollout and avoid misconfigurations."
Description

A safe preview mode to simulate a user’s effective permissions on specific claims and contexts without granting actual access. Supports impersonation of test users, shows visible vs. masked fields, and enumerates allowed actions and workflow tasks. Allows time-travel over claim state changes, generates shareable preview links for review, and records simulations for audit.

Acceptance Criteria
Impersonate Test User Against Specific Claim Context
Given an admin with Role Composer privileges and an existing test user profile And a claim with defined line of business, jurisdiction, and claim state When the admin selects the test user and the claim context and starts the simulation Then the simulator renders only entities and records the test user is permitted to access And a persistent non-dismissable banner indicates Preview Mode with the test user identity and claim ID And all write operations (create/update/delete) are blocked in preview mode and return a non-2xx with reason "preview_only" if invoked And any attempt to perform a blocked write is logged in the simulation audit with timestamp and endpoint And 95th percentile time to first render is <= 2 seconds for claims <= 1 MB payload
Field Visibility and Masking Preview
Given field-level permissions include read, edit, and mask rules for PII fields When the admin previews a claim with those fields Then read-only fields are visible but disabled with an "Read-only via role" indicator And masked fields display according to the configured mask pattern (e.g., last4 for SSN) and never expose raw values in DOM, network, or exports And fully hidden fields are omitted from UI and redacted from API responses in preview And a hover or info icon shows the rule and condition that caused read/edit/mask for each field And export/download in preview returns masked or redacted values consistent with UI
Allowed Actions and Workflow Tasks Enumeration
Given the role defines allowed actions and task permissions When the admin opens the Actions & Tasks panel during simulation Then only permitted actions are enabled and listed; disallowed actions appear disabled with a denial reason And the system displays the source rule for each action (rule name, condition matched, inheritance path) And only workflow tasks the role can view/assign/complete are shown with corresponding allowed operations And attempting a disabled action shows a rationale modal with rule evaluation summary And the enumeration matches backend authorization decisions 1:1 (no drift) in an automated contract test
Time-Travel Permission Preview Over Claim History
Given the claim has a state history and rule versions are time-stamped When the admin selects a past timestamp T in the simulator Then the system recomputes effective permissions as of T using historical claim data and rule version at T And the UI updates to reflect visibility, masking, actions, and tasks as of T And a diff view between T and Now highlights added/removed/changed permissions And time-travel mode is read-only and blocks action execution with reason "historical_view" And 95th percentile recomputation time is <= 3 seconds for histories up to 500 state transitions
Shareable Permission Preview Links
Given a completed simulation context (test user, claim, timestamp, filters) When the admin generates a shareable preview link Then the system creates a signed, tamper-evident URL containing only a reference token (no PII in query) And the link expires per policy (default 24 hours) and respects optional one-time access And only users with Permission Preview access can open the link; others receive 403 and an audit entry is recorded And opening the link reconstructs the exact simulation state immutably And any expired or tampered link returns 403 and invalidation is logged
Simulation Audit Trail and Export
Given auditing is enabled When a simulation starts, changes parameters, attempts actions, or ends Then an immutable audit record captures actor, test user, claim ID, context (LOB, jurisdiction, claim state), rule versions, timestamps, IP, user agent, attempted actions and outcomes And audit records are queryable by time range, actor, claim, and test user And audits can be exported to CSV and JSON with field-level masking preserved And default retention is 365 days and is tenant-configurable with enforcement jobs And a replay function can reconstruct the preview state from an audit record without granting live claim access
Inheritance and Condition Resolution Explanation
Given roles may inherit from blueprints and layer conditions by LOB, jurisdiction, and claim state When the admin inspects a field or action during simulation Then the system shows an explanation panel listing evaluated rules, inheritance overrides, matched conditions, and final precedence And conflicts display the tie-breaker applied (specificity > deny-overrides > allow) And explanations are available for 100% of displayed permissions and load within 1 second P95 And copying the explanation produces a redaction-safe text summary for review
Audit Trail, Versioning, and Rollback
"As a security officer, I want auditable history and rollback for role changes so that we remain compliant and can quickly recover from mistakes."
Description

Comprehensive audit logging of role changes with diffs, authorship, timestamps, and change reasons. Includes draft/review/publish workflow with approvals, semantic versioning, and the ability to roll back to prior versions without downtime. Exposes exportable audit reports, emits webhooks on publish for downstream systems, and integrates with SIEM for compliance.

Acceptance Criteria
Audit Log Entry on Role Change
Given an admin modifies a role’s permissions, conditions, or inheritance in Role Composer When they save a draft or publish the changes Then an immutable audit record is created with: roleId, roleName, changeType (create|update|delete), authorUserId, authorEmail, reason, timestamp (UTC ISO8601 with ms), versionBefore, versionAfter, and structured diff And the diff enumerates every changed field using JSON Pointer paths with before/after values, including field-level read/edit/mask and condition rules And PII values in diffs are masked per policy, and secrets are never persisted in plaintext And the record appears in the Audit Log UI and API within 5 seconds of the action and is assigned a monotonically increasing sequenceId for ordering And audit records are non-editable and non-deletable by users; only system retention policies may purge them, with purge events logged And audit retrieval is filterable by roleId, author, date range, changeType, and version, returning results in ≤ 2 seconds for up to 10,000 matching records
Draft-Review-Publish Workflow and Approvals
Given a role is in Draft When the author submits it for review with a required reason Then the status changes to In Review and designated reviewers receive notifications And a role cannot be published unless the configured approval rule is satisfied (at least one approver who is not the author), otherwise publish is blocked with a clear error And approvers can Approve or Request Changes with a mandatory comment; on Approve the status becomes Approved; on Request Changes the status returns to Draft with the comment visible And on Publish, the system records publisher identity, reason, timestamp, and links the publication to the approved review, creating an audit record And workflow transitions are constrained to Draft → In Review → Approved → Published or Draft → In Review → Draft; invalid transitions are blocked and logged And all reviewer actions are time-stamped, attributable, and accessible via UI and API
Semantic Versioning on Publish
Given a role with prior published versions When a new version is published Then the version string follows SemVer 2.0.0 format (MAJOR.MINOR.PATCH) and is unique per role And the system analyzes the change set and suggests a bump (MAJOR for broadened access or removal of constraints; MINOR for additive, non-breaking changes; PATCH for metadata-only changes), which the publisher must confirm And once published, the assigned version is immutable and displayed in UI, and included in API responses, audit entries, exports, and webhooks And version history for a role is sortable by publish timestamp and version, filterable, and retrievable via API within 2 seconds for up to 100 versions
Zero-Downtime Rollback to Prior Version
Given a role has at least one prior published version When an admin selects a prior version and confirms rollback with a reason Then the system creates a new published version whose content equals the selected version and records the rollback in the audit log And the rollback publish emits the same webhooks as a normal publish and increments the version per the confirmed bump policy And effective permissions for authorization checks switch to the rollback version within 60 seconds globally without service restarts, with no authorization 5xx errors during the transition And if the selected version is identical to the current, the rollback is blocked with a clear message And all active sessions honor the updated permissions on their next authorization evaluation, and background jobs pick up the change on next run
Exportable Audit Reports
Given an admin selects a date range and filters (roleId, author, changeType, version) When they request an export Then the system generates a report in CSV and JSON formats containing: eventId, timestamp (UTC), roleId, roleName, versionBefore, versionAfter, changeType, authorUserId, authorEmail, reason, and a summarized diff And CSV follows RFC 4180 with UTF-8 BOM; JSON is newline-delimited JSON; all timestamps are UTC ISO8601 with ms And for up to 100,000 events the export completes synchronously within 60 seconds; larger exports run asynchronously, notifying the user and providing a secure, expiring download link And each export is checksummed (SHA-256) with the hash displayed for integrity verification And export requests and downloads are themselves logged to the audit log
Publish Webhooks for Downstream Systems
Given a role is Published or Rolled Back When the publish completes Then a webhook is POSTed to each active endpoint within 5 seconds (p95), carrying payload fields: eventId, eventType (role.published|role.rolled_back), roleId, roleName, version, timestamp, publisherUserId, reason, and diff summary And each request includes an HMAC-SHA256 signature header over the body using the endpoint’s shared secret; TLS 1.2+ is required And endpoints returning 2xx are marked successful; non-2xx are retried with exponential backoff for up to 24 hours with jitter and idempotency via eventId And a dead-letter queue captures permanently failed deliveries; admins can replay events to a selected endpoint via UI and API And webhook delivery metrics (success rate, latency, retries) are visible per endpoint
SIEM Integration for Compliance
Given SIEM integration is configured When audit events occur Then events are streamed to the SIEM in near real-time (p95 under 2 minutes) over the selected transport (Syslog/TCP, Syslog/UDP, or HTTPS), using the configured schema (CEF or JSON) with required fields: eventId, timestamp, roleId, roleName, actor, action, versionBefore, versionAfter, reason, result And delivery is at-least-once with sequence numbers to enable de-duplication; transport is TLS 1.2+ for HTTPS and TCP Syslog; certificates are validated And batching, rate limiting, and back-pressure are supported without data loss; on outage, events buffer on disk up to 72 hours, after which backfill resumes automatically And integration health (connected, last sent time, queue depth, error rate) is visible in UI and emits alerts via existing monitoring hooks And configuration changes to the SIEM connector are audit-logged

JIT Pass

Just‑in‑time, time‑boxed access grants with purpose binding. Users request exactly what they need from a blocked screen, choose duration and scope, and obtain lightweight approvals. Access auto‑expires, is reason‑coded, and is fully audit‑logged—eliminating risky standing privileges while keeping work unblocked.

Requirements

Blocked Screen JIT Request Overlay
"As a claims manager, I want to request time-boxed access directly from the blocked screen so that I can continue processing a claim without breaking my workflow or context switching."
Description

Provide an in-context overlay on blocked screens that lets users request granular, time-boxed access without leaving their current workflow. The overlay auto-detects the resource context (claim, document, photo, task), pre-fills scope options (read, redact, edit, export), and offers duration presets with a maximum cap per policy. It supports keyboard navigation and WCAG AA accessibility, mobile-responsive layouts for field adjusters, localization, and persistence of unsent requests if connectivity drops. The overlay submits a single payload to the approvals service and policy engine, then updates the UI state in real time once access is granted or denied. This reduces toggling, keeps work unblocked, and ensures the request always references the exact loss and task in ClaimFlow.

Acceptance Criteria
Invoke Overlay From Blocked Screen With Context Prefill
Given a user encounters a blocked screen for a specific resource (claim/document/photo/task) When they activate Request Access via button or keyboard shortcut Then the JIT overlay opens in-place without navigation and without losing the current screen state Given the overlay opens on a blocked resource When it renders Then it auto-detects and displays the correct resource type and identifier and preselects valid scope options (read/redact/edit/export) for that resource Given policy duration caps exist for the user and resource When duration presets are displayed Then presets above the cap are hidden or disabled and a custom duration cannot exceed the cap
Submit Single Payload And Receive Real-Time Decision
Given required fields are valid (scope, duration, purpose/reason) When the user submits the request Then the client sends a single payload to the approvals service including resource context (loss and task IDs), scope, duration (start/end/TTL), reason code and free-text, requester identity, and policy reference Given the approvals service returns Granted When the decision is received Then the overlay closes and the blocked UI transitions to an unblocked state with the granted scope within 2 seconds, and a success toast is announced via aria-live Given the approvals service returns Denied When the decision is received Then the overlay remains open, shows the denial reason, and offers an allowed next action (e.g., change scope or duration) if policy permits Given the request fails due to a client-side validation error When the user attempts to submit Then submission is prevented and inline errors are shown and announced
WCAG AA Keyboard And Screen Reader Accessibility
Given a user navigates with keyboard only When the overlay opens Then focus moves to the overlay header, focus is trapped within the overlay, Esc closes the overlay, and all controls are reachable in a logical tab order with visible focus indicators Given a screen reader user When interacting with the overlay Then all fields and controls have programmatically associated labels, state, and instructions and dynamic updates (errors, decision status) are announced via aria-live Given WCAG 2.1 AA requirements When rendering the overlay Then text and interactive elements meet contrast ratio ≥ 4.5:1 and no information is conveyed by color alone
Mobile-Responsive Overlay For Field Adjusters
Given a device viewport width ≤ 414px When the overlay opens Then the layout renders in a single column without horizontal scrolling and content reflows without overlap or truncation Given touch interaction on mobile When tapping any control Then touch targets are ≥ 44x44 dp and the on-screen keyboard does not cover the active input (the view scrolls as needed) Given network-constrained conditions (3G) When opening the overlay Then the overlay becomes interactive within 1.5 seconds using cached resources where available
Localization And RTL Support
Given the user locale is Spanish (es) When the overlay opens Then all user-facing text, date/time formats, duration labels, and validation messages are localized in Spanish with no truncated strings Given the user locale is an RTL language (e.g., ar) When the overlay opens Then the layout mirrors correctly, focus order follows visual order, and bidirectional text renders appropriately Given unsupported locale selection When the overlay opens Then it falls back to English with a logged telemetry event for missing translation keys
Offline Persistence And Resume
Given the device loses connectivity before submission When the user has entered scope, duration, and reason Then the overlay persists the unsent request locally (including resource context) without user action Given connectivity is restored within 24 hours When the user revisits the same blocked resource Then the overlay offers to restore the unsent request with all previously entered values Given a restored draft When the user submits after reconnecting Then exactly one request is submitted using an idempotency key to prevent duplicates
Policy Cap Enforcement And Purpose Binding
Given a policy cap of 2 hours for the requested scope When the user selects or enters a duration exceeding 2 hours Then the control prevents the selection and displays a clear validation message indicating the maximum allowed duration Given purpose binding is required by policy When the user completes the form Then a reason code from the allowed set is mandatory and free-text justification (up to 500 characters) is captured and included in the request payload Given user role does not allow certain scopes for the resource When the overlay renders Then disallowed scopes are disabled with an explanatory tooltip and are not included in the submission
Purpose Binding & Reason Codes
"As an adjuster, I want to specify a purpose and reason code when requesting access so that the access I receive is appropriate, compliant, and fully auditable."
Description

Make purpose binding mandatory for every JIT Pass by requiring selection of a standardized reason code (e.g., fraud review, compliance QA, supervisor override) plus a brief free-text justification. Bind the request to a specific claim ID, task ID, and customer interaction when available. Enforce policy-specific constraints (e.g., sensitive-PHI requires compliance code and shorter maximum duration). Store purpose metadata with the access token and propagate it to audit logs, notifications, and analytics so downstream systems can attribute actions to an approved purpose and detect anomalous use.

Acceptance Criteria
Mandatory reason code and justification on JIT Pass request
Given a user attempts to create a JIT Pass from a blocked screen When the request form is submitted Then a standardized reason code must be selected from a system-managed list and a free-text justification of 10–500 characters must be provided Given no reason code is selected or the justification length is outside 10–500 characters When the user submits Then the request is rejected with a client-side validation message and the API returns HTTP 400 with error code MISSING_OR_INVALID_PURPOSE Given a valid submission When the API creates the JIT Pass Then the persisted record contains reason_code and justification as provided and the response echoes these fields
Bind pass to claim, task, and interaction context
Given the pass is initiated from a claim or task view with Claim ID and/or Task ID available When the JIT Pass is created Then claim_id and/or task_id are captured on the pass and are immutable for the life of the pass Given the pass is initiated without a Claim ID but the user intends to access claim data When submitting the request Then the user must enter a valid existing Claim ID; otherwise the request is blocked and the API returns HTTP 400 INVALID_CONTEXT Given a real-time customer interaction is active (e.g., call/chat) with interaction_id available When creating the pass Then interaction_id is captured and stored with the pass Given actions are performed using the JIT Pass When those actions target resources outside the bound claim_id/task_id Then the action is denied with HTTP 403 OUT_OF_SCOPE and an audit entry is recorded
Policy constraints for sensitive PHI access
Given the requested scope includes resources tagged sensitive_PHI or the claim is flagged sensitive When creating the JIT Pass Then only reason codes COMPLIANCE_QA or SUPERVISOR_OVERRIDE are selectable and the maximum duration selectable is 15 minutes Given a non-sensitive request When creating the JIT Pass Then the maximum duration selectable is 60 minutes Given a sensitive request with duration > 15 minutes or a disallowed reason code When the user submits Then the request is blocked with HTTP 400 POLICY_VIOLATION and a message specifying the violated rule Given a sensitive request is approved When the pass is active Then extensions are disabled; an extension attempt returns HTTP 409 EXTENSION_NOT_ALLOWED
Store and propagate purpose metadata to token, logs, notifications, analytics
Given a JIT Pass is approved When the access token is minted Then the token contains embedded claims: pass_id, reason_code, justification, claim_id, task_id, interaction_id (when present), scope, approver_id, issued_at, expires_at Given a JIT Pass is approved When the audit log entry is written Then it includes pass_id, requester_id, approver_id, reason_code, justification, claim_id, task_id, interaction_id (when present), scope, policy_flags, issued_at, expires_at Given notifications are dispatched to approvers or security channels When the pass is created Then the notification payload includes reason_code, justification, claim_id, task_id, duration, requester_id, and approver_id Given analytics ingestion is operational When actions occur under a JIT Pass Then 100% of emitted event records include pass_id, reason_code, and claim_id/task_id, with missing propagation rate ≤ 0.1% over a 24-hour window
Auto-expiry and post-expiry enforcement
Given a JIT Pass with duration D minutes When current time ≥ issued_at + D Then the pass status transitions to EXPIRED automatically without user action Given a pass is expired When a user attempts any protected action with the expired token Then the action is denied with HTTP 401/403 EXPIRED and an audit entry with reason EXPIRED is recorded within 1 second Given a pass expires while the requester has the UI open When expiry occurs Then an in-session banner appears within 5 seconds indicating access expired and offering to request a new pass Given expiry occurs When events are emitted Then an expiration event is written to the audit stream and analytics within 5 seconds of expiry
Downstream attribution and anomaly detection signal
Given any read/write action performed under a JIT Pass When the event is produced to downstream systems Then the event includes pass_id, reason_code, claim_id/task_id, and a purpose string to enable attribution Given an action is inconsistent with the approved purpose (e.g., reason_code=FRAUD_REVIEW but action modifies payout) When the anomaly detector evaluates the event Then an ANOMALOUS_USE signal is emitted to the security topic within 60 seconds and an alert is sent to the owning team Given an ANOMALOUS_USE signal is emitted When auditors query the audit trail Then they can retrieve in a single view the originating pass_id, user, purpose metadata, and the offending action details
Auto-Expiry & Immediate Revocation
"As a security-conscious admin, I want JIT grants to auto-expire and revoke immediately so that no one retains standing access beyond the approved window."
Description

Enforce strict start/end times on all granted access and automatically revoke privileges at expiry, even across active sessions. On revocation, the UI must immediately downgrade or block the relevant actions and mask sensitive fields; API tokens and roles are invalidated server-side. Include a resilient scheduler with at-least-once revocation, catch-up processing after outages, and guardrails to prevent grant extensions without re-approval. Provide a visible countdown timer and optional pre-expiry notification to the user. Support manual revoke by approvers or admins with instant propagation.

Acceptance Criteria
Auto-expiry revokes active session privileges within 5 seconds
Given a user has an active JIT Pass that reaches its end time When the pass expires Then within 5 seconds the UI disables all privileged actions bound to the pass scope, and sensitive fields in affected views are masked And all temporary roles and API tokens issued for the pass are invalidated server-side And any privileged API requests made after expiry receive 401/403 with a reason of "grant_expired" And active realtime connections receive a revocation event and the client applies the downgrade without requiring a page refresh
Manual revoke propagates instantly across UI and API
Given a JIT Pass is currently active When an approver or admin triggers a manual revoke for that pass Then within 5 seconds all of the user’s clients reflect loss of privileges (actions disabled, sensitive fields masked) And all tokens/roles tied to the pass are invalidated server-side And subsequent API calls using those tokens return 401/403 with a reason of "grant_revoked" And an audit log entry is recorded with actor, reason code, pass ID, scope, and timestamp
Resilient scheduler performs at-least-once catch-up after outage
Given the revocation scheduler is offline while one or more passes expire When the scheduler service recovers Then all passes whose end time has elapsed are revoked at-least-once within 1 minute of recovery And revocation is idempotent (no duplicate side effects or errors if processed twice) And no expired pass remains active after catch-up completes And a health metric and audit log record the count of processed catch-up revocations
Guardrail prevents duration/scope extension without re-approval
Given a user has an active pass When the user attempts to extend the duration or expand the scope of the pass without submitting for approval Then the server rejects the change and the UI prompts the re-approval flow And the attempted extension is logged with user, pass ID, requested changes, and timestamp And when a re-approved change is granted, a new pass/version is created; the original grant is not silently extended
Visible countdown timer and optional pre-expiry notification
Given a user has an active pass When the user is on a screen where the pass applies Then a countdown timer shows remaining time in mm:ss, updates at least once per second, and is accurate to within ±1 second And when remaining time equals the user-selected pre-expiry lead time (1–15 minutes), a UI notification is displayed until acknowledged or expiry And when the pass expires, the timer switches to "Expired" and privileged UI is downgraded within 5 seconds
Scope-aware downgrade and masking at revocation/expiry
Given a pass grants scope S covering specific actions and fields When the pass is revoked or expires Then only actions and fields within scope S are disabled/masked; unrelated application functionality remains available And masked fields display a standard placeholder (e.g., ••••) and cannot be copied or inspected via the DOM And attempts to invoke out-of-scope privileged APIs return 403 with a reason of "insufficient_scope"
Enforce start time activation and pre-start blocking
Given a pass has a future start time When the user attempts a privileged action before the start time Then the UI blocks the action, sensitive fields remain masked, and the API returns 403 with a reason of "grant_not_active" And when the start time is reached, privileges activate within 5 seconds without requiring a refresh, the countdown timer starts, and privileged actions become enabled
Lightweight Approval Routing
"As a team lead, I want to approve or deny access with a single click and clear context so that I can keep my team moving without compromising policy or oversight."
Description

Implement a policy-driven approval workflow that routes JIT requests to the right approver(s) with one-click approval/deny actions via in-app, email, or Slack/Teams. Support auto-approval rules for low-risk combinations (role/resource/duration) and multi-step approvals for sensitive scopes. Include timeouts with escalation, separation-of-duties checks, and contextualized request summaries (purpose, scope, claim/task links, risk score). Surface decision rationale capture and ensure decisions and timestamps are immutably logged. Minimize approver friction while maintaining compliance-grade controls.

Acceptance Criteria
Policy-Driven Routing to Correct Approver(s)
Given a JIT access request contains requester identity, role, resource, scope, duration, purpose, claim/task link, and risk score And routing policies map role/resource/scope/duration/purpose to approver groups with priority When the request is submitted Then the system selects approver(s) per the highest-priority matching rule and records the rule_id on the request And notifications are sent to all required approver(s) within 2 seconds And no approver outside the matched policy receives the request And the selected approver list is visible on the request detail And changes to routing after submission are prohibited except by policy-defined reassignments, which are logged
One-Click Approval/Deny via In‑App, Email, and Slack/Teams
Given an approver receives an approval request via in‑app, email, Slack, or Teams And action links/buttons are signed, single‑use, approver‑bound, and expire in 15 minutes When the approver clicks Approve or Deny in any channel while authenticated Then the decision is recorded in ≤2 seconds with channel metadata and the requester is notified And no secondary confirmation is required unless policy mandates rationale And duplicate or repeated clicks are idempotent and return the final state And if two approvers act concurrently, the first persisted decision is authoritative and later attempts receive “already decided” And if the approver is not authenticated, a single login step precedes the action and preserves context to complete in ≤2 total clicks
Auto-Approval for Low-Risk Requests
Given a policy defines low‑risk combinations of role/resource/scope/duration and a risk_score threshold <= T_low When a matching request is submitted Then the system auto‑approves the request in ≤1 second without human intervention And the decision reason is set to "Auto‑Approved per policy" with rule_id recorded And the requester is notified and the approval is logged immutably with timestamps
Multi-Step Approval for Sensitive Scopes
Given a policy defines sensitive scopes requiring N sequential and/or parallel approval steps (e.g., Manager -> Security -> Data Owner) When a matching request is submitted Then the workflow enforces the defined order and blocks step n+1 until step n completes And any Deny at any step terminates the request as Denied And for parallel steps, all required approvers must approve before progressing And the requester and approvers can see current step, pending approvers, and SLA timers And policy updates do not retroactively alter in‑flight step order; any change creates a new workflow version for subsequent requests
Timeouts with Escalation and Auto-Deny
Given a policy defines T1 (escalation) and T2 (final timeout) for pending approvals When no approver acts by T1 Then the request escalates to the configured backup approver group and notifies prior and new approvers When no approver acts by T2 Then the system auto‑denies with reason "Timeout" and notifies requester and approvers And any late action after auto‑deny is blocked with an "expired" message and logged And all timeout and escalation events are logged with RFC3339 timestamps and actor/system identifiers
Separation-of-Duties and Conflict Checks
Given SoD rules prohibit self‑approval and other conflicts (e.g., requester’s manager chain, change implementer vs approver, same duty group) When routing approvers Then conflicted users are excluded from assignment and alternates are selected per policy When a conflicted approver attempts to act (via any channel) Then the system blocks the action with a SoD violation message and logs the attempt And if policy allows break‑glass exceptions, an explicit override path requires mandatory rationale and secondary approval by a non‑conflicted role
Contextualized Summary and Rationale Capture with Immutable Audit
Given an approver views a pending request in‑app, email, Slack, or Teams Then the summary displays purpose (reason code), scope, resource, requested duration, requester, claim/task link, risk score, matched policy rule_id, SoD status, and SLA timers consistently across channels When an approver submits a decision Then rationale is required for Deny and for approvals where risk_score >= T_high; otherwise rationale is optional but captured if provided And an immutable audit record is written containing request_id, decision, rationale, approver_id, channel, rule_id, and RFC3339 timestamps with a content hash; records are append‑only and queryable by request_id and claim/task id And audit records are generated even for auto‑approvals, escalations, timeouts, and blocked/SoD attempts
Policy Engine & Access Templates
"As a security administrator, I want configurable policies and reusable access templates so that I can enforce least privilege consistently and adapt controls without code changes."
Description

Provide an admin-configurable policy engine to define JIT access templates by role, resource sensitivity, environment, and action scope. Policies specify allowed scopes, maximum durations, required purpose codes, approver tiers, MFA requirements, and auto-approval thresholds. Include versioning, draft/test modes, rule simulation with sample requests, and import/export for migration between environments. Expose policies through a service that evaluates requests deterministically and returns a decision, required steps, and computed risk indicators to downstream components.

Acceptance Criteria
Admin creates and validates JIT policy template
Given an admin with policy-management permissions When they create a new policy template specifying roles, environments, resource sensitivity, resource identifiers, allowed action scopes, maximum durations per action, required purpose codes, approver tiers per sensitivity, MFA requirement rules, and auto-approval risk thresholds Then the system saves the template as Version 1 in Draft if all fields pass schema and domain validation And invalid inputs are rejected with field-level errors and no template is created And maximum durations are positive integers in minutes and do not exceed the platform maximum And action scopes are selected from the controlled list and are unique And purpose codes exist and are active in the catalog And approver tiers are ordered and reference valid approver roles And MFA rules are one of [none, step_up, always] And any unspecified action scope defaults to deny
Deterministic evaluation API contract
Given a valid evaluation request payload containing userId, userRoles, environment, resourceId, resourceSensitivity, action, purposeCode, requestedDurationMinutes, requestId, and requestTimestamp When POSTed to /v1/policy/evaluate Then the response status is 200 and the body contains: decision in {deny, approve, require_approval}; requiredSteps array from {mfa, tier1_approval, tier2_approval, ...}; riskIndicators with durationRisk, sensitivityRisk, purposeRisk, anomalyScore, totalScore; appliedPolicyId and appliedPolicyVersion; and ruleTrace And repeated invocations with identical payload return identical body values (deterministic) and a stable decisionHash And if no matching policy exists, decision == deny with reasonCode "no_matching_policy" And p95 latency is <= 150 ms under 50 rps in staging
Auto-approval thresholds and MFA enforcement
Given an active policy with auto-approval threshold T and MFA rule configuration by sensitivity When a request's computed totalScore <= T, requestedDurationMinutes <= the policy maximum for the action, purposeCode is required and supplied, and the environment is allowed Then decision == approve And requiredSteps includes mfa if and only if the resourceSensitivity meets the policy's step_up or always threshold And when any of these conditions are not met, decision != approve and requiredSteps enumerate the missing steps or deny with a specific reasonCode
Approver tiers ordering and separation of duties
Given an active policy requiring tier1 and tier2 approver roles for specified sensitivities When a request evaluates to require_approval Then requiredSteps lists tier1_approval before tier2_approval and includes the approver role identifiers for each tier And if the requester holds any approver role for a required tier, that tier is flagged requires_different_approver == true in requiredSteps And if tier1_approval is denied, the decision becomes deny and tier2_approval is not requested
Policy versioning, draft/active/archived lifecycle and simulation
Given a policy template in Draft (version N) When an admin runs a simulation with a sample request Then the system returns a simulated decision and ruleTrace using version N and does not affect live evaluations And when the admin publishes version N, it becomes Active and immutable, the previous Active (if any) becomes Archived, and N is recorded with publishedBy and timestamp And any edit to an Active policy creates a new Draft version N+1 And rolling back selects a specific Archived version to become the new Active without content changes
Import/export for environment migration with dry-run validation
Given one or more policies selected for export When the admin exports them Then the system produces a signed JSON bundle containing schemaVersion, policy definitions, versions, references, and checksums And when the admin performs an import in Dry Run into another environment Then the system validates schema and references (roles, purpose codes, resource identifiers), reports conflicts and required mappings, and makes no changes And when the admin executes the import with required mappings, policies are created with correct versions, Active states optionally staged per flag, checksums match, and the operation is all-or-nothing with error reporting on failure
Audit logging and traceability of evaluations and simulations
Given any evaluation or simulation When the decision result is produced Then an immutable audit record is written containing requestId, request payload hash, decision, requiredSteps, riskIndicators, appliedPolicyId and version, reasonCodes, and timestamp And simulation records are flagged as simulation and excluded from live access audit metrics And audit records are queryable by requestId and time window and can be exported as JSON
End-to-End Audit Logging & Export
"As a compliance officer, I want complete, exportable audit logs of JIT access so that I can demonstrate control effectiveness and investigate issues quickly."
Description

Capture a complete, tamper-evident trail for each request: requester identity, claim/task context, purpose code and justification, policy evaluation result, approver decisions, grant issuance, scope changes, access utilization events, and revocation (auto/manual). Store audit records in an append-only log with retention controls and checksum verification. Provide search, filters, and dashboards in ClaimFlow, plus export via API/CSV and streaming to SIEM/Log platforms. Support field-level visibility controls to avoid exposing sensitive PHI in general logs while retaining compliance evidence.

Acceptance Criteria
Lifecycle Event Capture for JIT Pass Requests
Given a user submits a JIT Pass request tied to a specific claim/task And the request proceeds through policy evaluation, approval, grant issuance, scope changes, access utilization, and revocation (auto or manual) When the system processes each step Then an audit record is created for each event type with a shared correlation ID And each record includes: requester identity (user ID, role), claim/task identifiers, purpose code, free‑text justification, policy evaluation result (allow/deny with rule ID), approver identity/decision/reason, granted scope (resources/permissions), expiry timestamp, event type, event timestamp (UTC, ISO‑8601), actor (system/user), and revocation type (auto/manual) with reason And access utilization events include resource identifier, action, outcome (success/failure), and client metadata (IP, user agent) And no required field is null or empty And the sequence of timestamps is non‑decreasing across the lifecycle
Append‑Only Tamper‑Evident Log with Chain Verification
Given the audit log store is configured When any audit record is written Then it is appended only (no in‑place updates or deletes) and assigned an immutable sequential ID And a cryptographic checksum is computed over the record and the previous record’s checksum to form a verifiable chain (default SHA‑256) And a public verification endpoint/CLI validates the chain and returns OK with the last verified ID When an attempt is made to update or delete an existing record via APIs or storage Then the operation is rejected with HTTP 409/Forbidden and the attempt is itself audited And periodic verification (at least daily) produces an attestation artifact with the latest chain hash
Retention Controls and Legal Hold
Given a tenant‑level retention period (e.g., 7 years) is configured by an authorized admin When the retention job runs Then records older than the retention period are permanently pruned without breaking chain verifiability by anchoring periodic summary hashes And a legal hold flag on a claim/request prevents deletion of matching records regardless of age And all retention configuration changes and deletions are audit‑logged with actor, before/after values, and timestamp And an API/CLI reports effective retention settings and next scheduled purge time
Field‑Level PHI Visibility Controls
Given fields may contain PHI When audit data is viewed via general logs/UI/API by users without PHI privileges Then PHI‑designated fields are redacted (e.g., ****) or replaced with salted hashes while non‑PHI fields remain visible And when viewed by users with the Audit.PHI.View permission and an approved purpose code Then PHI fields are revealed And every PHI view/export event is itself audit‑logged with viewer identity, purpose, and timestamp And exports default to redacted mode; including PHI requires an explicit includePHI=true flag and appropriate permission And field‑level visibility rules are centrally managed and testable via a policy endpoint returning which fields are PHI
Search, Filters, and Dashboards in ClaimFlow UI
Given the Audit UI is accessible to authorized users When the user applies filters (date/time range, requester, claim/task ID, purpose code, decision, event type, approver, outcome) and free‑text search over justification Then results reflect the logical AND of filters and highlight matched text And the first page of 50 results returns in ≤2 seconds on a dataset of ≥1,000,000 records in staging baseline And results are paginated with stable cursors and sortable by timestamp and severity And selecting a record opens a detail view with the full field set and correlation timeline And dashboards display counts and trends by event type, purpose code, approvals vs revocations, and PHI‑view events with selectable date ranges
API and CSV Export with Integrity Metadata
Given an auditor with export permissions requests an export via API or UI When exporting with a filter set and date range Then the system generates a paginated export (JSON lines and CSV options) with a manifest containing total records, time window, filters, and SHA‑256 checksums per chunk And CSV includes a documented header row with field names and data types; timestamps are UTC ISO‑8601; nulls are blank And large exports are chunked to ≤100MB per file and support resume via cursor tokens; rate limits are enforced and communicated And the export can be downloaded or delivered to an external object store (e.g., S3‑compatible) with server‑side encryption enabled And an option to include PHI is disabled by default and requires elevated permission and purpose code
Real‑Time Streaming to External SIEM/Log Platforms
Given a tenant configures a streaming destination (HTTPS webhook JSON and/or Syslog TCP/TLS) When audit events occur Then events are delivered in near real‑time with at‑least‑once semantics, monotonically ordered per correlation ID, and include an idempotency key for deduplication And payloads are signed (HMAC or mTLS) and retried with exponential backoff on non‑2xx/network failures; failures after max retries are sent to a dead‑letter queue with operator alerting And destination configuration supports health checks, test sends, and field redaction rules matching PHI visibility controls And a delivery metrics dashboard shows success rate, lag, and DLQ volumes over time
IAM Integration for Ephemeral Privileges
"As an IT administrator, I want JIT Pass to leverage our existing SSO/IAM so that ephemeral privileges are enforced consistently across systems without manual role management."
Description

Integrate with enterprise IdPs and IAM (OIDC/SAML, SCIM) to provision and de-provision ephemeral roles or claims tied to JIT grants. Map ClaimFlow resources and actions to IAM groups/entitlements and issue short-lived tokens with embedded scope, purpose, and expiry. Ensure real-time propagation across microservices and downstream systems, with least-privilege defaults on integration failure. Support step-up MFA per policy at approval or grant time and maintain compatibility with mobile SSO for field adjusters working offline with sync-on-reconnect.

Acceptance Criteria
SSO JIT Grant via OIDC/SAML
Given a user is authenticated via enterprise OIDC/SAML SSO and attempts an elevated action blocked by policy When the user submits a JIT request with resource, action(s), purpose (reason code), and a duration between 5 and 60 minutes inclusive And the request is approved by an authorized approver Then a JIT grant is created and a short‑lived access token is issued within 2 seconds containing aud=ClaimFlow, scope matching the approved actions, purpose, exp=now+duration, iat, sub, jti, and grant_id And the requested action succeeds only while the token is valid and within scope And out‑of‑scope requests are denied with HTTP 403 and error code JIT_SCOPE_VIOLATION And the grant_id is returned to the client for subsequent calls
SCIM Ephemeral Entitlement Provisioning
Given a JIT grant is approved for a user When provisioning occurs Then the user is added via SCIM PATCH to an ephemeral entitlement/group mapped to "{resource}:{action}" with an attribute ttl equal to the grant expiry And on grant expiry or revocation, SCIM PATCH removes the membership within 5 seconds And provisioning/deprovisioning is idempotent and retried up to 3 times with exponential backoff on 5xx And on permanent failure the system enforces least‑privilege (deny) and emits alert event IAM_SCIM_FAILURE
Short‑Lived Token Claims and Validation
Given a JIT grant is active When issuing tokens Then tokens are signed using RS256 or ES256 and include claims: sub, email, scope, purpose, exp, iat, jti, grant_id, aud=ClaimFlow And token TTL is between 5 and 60 minutes and cannot be extended without a new approval And services validate signature, audience, exp, scope, and purpose against the requested operation before authorizing And tokens are rejected if clock skew exceeds 60 seconds or jti appears on the revocation list
Real‑Time Propagation and Fail‑Safe Deny
Given a JIT grant is approved, updated, or revoked When propagation events are published Then all ClaimFlow microservices and downstream systems reflect the new authorization state within 3 seconds (p95) and 5 seconds (p99) And until propagation confirmation, services default to least‑privilege (deny) for elevated actions And events are signed and versioned; out‑of‑order or stale versions are detected and ignored
Step‑Up MFA Enforcement
Given policy requires step‑up MFA for the target resource or approval path When the user requests or activates a JIT grant Then the user must complete MFA (TOTP, push, or WebAuthn) achieving AAL2 or higher before the grant becomes active And 5 consecutive failed MFA attempts lock the grant for 10 minutes And successful MFA is bound to grant_id and logged with method and AAL
Mobile SSO and Offline Access
Given a field adjuster is signed in via mobile OIDC with PKCE and becomes offline When the user has an active, offline‑eligible JIT grant that is not expired Then offline access to permitted actions is enforced using a locally cached, encrypted token and policy cache And if the grant expires while offline, elevated actions are blocked until reconnect and reauthorization And upon reconnect, audit logs and SCIM changes are synced within 10 seconds with server state winning on conflicts
Auto‑Expiry, Revocation, and Auditability
Given a JIT grant is active When the grant expires or is revoked by an approver Then elevated access is blocked within 3 seconds (p95) across all services and downstream systems And any sessions presenting the token are invalidated; subsequent requests return 401 with error JIT_EXPIRED And audit records include requester, approver, reason code, scope, duration, timestamps (requested, approved, activated, expired/revoked), and propagation metrics, retained for at least 7 years

Access Simulator

Instant “see‑as” preview of what a given user would see on a specific claim. Simulate by role, purpose, and jurisdiction to verify field‑level visibility, masks, and redactions before rollout. Share a snapshot with QA/Compliance to prevent surprises, speed audits, and build confidence in every change.

Requirements

See-As Target Selector & Context Picker
"As a claims administrator, I want to choose a user/role, purpose, and jurisdiction for a claim so that I can preview exactly what that user would see before changes go live."
Description

Provide a guided selector that lets authorized users choose the target of a simulation by user, role, or persona, plus purpose of access and governing jurisdiction, scoped to a specific claim. The selector must support autocomplete for users/roles, validation against existing policies, and clear error handling when combinations are invalid or unsupported. It pre-fills the current claim, handles multi-jurisdiction claims via precedence rules, and allows saving reusable presets. The selector initializes the simulator with a consistent context payload consumed by the policy engine and displays the active context in the UI so results are explainable and reproducible.

Acceptance Criteria
Autocomplete Target Selection by User/Role/Persona
Given I am an authorized user on a claim detail page and the See‑As Target Selector is open When I type at least 2 characters into the Target field Then the selector returns up to 10 suggestions across Users, Roles, and Personas sorted by relevance within 400ms p95 And each suggestion displays a type badge (User/Role/Persona) and primary identifier (name and email for users; display name for roles/personas) And keyboard navigation (Up/Down/Enter/Escape) and mouse selection are supported And selecting a suggestion populates targetType and targetId and moves focus to Purpose of access And if no results are found, a No matches message is shown with guidance to refine the query
Pre-Fill and Enforce Claim Scope
Given I open the selector from a claim detail view with claimId present Then the Claim field is pre-filled with the current claimId and cannot be cleared And attempting to edit the Claim field shows a tooltip indicating the selector is scoped to the current claim When the selector is opened outside a claim context Then the user is required to select a claimId before Start Simulation becomes enabled And the selector prevents starting a simulation if claimId is missing
Policy Validation and Invalid Combination Handling
Given I have selected a target (user/role/persona), a purpose of access, and a jurisdiction When I click Validate or Start Simulation Then the selector requests a policy decision for the selected combination and receives allow/deny with rationale And if allowed, the UI shows Valid with policyVersion and ruleId and Start Simulation remains enabled And if denied, Start Simulation is disabled and an inline error displays the denial reason with policy rule reference and recovery steps And the validation result is recorded with a correlationId for audit
Multi-Jurisdiction Precedence Resolution
Given the claim has multiple jurisdictions configured with precedence rules When I select a target and purpose Then the governing jurisdiction is auto-resolved according to precedence and displayed as selected And an info tip explains why it was chosen and which alternatives were considered And if precedence yields multiple allowed options, I am prompted to choose among allowed jurisdictions while disallowed options are disabled with a policy reason And the resolved jurisdiction is included in the context and used for policy validation
Save, Apply, Rename, and Delete Context Presets
Given I have a valid context (claimId, targetType, targetId, purpose, jurisdiction) When I save it as a preset with a unique name Then the preset is stored with createdBy and timestamp and appears in the Presets list And applying the preset restores all fields identically and re-validates against current policy before enabling Start Simulation And saving with a duplicate name prompts to Overwrite or Rename; choosing Overwrite updates the existing preset And I can rename or delete my presets with confirmation and audit logging And presets are private to the creator by default
Consistent Context Payload Initialization and UI Display
Given the selected context has been validated When I click Start Simulation Then the simulator is initialized with a JSON payload that includes: claimId (string), targetType (user|role|persona), targetId (string), purpose (string/enum), jurisdiction (string/ISO), policyVersion (semver), requestedBy (userId), requestedAt (ISO‑8601 UTC), contextHash (sha‑256) And the exact payload is written to audit logs with a correlationId And the UI displays an Active Context summary showing claimId, target, purpose, jurisdiction, policyVersion, and contextHash in a persistent banner And a Copy context action copies the JSON payload to the clipboard And repeating with identical inputs produces the same contextHash
Policy Evaluation Parity & Version Toggle
"As a product owner, I want to simulate against both current and staged policies and see what changes so that I can validate access impacts before rollout."
Description

Back the simulator with the same rules engine used in production access control so outputs are identical given the same inputs. Accept a context payload (user/role, purpose, jurisdiction, claim metadata) and compute field-level visibility, masking, and redactions deterministically. Support toggling between current (production) and staged policy versions and present a concise diff of what changes between versions. Enforce performance SLAs (e.g., p95 under 2 seconds for typical claims) and provide structured reasons for each visibility decision to aid troubleshooting. Ensure the engine honors jurisdictional overrides, purpose-based minimization, and data classification tags.

Acceptance Criteria
Simulator Parity with Production Engine
Given a fixed context payload and claim snapshot identical to production inputs When I evaluate access with the simulator using policyVersion=current Then field-level visibility, mask, and redaction decisions match production results for every field And the total counts of visible, hidden, masked, and redacted fields match production And repeated evaluations with the same inputs produce identical outputs and reasons traces
Policy Version Toggle and Default Behavior
Given a valid context payload including user/role, purpose, jurisdiction, and claim metadata When policyVersion=current is supplied Then the simulator evaluates against the current policy and returns 200 with results When policyVersion=staged is supplied Then the simulator evaluates against the staged policy and returns 200 with results When policyVersion is omitted Then the simulator defaults to current policy When an unknown or unsupported policyVersion is supplied Then the simulator returns 400 with a clear error code and message and does not perform an evaluation When required context fields are missing or invalid Then the simulator returns 400 with validation errors identifying the missing/invalid fields
Concise Diff Between Current and Staged Policies
Given the same context payload, evaluated under current and staged policies When I request a diff between current and staged results Then the response lists only fields where visibility, mask, or redaction state differs And for each changed field, the response includes before and after states and the policyVersion for each And the response includes summary counts of added visibility, removed visibility, added masks, removed masks, and redactions changed And if there are no differences, the response returns an empty list and a zeroed summary
Jurisdictional Overrides Enforcement
Given a claim with fields governed by jurisdiction-specific rules When I evaluate with jurisdiction=A and again with jurisdiction=B Then the results reflect the overrides defined for each jurisdiction, with differences limited to the fields and effects specified by policy And for each affected field, the reasons trace cites the applicable jurisdiction rule identifier
Purpose and Classification-Based Minimization
Given the same user/role and claim, and two purposes where Purpose X is narrower than Purpose Y per policy When I evaluate for Purpose X and Purpose Y Then the set of visible fields for Purpose X is a subset of or equal to the set for Purpose Y And fields tagged with higher-sensitivity classifications are masked/hidden unless the policy explicitly permits exposure for the supplied purpose and role And for every minimized field, the reasons trace indicates purpose-based minimization and classification factors
Structured Reasons Trace per Field
Given any evaluation When results are returned Then every field decision includes a non-empty machine-readable reasons array And each reason includes at minimum ruleId, decision (allow/mask/redact/deny), policyVersion, and factors used (jurisdiction, purpose, classificationTags) when applicable And the reasons are ordered according to evaluation order or priority so that the top entry explains the effective decision And no reasons are returned for fields omitted from the claim payload
Performance SLA on Typical Claims
Given the Typical Claims Suite defined in test data and production-like infrastructure When evaluating with the simulator using policyVersion=current Then the end-to-end evaluation latency is p95 <= 2000 ms measured over at least 500 requests And the p95 SLA holds with a warm cache and up to 10 concurrent requests And evaluations meet the SLA even when reasons tracing is enabled and when a version diff is requested
Masking & Redaction Visualization
"As a QA analyst, I want clear visual indicators and reasons for masked or redacted fields so that I can verify the correctness of access rules."
Description

Render a non-editable claim view that visually communicates access results at the field and artifact level. Masked values display standardized placeholders, redacted attachments show blurred thumbnails, and fully hidden items are indicated by collapsed stubs. Each concealment includes an inline reason tooltip that cites the governing rule and policy version. Provide a legend, accessibility-compliant color and iconography, and an option to toggle an "explain" layer that highlights elements affected by the simulation. Ensure no mechanism can reveal real sensitive data beyond the permitted simulation result.

Acceptance Criteria
Field Masking and Read‑Only Claim View
Given a simulated user with role, purpose, and jurisdiction that restrict some claim fields When the Access Simulator renders the claim view Then no edit or bulk action controls are present anywhere on the page And permitted fields display their true values exactly as stored And restricted fields display the standardized placeholder "[MASKED]" with the concealment icon And the placeholder token is identical across text, number, date, and reference fields And the original values for masked fields are absent from the DOM and client-consumed API responses And copying, printing, or exporting a masked field yields only "[MASKED]"
Hidden Fields and Sections Indicated by Collapsed Stubs
Given the simulation hides one or more fields or sections entirely When the claim view loads Then each hidden item is replaced by a collapsed stub labeled "Hidden by access rules" And the stub shows the item label and type but no values And the stub cannot be expanded or revealed by any UI control And the stub includes an inline reason tooltip control And screen readers announce the stub and its hidden state
Attachment Redaction with Blurred Thumbnails
Given one or more attachments are redacted under the simulation When the attachments gallery renders Then each redacted attachment shows a blurred thumbnail derived from a server-side redacted asset (not a client-side filter) And opening the attachment viewer displays only the redacted asset And download and right-click save deliver only the redacted asset And file names, EXIF, and embedded metadata are masked or removed per rule And the original unredacted asset bytes are never transmitted to the client
Inline Reason Tooltip Citing Rule and Policy Version
Given any field masking, attachment redaction, or hidden stub is present When the user hovers or focuses on the info icon for that concealment Then a tooltip appears within 300 ms showing the governing rule name/ID and policy version in the format "Rule: {id or name} • Policy v{semver}" And the tooltip includes effective date and jurisdiction when applicable And the tooltip is reachable via keyboard and dismissible with Esc And the tooltip content contains no original sensitive values And analytics/logging record only rule/policy identifiers, not concealed data
Explain Layer Toggle Highlights Affected Elements
Given the claim view contains any concealed elements When the user toggles Explain Layer to On Then all masked fields, redacted attachments, and hidden stubs are visually highlighted with the explain color and iconography And a legend callout displays counts by type (masked, redacted, hidden) And toggling Explain Layer Off returns the view to normal without altering concealment And the toggle state persists while navigating within the claim in the same session And keyboard users can toggle via a control with ARIA-pressed reflecting state
Legend and Accessibility Compliance
Given the Access Simulator view is rendered When the legend is opened Then it lists each concealment type with its icon, color swatch, placeholder example, and definition And all text/icon contrast ratios meet WCAG 2.2 AA thresholds And color is not the only means of conveying meaning; each item has a distinct icon and text label And all interactive controls are keyboard accessible with visible focus and screen-reader labels And high-contrast mode and common color-blind simulations preserve meaning
No Sensitive Data Leakage Across Surfaces
Given a claim contains sensitive values concealed by the simulation When inspecting the DOM, network requests/responses, analytics payloads, logs, alt text, ARIA labels, and data attributes Then no original sensitive values are present; only placeholders or redacted derivatives are returned And printing, exporting, or snapshotting reproduces only masked/redacted content And copying or selecting text from concealed elements yields only placeholder text And client-side caching and offline storage contain no original sensitive bytes And security tests for CSS/JS injection, feature flags, and error states do not expose concealed data
Zero-Write Non-Interactive Preview Mode
"As a system administrator, I want the simulator to be strictly read-only so that testing cannot alter data or trigger workflows."
Description

Guarantee that simulation runs are read-only and side-effect free. Disable or intercept all write operations, workflow actions, notifications, and external calls within the simulated view. Watermark the UI as "Simulated" and suppress background automations that would normally trigger on view or interaction. Implement guardrails at both UI and API layers to prevent state mutation, with centralized enforcement and telemetry to confirm zero writes occurred during a session.

Acceptance Criteria
UI Interactions Produce No Writes
Given an active Access Simulator session on claim C123 for user U When the user attempts to edit and save a field, add a note or attachment, change assignment or status, or trigger any workflow action Then all write-capable controls are disabled or intercepted with the message "Simulation Mode: changes will not be saved" And a page refresh shows no persisted changes to the claim, tasks, notes, attachments, or status And the audit log shows 0 created/updated/deleted records for the session And a telemetry event "simulation.write_intercepted" is recorded per attempted action with rowsAffected=0
API Layer Rejects Mutations in Simulation
Given a valid simulationSessionId is present in the request context (header or token) When any POST, PUT, PATCH, or DELETE is invoked against the API Then the server responds 403 Forbidden with errorCode=SIMULATION_READ_ONLY and includes simulationSessionId in the response And no database mutations are executed (verified by transaction/audit logs) And any GET endpoints that normally perform incidental writes (e.g., lastViewedAt) do not write during simulation (rowsAffected=0)
External Integrations and Notifications Suppressed
Given an active simulation session When an action would normally send an email/SMS/push, enqueue a message, fire a webhook, invoke a payment/document service, or perform any outbound HTTP call Then no outbound network requests are made and no messages are queued And logs record a "skipped_due_to_simulation" reason with target system identifiers And egress monitoring shows 0 external calls during the session
Workflow Automations Do Not Trigger
Given workflow automations configured to trigger on view, read, or user interaction When the claim is opened and navigated in simulation Then no workflow jobs start, no tasks are created, and no status transitions occur And the workflow engine metrics show jobsStarted=0 and tasksCreated=0 for the simulationSessionId And after exiting simulation, normal automations resume unaffected for non-simulated views
Simulated Watermark and Visual Indicators
Given any screen, modal, or printable view within the Access Simulator When the UI renders at desktop, tablet, and mobile breakpoints Then a persistent, non-dismissible "Simulated" watermark/badge is visible on all views and components, including modals and embedded widgets And the watermark includes the simulationSessionId and start time And print/print-to-PDF includes the "Simulated" watermark And accessibility checks pass (contrast ≥ 4.5:1, ARIA label present)
Centralized Enforcement and Telemetry Coverage
Given centralized simulation enforcement is enabled When server-side code handles requests and UI attempts write actions Then 100% of write-capable API endpoints and domain commands are routed through the read-only guard And session-level telemetry emits a summary event on close: attemptedWrites=0, externalCalls=0, automationsTriggered=0 And if attemptedWrites>0, a high-severity alert is generated and the session is marked non-compliant
Session Isolation and Exit Conditions
Given a user starts simulation from a claim detail page When the user exits simulation or the session times out due to inactivity (configurable timeout) Then all simulated state is discarded and the user returns to the pre-simulation context without elevated or simulated permissions And no drafts, locks, or caches persist from the simulation And deep links from the simulation cannot be used to perform mutations outside simulation (token invalid outside session)
Shareable Simulation Snapshot with Expiring Access
"As a compliance reviewer, I want an expiring link to a simulation snapshot so that I can audit and approve access changes without touching live data."
Description

Enable users to generate an immutable snapshot of the simulated view, capturing rendered content, applied policy version, context (user/role, purpose, jurisdiction), claim ID, timestamp, and rule explanations. Store snapshots securely with content limited to already-masked outputs, not raw underlying data. Provide expiring, access-controlled links (SSO-aware, signed URLs) and optional PDF export with watermarks. Record who created, viewed, or downloaded a snapshot and allow revocation prior to expiry.

Acceptance Criteria
Generate Immutable Snapshot with Context Metadata
Given a user has simulated a claim view with a specific role, purpose, jurisdiction, and policy version When the user clicks "Create Snapshot" Then the system saves an immutable snapshot that includes: snapshot ID, claim ID, creation timestamp (ISO 8601, ms precision), creator user ID, role, purpose, jurisdiction, applied policy version identifier, rule explanation list with rule IDs and rationales, and the exact rendered content as seen (masked values, labels, and layout) And the snapshot is assigned a content hash (SHA-256) and ETag And any attempt to modify the snapshot payload is rejected with 409 Conflict and does not change the hash/ETag And the snapshot content matches the current simulation view values and masks (DOM/text diff ignoring transient UI elements)
Store Only Masked Outputs (No Raw Data)
Given the simulation view contains masked/redacted fields When the snapshot is persisted Then only the rendered, already-masked values and derived artifacts are stored And no raw/unmasked underlying data fields, attachments, or source images are persisted in the snapshot record or its storage blob And automated scanning of the snapshot payload and PDF export finds no PII in fields flagged as masked/redacted And the snapshot references the underlying claim by ID only without embedding source datasets
Expiring SSO-Aware Signed Link
Given a snapshot exists with a configured expiry time-to-live (TTL) When the creator generates a share link Then the system issues a signed URL that encodes snapshot ID and expiration timestamp and is verifiable server-side And a recipient with a valid SSO session who opens the link before expiration is granted read-only access to the snapshot And opening the link after expiration returns 403 Expired with no content leakage And tampering with the link token/signature results in 403 Invalid Signature with no content leakage
Optional PDF Export with Watermarks
Given a user with access to a snapshot requests "Export PDF" When PDF generation completes Then the PDF contains the same content and masks/redactions as the snapshot (field values, labels, and visibility) and no raw data And the PDF is watermarked with "Simulation Snapshot", and includes footer metadata: claim ID, snapshot ID, creator user ID, creation timestamp, applied policy version, and snapshot expiry And the PDF is stamped with a document hash and stored read-only And any PDF download is logged with actor, timestamp, snapshot ID, and outcome
Audit Trail for Create, View, Download
Given snapshot lifecycle events occur When a user creates, views, or downloads a snapshot or its PDF Then an audit record is written for each event with: actor ID, action {create|view|download}, snapshot ID, timestamp, IP and user agent, and outcome {success|denied} And audit records are immutable, time-ordered, and queryable by snapshot ID, actor, and date range And attempting an unauthorized access (e.g., expired/revoked link) also records a denied event
Revocation Prior to Expiry
Given a snapshot has an active share link When the creator or an admin selects "Revoke Access" and confirms Then all existing share links for the snapshot become invalid immediately and further accesses return 403 Revoked And the snapshot status is updated to Revoked and the event is audited with actor, timestamp, and reason And new PDF exports are blocked after revocation and attempts are denied and audited And previously downloaded PDFs cannot be retracted, but additional downloads from the system are blocked
Access Scope Limited to Snapshot
Given a recipient opens a snapshot via a valid share link When the recipient attempts to navigate to the live claim, edit data, or request unmasked/hidden fields Then the UI clearly indicates Read-Only Snapshot mode and disables edit/navigation controls outside the snapshot And API calls to fetch underlying raw claim data are not executed and any direct attempts are denied with 403 And only snapshot content is viewable and downloadable within the allowed time window
Simulation Permissions & Safeguards
"As a security administrator, I want to restrict and monitor simulation capabilities so that sensitive views cannot be emulated without proper authorization."
Description

Define and enforce who can simulate which users/roles and scopes, with organization, line-of-business, and claim assignment constraints. Apply rate limiting, session timeouts, and PII minimization for results shared outside core teams. Prevent simulation of privileged personas unless explicitly granted. Provide administrative controls to configure guardrails, plus clear denial messaging when an attempt violates policy. Log attempted and successful simulations for security review.

Acceptance Criteria
Enforce Simulation Authorization Matrix
Given a requester has simulate permissions for personas/roles R and scopes S (purpose, jurisdiction), When they initiate a simulation that matches R and S, Then the simulation starts and only fields permitted by R and S are visible. Given a requester attempts to simulate a persona or scope not in their authorization matrix, When they submit the request, Then the system blocks the simulation with HTTP 403, shows a clear denial message containing a human‑readable reason, policy code SIM_AUTH_001, and remediation guidance, and no claim data is disclosed.
Block Privileged Personas Without Explicit Grant
Given the target persona is designated as privileged and the requester lacks an explicit simulate_privileged grant, When the simulation is requested, Then the request is denied with policy code SIM_PRIV_403, no partial data renders, and the attempt is fully logged. Given the requester has an explicit simulate_privileged grant scoped to certain privileged personas and purposes, When they request a simulation that matches the grant, Then the simulation is allowed; otherwise it is denied with SIM_PRIV_403.
Organization, LOB, and Assignment Constraints
Given organization constraints are enabled, When a requester attempts to simulate a claim outside their permitted org tree, Then the system denies the request with SIM_SCOPE_ORG and logs the attempt. Given line‑of‑business constraints are configured per role, When a simulation includes a disallowed LOB, Then the system denies the request with SIM_SCOPE_LOB. Given assignment_required=true, When a requester attempts to simulate a claim not assigned to them or their team, Then the system denies the request with SIM_SCOPE_ASSIGN; When the claim is assigned to them or their team, Then the simulation is allowed.
Rate Limiting and Session Timeout Controls
Given a configured rate limit of L requests per window T for simulate actions, When a requester exceeds L within T, Then the system responds with HTTP 429, includes a Retry‑After header with remaining seconds, and does not execute the simulation. Given a simulation session is active, When idle time exceeds the configured idle_timeout, Then the session terminates and requires re‑authorization to resume. Given a simulation session is active, When total elapsed time exceeds the configured max_session duration, Then the session terminates and requires a fresh start.
PII Minimization for Shared Snapshots
Given a snapshot is generated for sharing to recipients outside core teams, When the snapshot is created, Then all fields classified as PII by the data catalog and applicable jurisdiction rules are masked/redacted, attachments are processed for redaction, and the shared link enforces least‑privilege visibility. When a recipient accesses the snapshot, Then unmasked PII is not retrievable via UI, API, or URL parameters; downloads/exported files contain identical redactions; an audit record includes a redaction summary and snapshot TTL. When the snapshot TTL expires or access is revoked, Then the link becomes unusable and no content is retrievable.
Administrative Guardrails Configuration
Given an administrator with guardrails_manage rights opens Guardrails Settings, When they configure persona/role simulation mappings, privileged persona list, allowed purposes, jurisdictions, org/LOB/assignment rules, PII categories for sharing, rate limits, session timeouts, and denial message templates, Then the system validates inputs, prevents conflicting rules, saves a versioned change set, and applies it without exposing in‑flight simulations to broader access. When a configuration change is saved, Then the system records before/after values, actor, timestamp, and a change reason in the audit log, and supports rollback to a prior version.
Security Logging for Simulations
Given any simulation attempt (successful or denied), When it occurs, Then an immutable log entry records actor identity, target persona/role, declared purpose, claim ID(s), scope parameters, timestamp, client IP, user agent/device fingerprint (if available), outcome (allow/deny), denial reason and policy code, and a correlation ID. Given a security reviewer with log_view rights, When they filter logs by actor, claim ID, policy code, time range, or correlation ID, Then the system returns matching entries within the configured query SLA and supports export; PII values in logs are minimized/masked per policy.
Audit Trail & Change Workflow Integration
"As a release manager, I want simulations and their evidence attached to change requests with enforceable gates so that access policy changes cannot deploy without proper verification."
Description

Capture a complete audit trail for each simulation and snapshot, including initiator, target context, policy version, rules invoked, and outcome. Expose APIs and webhooks to attach snapshots and audit data to change requests in tools like Jira and to CI/CD gates. Provide a checklist integration that blocks policy deployments until required simulations and approvals are present. Support retention policies, export to CSV/JSON, and search/filtering for audits and regulators.

Acceptance Criteria
Audit Trail Record Completeness for Simulations and Snapshots
Given a user runs an access simulation or generates a snapshot When the operation completes (success or failure) Then an audit record is created with: auditId, timestamp (UTC ISO-8601), initiator userId and role, target claimId, policyId, policyVersion (version and content hash), jurisdiction, purpose, environment, and correlationId And includes the ruleset version and a list of rules invoked with evaluation outcome per rule And includes the visibility outcome summary (counts of revealed/masked/redacted fields) and the linked snapshotId (if any) And the record is immutable (append-only) with a recordHash (SHA-256) and previousHash for tamper evidence And the audit record is retrievable by auditId within 2 seconds p95
Webhook Delivery and Security to External Change Tools
Given webhooks are configured for snapshot and audit events When a snapshot or audit record is created Then a POST is sent to each subscribed endpoint within 5 seconds p95 containing eventType, eventId, auditId, snapshotId, policyVersion, status, and timestamp And the request includes an HMAC-SHA256 signature header over the raw body and a replay-prevention timestamp And non-2xx responses trigger exponential-backoff retries with jitter for up to 24 hours And deliveries are idempotent via a stable eventId and x-idempotency-key header And delivery outcomes (success/failure, attempts, lastError) are recorded and searchable in the audit trail
API Attachment to Change Requests (e.g., Jira)
Given a change request key (e.g., JIRA-123) and a snapshot/auditId When POST /integrations/jira/{issueKey}/attachments is called with valid OAuth2 credentials and payload {snapshotId|auditId} Then the issue shows a new attachment or deep link to the snapshot and audit summary within 10 seconds p95 And the attachment metadata includes policyVersion, rulesetVersion, jurisdiction, initiator, timestamp, and a deep link back to ClaimFlow And the API responds 201 with attachmentId and is idempotent on retries (same attachmentId returned for duplicate requests) And authorization is enforced to the tenant/project scope
CI/CD Gate Evaluation API
Given a target policyVersion and deployment environment When the pipeline calls GET /gates/policy-readiness?policyVersion=...&env=... Then the API returns JSON {status: pass|fail, reasons: [...], requiredEvidence: [...]} within 1 second p95 And fail is returned until required simulations (by role, purpose, jurisdiction) and approvals (required approver roles) are present and linked to the change And each evaluation emits an audit record with auditId linking the gate decision to the evidence set And the endpoint enforces service-to-service auth and rate limits (e.g., 100 rps per client)
Deployment Checklist Blocking Behavior
Given a deployment is initiated via CLI, UI, or API When required simulations or approvals are missing or stale (> N days configurable) Then the deployment is blocked and a checklist enumerates missing items by role, purpose, and jurisdiction And an explicit override is permitted only to users with Change Approver role and requires a non-empty justification And the override decision, approver identity, justification text, and timestamp are recorded in the audit trail and linked to the deploymentId And the CLI/API exits with a non-zero code or fail status when blocked (unless override used)
Retention Policy and Legal Hold Enforcement
Given tenant-defined retention settings by policy and jurisdiction (e.g., 180-3650 days) When an audit record or snapshot exceeds its retention period Then it is purged irreversibly within 24 hours by a scheduled job, and a purge event with counts and scope is appended to the audit trail And records under active legal hold are excluded from purge until the hold is lifted And admins can create, list, and release legal holds via API; all hold actions are audited And purge activity is exportable for regulator review
Audit Search, Filter, and Export to CSV/JSON
Given an authorized user with Audit Viewer or higher permissions When searching via UI or API with filters (date range, claimId, policyId/version, initiator, role, jurisdiction, rule name, outcome, environment, webhook delivery status) Then results return in <= 2 seconds p95 for up to 10,000 matches with correct pagination and sort (time desc default) And results are restricted to the user's authorization scope and preserve redactions/masks in field-level data And exports produce deterministic CSV/JSON matching the filtered set, with documented schema, UTC timestamps, and a file checksum And exported files are retained for download for at least 24 hours or until explicitly deleted

Creep Guard

Continuous monitoring for permission creep. Detects dormant access, long‑lived temporary grants, and rarely used permissions; recommends removals and can auto‑revoke after inactivity windows. Usage heatmaps show exactly which privileges are truly needed, shrinking risk without slowing teams.

Requirements

Universal Permission Telemetry
"As a security admin at an MGA, I want granular telemetry of permission usage so that I can measure inactivity and identify unnecessary access without disrupting claim operations."
Description

Capture fine-grained telemetry for every permission check and resource access across ClaimFlow (web app, APIs, NLP pipelines, workflow automations, file storage). Log actor, role, tenant, environment, permission, resource, channel (UI/API/bot), outcome, and timestamp with low-overhead instrumentation. Aggregate usage counts and last-seen timestamps in near real time with configurable retention and sampling. Anonymize or hash sensitive fields and enforce tenant isolation to meet insurer/MGA privacy and compliance needs. Provide a stable schema on the event bus and in the data warehouse so downstream detection, heatmaps, and recommendations can reliably consume the data.

Acceptance Criteria
Complete Telemetry Record on Permission Check
Given any permission check occurs in the web app, REST API, NLP pipeline, workflow automation, or file storage When the check is evaluated Then exactly one telemetry event is emitted per check with non-null fields: actor_identifier, role, tenant_id, environment, permission_code, resource_identifier, channel in {UI, API, BOT, NLP, WORKFLOW, STORAGE}, outcome in {allow, deny}, timestamp (ISO-8601 UTC), event_id (UUID), and trace_id (if available) And p95 added latency per permission check <= 5 ms and CPU overhead <= 2% at 2,000 checks/second sustained load And event emission success rate >= 99.99% with duplicate rate <= 0.01% over a 1-hour soak test
End-to-End Coverage Across All Channels
Given coverage tests trigger permission checks via Web UI, REST API, bot integration, NLP pipeline, workflow automation, and file storage When each action executes Then a telemetry event is visible on the event bus within 2 seconds with the correct channel value And the corresponding record is persisted to the warehouse fact table within 5 minutes And channel coverage = 100% with no missing events for the triggered actions
Near Real-Time Aggregation and Last-Seen
Given continuous ingestion at 5,000 events/second across multiple tenants When querying aggregates by key {tenant_id, role, permission_code} Then usage_count reflects all ingested events with freshness p99 <= 60 seconds And last_seen equals the most recent event timestamp for that key within ±1 second And replaying the raw stream does not double-count in aggregates (idempotent aggregation)
Configurable Retention and Sampling Accuracy
Given a tenant configures retention_days ∈ {30, 90, 365} and sampling_rate ∈ {1.0, 0.5, 0.1} When the config is updated via the admin API Then new sampling is applied within 10 minutes and events include sampling_weight metadata And aggregated counts differ from true counts by ≤ 5% at 95% confidence on a 1M-event synthetic workload And data older than retention_days is purged from hot storage and the warehouse by 02:00 UTC the next day
Sensitive Field Anonymization
Given tenant privacy setting anonymize_sensitive = true When telemetry events are emitted Then actor_identifier and resource_identifier are irreversibly hashed with a tenant-scoped salt; plaintext values are not present on the event bus or in the warehouse And the salt is stored in KMS and rotation preserves intra-tenant linkage across a 7-day rotation window And queries for plaintext identifiers return no rows
Tenant Isolation in Streams and Warehouse
Given tenants A and B and a consumer authenticated for tenant A When subscribing to the telemetry event stream or querying warehouse tables Then only rows with tenant_id = A are accessible; attempts to access tenant_id = B result in 403 (stream) or 0 rows (warehouse) And row-level security policies prevent cross-tenant joins and are validated by automated policy tests
Schema Stability and Backward Compatibility
Given telemetry schemas are registered with BACKWARD compatibility in the schema registry When a new optional field is added to the event schema Then existing consumers using the previous schema version continue processing without code changes And CI rejects any breaking change unless a new major version is published and dual-publish of old and new schemas runs for ≥ 12 months And warehouse tables never drop/rename existing columns; downstream detection and heatmap jobs from the previous release pass integration tests against the updated schema
Dormant Access Detection Rules
"As a compliance officer, I want dormant access automatically flagged based on configurable thresholds so that we can proactively remove stale privileges and reduce audit findings."
Description

Evaluate permission usage against configurable inactivity thresholds to detect dormant users, roles, and privileges. Support per-permission and per-role thresholds, business-hour windows, seasonality considerations for claims volume, and exclusions for service and break-glass accounts. Generate findings with clear evidence (last used time, frequency trend, dependent workflows) and risk scoring, de-duplicated across microservices. Emit findings as tasks into ClaimFlow’s workflow engine for routing to the right approvers.

Acceptance Criteria
Per-Permission Threshold Detection
Given user "u123" has permission "Claim.Edit" with an inactivity threshold of 14 business days And usage logs show last_used_at = 2025-08-31T10:00:00Z and 0 uses since that timestamp And evaluation occurs at 2025-09-30T09:00:00Z When the dormancy detection job executes for tenant "acme-insurance" Then exactly 1 finding is created with type = "DORMANT_PERMISSION" for user "u123" and permission "Claim.Edit" And the finding source = "CreepGuard" and status = "Open" And no role-level or user-level finding is created for this condition
Per-Role Threshold Detection and Precedence
Given user "u124" is assigned role "Senior Adjuster" which includes permissions ["Claim.View","Claim.Edit"] And the role "Senior Adjuster" has an inactivity threshold of 30 business days And permission "Claim.Edit" has an inactivity threshold of 14 business days And usage logs show last_used_at("Claim.Edit") = 35 business days ago and last_used_at("Claim.View") = 5 business days ago When the dormancy detection job runs Then a finding with type = "DORMANT_PERMISSION" is created for permission "Claim.Edit" for user "u124" And no finding with type = "DORMANT_ROLE" is created for role "Senior Adjuster" Given user "u124" now has last_used_at("Claim.View") = 35 business days ago and last_used_at("Claim.Edit") = 35 business days ago When the dormancy detection job runs Then exactly 1 finding with type = "DORMANT_ROLE" is created for role "Senior Adjuster" for user "u124" And no additional permission-level findings are created for permissions already covered by the role-level finding in this evaluation run
Business-Hour Windows Applied to Inactivity Calculations
Given business hours are configured as Monday–Friday 08:00–18:00 America/New_York And permission "Claim.Approve" for user "u200" has an inactivity threshold of 16 business hours And last_used_at("Claim.Approve") = 2025-09-26T17:00:00-04:00 (Friday) When evaluation occurs at 2025-09-29T09:00:00-04:00 (Monday) Then accumulated inactivity = 2 business hours and no dormant finding is created When evaluation occurs at 2025-10-01T10:00:00-04:00 (Wednesday) Then accumulated inactivity >= 16 business hours and exactly 1 finding with type = "DORMANT_PERMISSION" is created for user "u200" and permission "Claim.Approve"
Seasonality-Aware Dormancy Detection by Line of Business
Given Line of Business "Property" has seasonality rules: Off-season = November–February with inactivity threshold 120 calendar days, In-season = March–October with inactivity threshold 30 calendar days And user "u300" with role "CatAdjuster" has permission "Cat.Claim.Approve" And last_used_at("Cat.Claim.Approve") = 2025-01-10T12:00:00Z When evaluation occurs on 2025-02-15T12:00:00Z (off-season) Then no dormant finding is created for "Cat.Claim.Approve" When evaluation occurs on 2025-04-15T12:00:00Z (in-season) Then a dormant finding with type = "DORMANT_PERMISSION" is created for user "u300" and permission "Cat.Claim.Approve"
Exclusion of Service and Break-Glass Accounts from Findings
Given account "svc_claims_export" is flagged account_type = "service" and account "breakglass_admin" is flagged break_glass = true And both accounts hold permissions with last_used_at > configured thresholds When the dormancy detection job runs Then no findings are created for "svc_claims_export" or "breakglass_admin" And an audit log entry is written per excluded account with reason in {"service_account","break_glass_account"}
Findings Generated with Evidence and Risk Scoring
Given user "u123" and permission "Claim.Edit" breach the inactivity threshold When a dormant finding is created Then the finding includes fields: entity_type, entity_id, user_id, permission_id, last_used_at (RFC3339 with timezone), usage_frequency_30d, usage_frequency_60d, usage_frequency_90d, trend in {"increasing","flat","decreasing"}, dependent_workflows (array), risk_score (0–100 integer), risk_factors (array), checksum And last_used_at matches the latest observed usage timestamp for the entity And usage_frequency_* reflect exact counts from the last 30/60/90 calendar days respectively And trend = "decreasing" when 30d < 60d and 60d < 90d And dependent_workflows includes at least one workflow that references the permission when such a dependency exists (e.g., "FNOL Intake") And risk_score is within [0,100] and does not decrease when inactivity_days increases by 10 with all other factors held constant And two consecutive runs over identical input produce identical risk_score and checksum values
Cross-Microservice Deduplication and Workflow Task Emission and Routing
Given microservices "authz-service" and "claims-api" emit usage metrics for the same tenant_id/user_id/permission_id And correlation keys are configured as {tenant_id, user_id, role_id?, permission_id} When both sources trigger evaluation in the same cycle Then exactly 1 consolidated finding is persisted for the entity And the finding contains dedupe_count >= 1 and sources includes ["authz-service","claims-api"] And re-running the job with unchanged inputs creates no additional findings (idempotent) When a finding is created Then a workflow task is emitted to ClaimFlow with type = "Review Dormant Access" and includes finding_id, tenant_id, entity identifiers, risk_score, suggested_action = "Review/Remove" And routing assigns the task to the correct approver based on rules: if line_of_business = "Property" and risk_score >= 70 then assignee_group = "Security Admins" else assignee_group = "LOB Owner: Property" And the task priority = "High" when risk_score >= 80 else "Normal"
Auto-Revocation Policies with Safeguards
"As an IT admin, I want to automatically revoke unused permissions with approvals and rollbacks so that security improves without blocking active claims work."
Description

Provide a policy framework to auto-revoke or downgrade unused permissions after inactivity windows with guardrails. Support staged notifications (heads-up, reminder, final), just-in-time approval workflows routed to claim managers, grace periods, and exceptions for critical roles. Integrate with IdP/IAM (Okta, Azure AD, Google Workspace) and ClaimFlow RBAC to execute changes, with dry-run mode, bulk actions, and automatic rollback if revocation fails or breaks a protected workflow. Record all actions in the audit log and surface status in the UI.

Acceptance Criteria
Auto-Revocation after Inactivity with Staged Notifications
Given an auto-revocation policy with a 30-day inactivity threshold and notifications configured at T-7d, T-2d, and T-1h When a user’s permission shows no usage events for 30 consecutive days Then the system schedules revocation/downgrade per policy and sends heads-up at T-7d, reminder at T-2d, and final notice at T-1h to the user and their manager And each notification includes permission name, last-used timestamp, scheduled action time, and links to request extension or acknowledge removal And on reaching T, if no extension is approved, the permission is revoked or downgraded as configured And permissions covered by exception rules receive no notifications and are not scheduled for revocation And if the permission is a temporary grant that exceeds its maximum duration, the system proceeds to revoke at expiry after the final notice, regardless of recent usage
Just-in-Time Approval Workflow and Grace Period
Given final notifications provide a one-click Request Extension action When a user requests an extension before the scheduled revocation time Then a just-in-time approval request is created and routed to the assigned claim manager approver group with the requested duration and justification And approvers can Approve (selecting an allowed extension duration within policy limits) or Deny from email/in-app And on approval, the permission is extended and the revocation is deferred by the approved grace period; the new expiry is shown in the UI And on denial, the permission is revoked immediately and the user is notified And if no action is taken within the SLA (e.g., 48 hours before T), the request escalates to backup approvers; if still pending at T-1h, the default outcome is Deny
Exceptions for Critical Roles and Protected Workflows
Given a role or permission is flagged as Critical or linked to a Protected Workflow When policy evaluation would revoke or downgrade that permission Then the system skips execution and labels the item as Exempt in the UI with the applicable exception rule And a review task is created for owners to re-validate the exception by a defined cadence (e.g., quarterly) And any manual override requires dual approval and a recorded justification And exempt items do not receive staged notifications unless explicitly enabled by policy
Dry-Run Mode with Impact Preview
Given a policy is set to Dry-Run When the evaluation job runs on the selected scope Then no changes are pushed to IdP/IAM or ClaimFlow RBAC And the system produces an impact report listing users, permissions, action type (revoke/downgrade), reason (inactivity/expiry), and scheduled times And the audit log records a simulated action entry with correlation ID and counts per action type And the UI allows exporting the preview and provides an Apply Now action that runs the same batch in Live mode
Provider Integration Execution and Automatic Rollback
Given Live mode is enabled and connections to Okta, Azure AD, Google Workspace, and ClaimFlow RBAC are healthy When a scheduled revocation/downgrade batch executes Then the system applies changes via provider APIs using least-privilege service accounts and confirms each change by reading back the resulting state And if any change in the batch fails or a protected workflow health probe indicates breakage, the system automatically rolls back all changes in the batch to the prior state And each item is marked Completed, Rolled Back, or Failed with provider error codes and timestamps And operations are idempotent on retries and respect provider rate limits with exponential backoff
Bulk Actions with Safety Limits
Given an administrator selects a set of users/permissions for bulk dry-run or live execution When the bulk action is initiated Then the system enforces guardrails: maximum batch size (e.g., 500 items), required typed confirmation for live runs, and exclusion of items under active exceptions or pending approvals And execution occurs in chunks with per-chunk transactional rollback on failure And the UI displays progress, success/failure counts, and provides a single-click Undo for the last bulk batch (within a configurable time window)
Audit Logging and UI Status Visibility
Given any simulated or executed revocation/downgrade or approval decision occurs When viewing the Audit Log and Creep Guard UI Then each record includes timestamp, actor (system/user), policy ID, user ID, permission/role, provider, previous state, new state, reason, approver (if any), correlation ID, and outcome And audit records are immutable, searchable by filters (user, permission, policy, date range, outcome), and exportable (CSV/JSON) And the UI shows real-time status badges per permission (Scheduled, Pending Approval, Extended until <date>, Exempt, Revoked, Rolled Back, Failed) and last-used timestamps
Temporary Grant Lifecycle Enforcement
"As a team lead, I want temporary access to automatically expire and require re-approval if extended so that short-term needs don’t become permanent risk."
Description

Track all time-bound access grants with explicit start/end times and owners. Enforce expirations automatically, detect and alert on long-lived “temporary” grants, and require re-authorization to extend. Provide a lightweight UI and API for request/approve/expire flows with templates for incident response, vendor access, and on-call support. Link grants to tickets and claims where applicable and notify owners and approvers ahead of expiry to prevent disruption.

Acceptance Criteria
Create Temporary Grant via UI
Given a GrantAdmin opens the Create Temporary Grant UI using the "Incident Response" template When they enter owner O, grantee U, resource R, approver A, start time S, end time E, and optional ticket T and claim C, and submit Then the system validates that owner, grantee, resource, approver, start, and end are present; that E > S; and that S and E are valid timestamps And if validation fails, the form is blocked with field-level error messages; no grant is created And if validation passes, the grant is created with status "Scheduled" when S > now or "Active" when S <= now, stored in UTC with ISO 8601 precision And the created grant includes id G, template "Incident Response", owner O, grantee U, resource R, approver A, start S, end E, ticket T (if provided), claim C (if provided) And an audit log entry is recorded with actor, action "grant.create", and the full before/after payload And the UI displays a confirmation with grant id G
Create Temporary Grant via API
Given an API client authenticated with scope grants.write sends POST /grants with an Idempotency-Key and payload containing owner, grantee, resource, approver, start S, end E, and optional ticket and claim When E <= S or required fields are missing Then the API responds 400 with machine-readable errors; no grant is created When the payload is valid Then the API responds 201 with Location /grants/{G} and the created grant object; timestamps normalized to UTC And the initial state is "PendingApproval" when the template requires approval or approver A has not approved; otherwise "Scheduled" or "Active" based on S And a retry with the same Idempotency-Key within 24h returns 200 and the same grant id G without duplicating side effects
Automatic Expiration and Revocation
Given an Active grant G with end time E When current time reaches E Then the system revokes the mapped permission in the target provider within 60 seconds and marks G as "Expired" And access attempts using the revoked permission are denied by the provider within 60 seconds of E And notifications are sent to owner, grantee, and approver with subject "Grant Expired" and include G, resource, and end time And an audit log "grant.expire" with correlation to provider action is recorded And if provider revocation fails, the system retries for up to 30 minutes with exponential backoff and raises a high-priority alert after final failure
Pre-Expiry Notifications and Escalation
Given a grant G with end time E and notification policy {T-7d, T-24h} When the clock reaches E minus 7 days or 24 hours Then the system sends one notification per channel (email and in-app) to owner, grantee, and approver including one-click "Request Extension" and "Decline" actions And duplicate notifications are suppressed if an extension request is already PendingApproval And notification send/fail status is recorded per recipient; failures are retried for 24 hours And no notification is sent if E is within the next 15 minutes at the time of grant creation; only the closest upcoming window fires
Long-Lived Temporary Grant Detection
Given a policy MaxTemporaryDuration = 30 days When a temporary grant is created or updated with end - start > 30 days Then the system flags the grant as "Long-Lived", sends an alert to SecurityOps and the approver, and requires justification text before approval can proceed And the grant appears in the "Long-Lived" dashboard filter within 5 minutes And a weekly summary report lists all Long-Lived temporary grants with age, owners, and linked tickets/claims
Extension Re-Authorization Flow
Given a grant G with end time E and state Active When the owner or grantee requests an extension before E with proposed new end time E2 > E Then the system sets state "PendingApproval" and notifies approver A And when A approves, the grant end time becomes E2, an audit "grant.extend" is recorded, and no access interruption occurs if approval time < E And when A rejects, the grant retains end time E and the requester is notified with the rejection reason And extensions that would exceed policy MaxTemporaryDuration are blocked with a clear error And requests submitted after E result in creation of a new grant G2 referencing G as predecessor; G remains Expired
Linking Grants to Tickets and Claims
Given the "Incident Response" template requires a ticketId and the "On-Call Support" template allows an optional claimId When a user submits a grant with ticketId T and claimId C Then the system validates T and C against configured integrations; invalid IDs are rejected with 400 (API) or field errors (UI) And on success, the grant stores T and C, displays deep links to the ticket and claim, and includes them in audit logs and notifications And grants created with the "Incident Response" template without a ticketId are blocked; with "Vendor Access" template either ticketId or vendorId must be present
Least-Privilege Heatmaps and Drill-Down
"As a security analyst, I want heatmaps of permission usage with drill-down so that I can see which privileges are truly needed and justify removals to stakeholders."
Description

Render interactive heatmaps that compare granted permissions versus actual usage across modules (intake, NLP extraction, attachments, routing) by user, role, team, and tenant. Enable filtering by line of business, region, environment, and timeframe, and provide drill-down to the exact events that justify a permission. Support exports (CSV/PDF) and embeddable widgets for governance dashboards. Ensure performance on large tenants and accessibility compliance.

Acceptance Criteria
Heatmap Permission Usage Accuracy
Given a tenant with granted permissions and usage events across modules (intake, NLP extraction, attachments, routing) for a selected timeframe When the heatmap is rendered grouped by user, role, team, or tenant Then each cell displays granted count, used count, and usage ratio that match the audited event log within ±0.1% And each cell tooltip contains module, principal (user/role/team), permission, granted, used, last-used (ISO 8601), and usage ratio And cells with zero usage are visually distinct and labeled “0 usage” And switching grouping (user↔role↔team↔tenant) recomputes counts and ratios correctly within 300 ms P95 client-side
Advanced Filtering by LOB, Region, Environment, and Timeframe
Given filters LOB, Region, Environment, and Timeframe are set (e.g., LOB=Auto, Region=EMEA, Env=Prod, Timeframe=Last 90 days in tenant timezone) When the heatmap and summaries are displayed Then only grants and events matching all filters (logical AND) are included And relative and absolute date ranges produce identical results to their equivalent explicit timestamps And clearing any filter updates the view within 1 second P95 and restores full-scope counts
Drill-Down to Permission-Justifying Events
Given a user selects a heatmap cell representing a permission for a principal and module When the drill-down panel opens Then it lists the exact events that justify the permission with columns: event_id, timestamp (ISO 8601), actor, principal type, module, permission, resource_id, outcome, and request_id And results are paginated (default 50 per page), sortable by timestamp, and filterable by outcome And each row links to the raw audit log entry; the first page loads within 2 seconds P95
CSV and PDF Exports Reflect Current View
Given the current heatmap view and filters When the user exports CSV Then the CSV includes one row per cell with columns: module, principal type, principal id/name, permission, granted, used, usage ratio, last used, filters applied; row count equals the on-screen dataset (up to 1,000,000 rows) And the CSV is delivered within 30 seconds P95; larger datasets are chunked into multiple files with consistent headers When the user exports PDF Then the PDF includes the rendered heatmap, legend, applied filters, and summary stats, fits A4/Letter, and is generated within 2 minutes P95
Embeddable Governance Widget
Given an embed token scoped to a tenant and optional preset filters When the widget is loaded via iframe or JS component in an external dashboard Then the heatmap renders read-only with data identical to the main app for the same scope And the token enforces tenant isolation, expires per TTL (min 15 minutes, max 24 hours), and returns 401 after expiration And the widget supports responsive resizing and filter updates via postMessage, rendering updates within 1 second P95
Performance at Scale for Large Tenants
Given a tenant with ≥50k users, ≥10k roles, ≥200 teams, 5M permission grants, and 250M usage events over 12 months When rendering the heatmap for the last 30 days Then time-to-first-render is ≤2 seconds P95 and ≤4 seconds P99 And applying any single filter updates the view in ≤1 second P95 And opening a drill-down returns the first page in ≤2 seconds P95 under 50 concurrent sessions
Accessibility Compliance (WCAG 2.2 AA)
Given users relying on keyboard and assistive technologies When navigating the heatmap, filters, and drill-down Then all interactive elements are reachable by keyboard with visible focus order and labels And heatmap cells expose accessible names conveying module, principal, permission, granted, used, ratio, and last-used for screen readers And color is not the sole means of conveying information (patterns/text are present), contrast ratios meet ≥4.5:1, and content remains usable at 200% zoom And exported PDFs include tags, reading order, and alt text for visuals
Rightsizing Recommendation Engine
"As a platform owner, I want data-backed permission reduction recommendations so that we can move toward least privilege without breaking processes."
Description

Generate data-backed recommendations to remove, downgrade, or consolidate permissions and propose least-privilege roles based on historical usage patterns and separation-of-duties constraints. Provide confidence scores, impact simulation showing affected workflows, and one-click application via existing approval workflows. Learn from accepted/overridden recommendations to improve precision over time and support batch actions for large teams.

Acceptance Criteria
Separation-of-Duties Compliant Recommendations
Given active separation-of-duties (SoD) policies are configured When the engine generates rightsizing recommendations Then no recommendation violates any active SoD policy And any potential violation is labeled as "Conflict" and is not eligible for auto-apply And each conflict includes the policy identifier and implicated roles/permissions And the API endpoint /recommendations returns zero items with "eligible_for_auto_apply": true that violate SoD
Generate Least-Privilege Recommendations from 90-Day Usage
Given 90 days of permission usage telemetry and current entitlements for a user When the engine generates rightsizing recommendations Then any permission unused in the last 90 days is recommended for removal with reason "unused_90d" and usage_count = 0 And any permission used at higher-than-needed level is recommended for downgrade to the least-privilege role that preserves all observed actions And redundant overlapping roles are recommended to be consolidated into an equivalent or smaller least-privilege role set And each recommendation includes timestamp, rationale, and supporting usage metrics (last_used_at, used_actions, usage_counts)
Confidence Scores and Thresholding
Given a fixed dataset and configuration When the engine generates recommendations Then each recommendation includes a confidence_score between 0.0 and 100.0 with at most one decimal place And confidence scores are deterministic across runs with identical inputs And the UI/API supports sorting by confidence_score and filtering by a minimum threshold (e.g., >= 70) And auto-apply candidacy respects the configured policy_min_confidence threshold and excludes lower-scored recommendations
Impact Simulation of Affected Workflows
Given a selected recommendation When the user opens the impact simulation Then the system lists workflows/tasks that would lose access if applied, including workflow_id, action, impacted_count in the last 30 days, and last_seen_at And the simulation clearly labels impact_level as none/low/medium/high based on configurable thresholds And the simulation computes and displays results within 2 seconds for up to 1,000 entitlements per user And the simulation view provides a reversible preview state without committing changes
One-Click Application through Approval Workflow
Given an approver is authenticated and the existing approval workflow integration is configured When the approver clicks "Apply" on a recommendation Then a single change request is created in the existing approval workflow containing the proposed entitlement changes And the recommendation status updates to "Pending Approval" with a linked external request ID And upon approval, entitlements are updated, the recommendation is marked "Applied", and an audit log captures timestamp, actor, and change details And upon rejection, the recommendation is marked "Rejected" with the rejection reason And re-clicking "Apply" for a pending recommendation does not create duplicate requests (idempotency)
Active Learning from Accepted and Overridden Recommendations
Given recommendations are either applied (accepted) or dismissed/overridden with a reason When the engine retrains on the next scheduled cycle (within 24 hours) Then future recommendations of the same pattern for the same entity reduce confidence or are suppressed for at least 30 days if previously overridden, unless usage changes materially And future recommendations of accepted patterns for similar entities increase confidence appropriately And the model version, feedback counts applied, and date of retraining are recorded in telemetry and audit logs
Batch Recommendation Review and Application
Given a reviewer selects 50–500 recommendations across multiple users in batch mode When the reviewer submits a batch apply Then the system creates individual approval requests per user within 5 seconds and begins asynchronous processing And the batch summary displays counts by status (submitted, pending_approval, applied, rejected, failed) and updates at least every 5 seconds And partial failures are reported with error reasons per item without blocking other items And batch operations respect SoD policies and confidence thresholds identically to single-item apply
Compliance Audit Trails and Exports
"As an auditor, I want complete, exportable evidence of permission reviews and changes so that we can demonstrate access governance during audits."
Description

Maintain immutable, tenant-isolated logs of detections, recommendations, approvals, revocations, exceptions, and rollbacks with actor, timestamp, rationale, and evidence links. Provide exportable evidence packs for SOC 2, ISO 27001, and NIST audits as CSV/PDF and an API/webhook for GRC systems. Support retention policies, legal holds, redaction of PII, and time synchronization with IdP change logs to create end-to-end traceability for access governance.

Acceptance Criteria
Immutable Audit Log Capture and Integrity
Given tenant T and an authenticated actor or system process When a detection, recommendation, approval, revocation, exception, or rollback occurs Then an audit entry is appended immutably containing: tenant_id, event_type, object_id, actor_id (or system), ISO 8601 UTC timestamp, rationale, evidence_url(s), request_id, and environment And the entry includes content_hash (SHA-256) and previous_hash to form a verifiable chain And attempts to update or delete existing entries via API/UI are rejected with 403 and create a separate audit event And a chain verification API for the last 1,000 entries returns 100% integrity (no breaks) within 2 seconds
Tenant Isolation of Audit Data
Given a user scoped to tenant A with least-privilege access When the user queries audit logs via UI or API Then only entries with tenant_id A are returned and pagination totals reflect tenant A only And attempts to access or export entries from tenant B return 403 (or 404) and are themselves audited And cross-tenant hash chains are disallowed; each tenant’s chain root and segment verification operate independently
Evidence Pack Export for SOC 2 / ISO 27001 / NIST (CSV/PDF)
Given a user with AUDIT_EXPORT role selects a date range, event types, and compliance framework (SOC2, ISO27001, or NIST) When the user requests an export Then the system generates a CSV and a PDF evidence pack for up to 100,000 events within 2 minutes and provides download links valid for 24 hours And the CSV includes columns: event_id, tenant_id, event_type, actor_id, timestamp_utc, rationale, evidence_url, request_id, prev_hash, content_hash And the PDF includes summary (scope, filters, generation timestamp UTC), dataset SHA-256 checksum, and sample entries with evidence links And the export metadata (job_id, requester, filters, checksums) is logged as an audit event
GRC API and Webhook Delivery of Exports
Given a GRC system registers a webhook URL with HMAC-SHA256 secret and scopes an API token to AUDIT_EXPORT:read When an export job completes Then a POST is sent to the webhook within 10 seconds containing job_id, tenant_id, framework, counts, sha256, size_bytes, and a signed download URL And failed deliveries are retried with exponential backoff (5 attempts over ~15 minutes) and final failure is alerted and audited And API endpoints enforce authZ: 401 without token, 403 on cross-tenant access, 200 with paginated job listing for the correct tenant
Retention Policies and Legal Holds Enforcement
Given a tenant retention policy R days is configured When an audit entry ages past R days without an active legal hold Then it is purged within 24 hours by a scheduled job and a tombstone audit event is created linking the removed entry_id And when a legal hold (case_id) is applied to a set of entries Then purge is blocked (423 Locked) for those entries until the hold is released, and all hold actions are audited And purge/redaction operations never break chain verification for remaining entries (tenant chain verification still passes)
PII Redaction Controls in Logs and Exports
Given PII fields are configured (e.g., email, phone, SSN) and role-based access is defined When a user without PII_VIEWER role views or exports logs Then PII values are masked or omitted in UI, CSV, and PDF, and a redaction_applied flag is present in outputs And users with PII_VIEWER must explicitly enable “Include PII” per export request; the action is justified (rationale required) and audited And stored audit entries remain unchanged (hash stable); redaction is applied at presentation/export time
Time Synchronization and IdP Log Correlation
Given NTP is configured with at least two trusted time sources When the system reports time_skew_seconds Then skew remains <= 2 seconds over a 24-hour window, otherwise an alert is raised and annotated in exports And given an IdP change event (e.g., Okta/Azure AD) affecting a subject When a related access governance event occurs in the system Then correlation links are present with monotonic ordering, IdP event URL, and timestamp delta <= 5 seconds

Blueprint Diff

Versioned templates with side‑by‑side diffs and impact analysis. See who gains/loses access by change, preview affected fields and workflows, and roll out safely with staged cohorts and automatic rollback. Cuts change risk and keeps permission sets transparent and defensible.

Requirements

Versioned Blueprint Repository
"As a configuration admin, I want to save and retrieve versioned blueprints with full history so that I can safely manage changes and reproduce past states."
Description

Implement a centralized repository for blueprint templates (schemas, field definitions, permission matrices, routing rules, and automations) with immutable versioning, branching, and tagging. Each version records author, timestamp, change summary, environment scope (dev/test/prod), and backward-compatibility flags. Provide APIs and UI to create, clone, diff, and pin versions to environments, ensuring reproducibility, safe rollback, and consistent deployments across ClaimFlow’s intake engine and workflow orchestrator.

Acceptance Criteria
Create and Tag a New Blueprint Version
Given a user with Blueprint Admin permission and a valid blueprint payload (schema, field definitions, permission matrix, routing rules, automations) When they create a new version via API or UI and provide a change summary, environment scope, backward-compatibility flag, and optional tags Then the system persists an immutable snapshot with a unique version ID, records author from identity and server timestamp, stores metadata and tags, and returns 201 with the version ID and metadata And the new version appears in the repository list with exact metadata values And any attempt to update this version afterward is rejected with 405 Method Not Allowed
Clone and Branch from Existing Version
Given an existing version V in the repository When a user clones V and specifies a branch name and whether to copy tags Then the system creates version V' with parent=V, branch=<name>, identical content to V, a new immutable ID, and tags copied only if explicitly requested And edits to V' do not modify V And the history view shows the branching relationship between V and V'
Diff Two Versions with Impact Analysis
Given two version IDs V1 and V2 When a user requests a diff via API or UI Then the system returns a structured diff highlighting added/removed/modified items across schemas, field definitions, permission matrices, routing rules, and automations And the diff includes an access impact report listing roles/users who gain or lose access with counts And the diff provides a backward-compatibility assessment (compatible/incompatible) with reasons And the UI renders a side-by-side view consistent with the API response
Pin Version to Environment
Given a selected version V and a target environment E (dev/test/prod) When an admin pins V to E Then the environment's active version pointer updates atomically to V and is recorded with actor and timestamp in the audit log And ClaimFlow's intake engine and workflow orchestrator read and use V for new requests within 60 seconds And in-flight processes continue using the previously pinned version
Rollback to Previous Version
Given environment E is currently pinned to version V2 and the previously pinned version V1 is recorded When an admin initiates a rollback for E Then the active version pointer for E reverts atomically to V1 and the event is logged with actor, timestamp, and reason And dependent services switch to using V1 for new work within 60 seconds
Backward Compatibility Gate on Pinning
Given a candidate version V marked as backward-incompatible When an admin attempts to pin V to test or prod without a linked migration plan ID or override justification Then the operation is blocked and the API returns 409 with details of incompatible changes And the UI displays the list of blocking changes and required actions to proceed
Audit Trail and Immutability Enforcement
Given any saved version When a user attempts to modify or delete its contents or metadata Then the system rejects the request with 405 Method Not Allowed and guidance to create a new version And the audit endpoint returns author, timestamp, change summary, parent/branch info, environment pin history, and a content hash for immutability verification
Side-by-Side Diff Viewer
"As a claims operations lead, I want to see a clear side-by-side comparison of blueprint versions so that I can understand exactly what will change before deploying."
Description

Provide an interactive split-view and unified diff UI that highlights added/removed/modified entities across blueprint components, including fields, validation rules, defaults, visibility conditions, permissions, and workflow steps. Support schema-aware diffing (path-based), ignore cosmetic changes, collapse unchanged sections, and deep-link to the exact node in the blueprint. Offer copyable patch output and integrate with impact analysis and approval flow to enable informed change reviews within ClaimFlow.

Acceptance Criteria
Toggle Split and Unified Diff for Blueprint Changes
Given a baseline and a modified blueprint with changes across fields, validation rules, defaults, visibility conditions, permissions, and workflow steps, When the user opens the diff viewer in Split view, Then added (+), removed (−), and modified (~) entities are highlighted with consistent badges and color coding. Given the diff viewer is in Split view with some sections expanded, When the user toggles to Unified view, Then the view switches without page reload, preserves scroll position and expanded/collapsed state, and completes within 300 ms. Given any change chip or row, When the user hovers or focuses it, Then a tooltip/inline annotation shows component type, full path, and a one-line change summary. Given counts by component type are displayed, When the diff is rendered, Then the counts for fields, validation rules, defaults, visibility conditions, permissions, and workflow steps match the number of visible change annotations in the current view mode.
Schema-Aware Path-Based Diff with Cosmetic Ignore
Given two blueprint versions, When diffing by schema path, Then entity identity is determined by path and key, and renames appear as a remove at the old path plus an add at the new path. Given an entity whose path is unchanged but values differ, When diffing, Then the change is marked as modified (~) and shows field-level before/after deltas where applicable. Given non-semantic differences (whitespace-only text changes, JSON key order, metadata like lastEdited timestamps) exist, When diffing with "Hide cosmetic changes" enabled (default), Then these differences are excluded from results and from change counts. Given the user enables "Show cosmetic changes", When the diff is recomputed, Then cosmetic differences appear tagged as Cosmetic and can be filtered out again by disabling the toggle. Given an order-insensitive collection (e.g., permission set membership) is only reordered, When diffing, Then no change is shown; if membership changes, Then adds/removes are shown per member path.
Collapse Unchanged Sections and Change Navigation
Given a diff with changed and unchanged sections, When the viewer loads, Then only sections containing changes are expanded and all-unchanged sections are collapsed with a badge showing 0 changes. Given the user clicks "Expand all changes", When invoked, Then all sections containing at least one change expand within 200 ms; clicking "Collapse all" collapses them within 200 ms. Given a section header shows a change count, When changes are filtered (e.g., hide cosmetic), Then the counts update immediately to reflect the visible set. Given keyboard navigation is used, When the user presses Next/Previous Change, Then focus and viewport move to the next/previous change item in document order with response time ≤150 ms and without skipping any changes.
Deep-Link to Exact Blueprint Node
Given a change item is selected, When the user clicks "Copy link to change", Then the clipboard receives a URL containing the diff id and schema path and no sensitive data values. Given the deep-link URL is opened in a new browser session, When the diff viewer loads, Then the corresponding node's parent sections auto-expand, the change item is scrolled into view and highlighted, and the same view mode is restored. Given the user navigates between changes, When using the browser Back/Forward buttons, Then the viewer restores the prior selection, scroll position, and expanded state without re-computing the diff. Given a deep-link points to a node that no longer exists, When opened, Then the viewer displays a non-blocking notice and focuses the nearest existing ancestor path.
Copyable Patch Output and Apply Validation
Given a diff is computed, When the user clicks "Copy Patch", Then a JSON patch representing only the semantic differences is copied to the clipboard and a success toast confirms the action; on clipboard failure, a "Download Patch" option is offered. Given the copied patch is applied to the baseline via the system patch engine, When validation runs, Then the resulting blueprint is structurally equivalent to the modified version and a re-diff returns zero differences. Given the patch exceeds 1 MB, When attempting to copy, Then the UI blocks the action with a clear message and enables "Download Patch" instead. Given cosmetic changes are hidden, When generating the patch, Then cosmetic-only differences are excluded from the patch output.
Impact Analysis Panel Integration
Given the diff viewer is open, When the user opens the Impact Analysis panel, Then counts for users gaining access, users losing access, affected fields, and affected workflows are displayed and computed from the permission and workflow changes in the diff. Given a permission change row is selected, When the Impact panel is open, Then the panel filters to show only impacted identities and resources related to that change and displays consistent counts with the diff annotations. Given the user clicks "Start Approval" from the diff viewer, When the flow starts, Then the approval request is pre-populated with the diff id, change summary, and impact summary, and the viewer shows the request status as Pending Approval. Given user permissions, When a user without approval rights views the diff, Then the "Start Approval" button is disabled with a tooltip explaining required role.
Accessibility, Permissions, and Performance for Large Blueprints
Given keyboard-only usage, When navigating the diff viewer, Then all interactive elements (view toggle, expand/collapse, change list, copy patch, impact panel) are reachable in a logical tab order with visible focus indicators. Given a screen reader is active, When reading change items, Then each item exposes role and aria-label including change type (added/removed/modified), component type, and schema path. Given color requirements, When rendering highlights and badges, Then contrast ratios meet WCAG AA (>= 4.5:1 for text/icons). Given a 10k-node blueprint with 500 changes on a standard test machine, When computing the diff, Then initial compute completes within 5 seconds and 95th percentile interactions (expand/collapse, next/previous change) respond within 200 ms. Given access controls, When a user without Blueprint:ViewDiff permission attempts to open the viewer, Then access is denied; when a user lacks clearance for confidential fields, Then those field values are redacted in the diff while still indicating that a change occurred.
Access Impact Analysis
"As a compliance officer, I want to see who gains or loses access from a proposed change so that I can ensure permissions remain least-privilege and defensible."
Description

Automatically compute and display who gains or loses access due to permission changes by evaluating roles, groups, business units, and lines of business against the proposed blueprint. Present risk levels, justification hints, and least-privilege compliance checks, with exportable lists for audit. Support dry-run validation against directory data and cross-environment comparisons to ensure permission sets remain transparent and defensible.

Acceptance Criteria
Compute Gains/Losses by Role, Group, BU, and LOB
Given a current blueprint and a proposed blueprint with permission changes across roles, groups, business units, and lines of business When the user runs Access Impact Analysis Then the system computes two distinct result sets: GainedAccess and LostAccess And each result record includes principalId, principalType, displayName, sourceType (role|group), sourceId, businessUnitId, lineOfBusinessId, resourceId, permission, changeType (gain|loss) And counts per dimension (role, group, BU, LOB) and totals are displayed and match the cardinality of the result sets And results can be filtered by role, group, BU, LOB, resource, permission, riskLevel, and principalType, and filters update counts accordingly And results are stable (identical input yields identical output ordering and totals) And pagination supports pageSize up to 1000 with <500 ms page fetch on datasets up to 10,000 principals And full recomputation completes within 10 seconds on datasets with 10,000 principals and 100,000 entitlements
Risk Levels and Justification Hints Display
Given risk-scoring rules are configured (e.g., resource sensitivity, privilege scope change, segregation-of-duties conflicts) When impact results are displayed Then each change includes riskLevel ∈ {Low, Medium, High, Critical} derived from the active rules And each High or Critical item includes a justificationHint with ruleId, rationale text, and recommended mitigation And users can sort and filter by riskLevel, and the risk summary shows counts per level that match the filtered result set And High/Critical items are visually distinguished and include clear reasoning traceability (ruleId → ruleName) And risk computations are deterministic for the same inputs and ruleset
Least-Privilege Compliance Checks
Given least-privilege policy constraints are defined (e.g., maximum scope per role, allowed permission combinations) When analyzing proposed entitlements per principal Then any entitlement exceeding policy is flagged with complianceStatus=NonCompliant and associated policy ruleIds And redundant access via overlapping groups/roles is identified and flagged as reducible with a suggested action And a per-principal summary shows proposedPermissionsCount, minimalRequiredCount, and reductionOpportunityCount And a global compliance summary displays total noncompliant principals and breakdown by violated rule, matching the detailed flags
Exportable Audit Lists
Given impact results are present on screen When the user exports Gained and Lost access results as CSV and JSON Then exported files include header metadata: generatedAt (ISO 8601), blueprintVersion, environment, proposedBy, commitId, filterParams, resultChecksum And each row includes: principalId, principalType, displayName, sourceType, sourceId, businessUnitId, lineOfBusinessId, resourceId, permission, changeType, riskLevel, justificationHint.ruleId And exported content respects active filters and sort order and matches on-screen counts And files are available within 30 seconds for up to 100,000 rows and pass schema validation And an audit log entry records export metadata and a retrieval link valid for 30 days
Dry-Run Validation Against Directory Data
Given a configured read-only directory integration (e.g., SCIM/LDAP) and no write credentials When the user triggers a dry-run impact analysis Then the system fetches live directory memberships and attributes without persisting any changes And unresolved principals, disabled accounts, and orphaned groups are listed with reason codes And the dry-run summary shows counts of matched principals, unmatched principals, and discrepancies between blueprint assumptions and directory state And the audit log records that a dry-run executed with zero write operations
Cross-Environment Access Comparison
Given two environments are selected (e.g., Staging and Production) and a proposed blueprint is chosen When the user runs a cross-environment access impact comparison Then the results display per-environment Gained and Lost sets plus a delta view of differences between environments And identity resolution uses a stable globalPrincipalId to map accounts across environments And differences are labeled with environment tags and can be filtered to Only Differences And a summary highlights roles/groups that exist in one environment but not the other And exporting the comparison includes environment fields and is consistent with on-screen results
Workflow & Field Impact Preview
"As a claims manager, I want to preview affected fields and workflow steps so that I can anticipate operational impacts and update playbooks."
Description

Simulate and preview how blueprint changes will affect intake forms, NLP-extracted fields, validation outcomes, task routing, and automation triggers. Show before/after field visibility, read-only changes, default value shifts, and affected workflow steps. Run sample claims through a dry-run test suite, flag breaking changes, and provide remediation hints to reduce operational disruption in ClaimFlow.

Acceptance Criteria
Field Visibility and Read-Only Diff Preview
Given a draft blueprint with changes to field visibility or editability rules When the user opens the Workflow & Field Impact Preview Then a side-by-side before/after list shows all affected fields across all intake forms, including prior state (Visible/Hidden, Editable/Read-only) and new state And the preview displays per-form and total counts of affected fields And the user can filter by form, field group, role, and change type (visibility, read-only) And enabling "Show only changes" hides all unaffected fields And the preview renders within 5 seconds for blueprints up to 500 fields
Default Value Shift Detection
Given a draft blueprint that modifies default values or defaulting logic for one or more fields When the user runs the impact preview Then the system lists each affected field with explicit before/after default values and default source (static, rule, NLP) And the preview highlights any fields where the new default violates existing validation rules And the user can simulate toggling the defaulting rule on/off to see the resulting before/after defaults reflected immediately in the preview And all detected default shifts are counted and can be filtered by form and field group
Validation Outcome Impact Analysis
Given a selected sample claims dataset (system sample or user-uploaded) and a draft blueprint with rule changes When the user executes a dry-run validation Then the system reports, per claim, the count of newly failing validations, newly passing validations, and unchanged validations And a per-rule breakdown shows which rules caused new failures or resolutions, with severity and affected fields And no production data, tasks, or states are modified by the dry run And the dry-run completes within 10 minutes for up to 1,000 sample claims, or surfaces a progress indicator and partial results if longer
Task Routing and Automation Trigger Preview
Given a draft blueprint with changes to routing logic or automation trigger conditions When the user runs the impact preview on a sample claims set Then the preview shows before/after task queues, assignees, SLAs, and workflow steps for each claim And the preview lists triggers that would newly fire, cease firing, or change order, with conditions and target actions And a workflow diagram highlights steps added, removed, or reordered with change badges And differences are filterable by line of business, claim type, and queue
NLP-Extracted Field Mapping Impact
Given a draft blueprint that changes NLP extraction models, confidence thresholds, or field mappings When the user runs the impact preview on sample claim documents (photos and messages) Then the system displays before/after extraction confidence scores and mapped target fields for all impacted fields And any fields dropping below the configured confidence threshold are flagged as at-risk with an estimate of additional manual entry required And fields that will no longer auto-populate are listed per form with counts And the preview uses a fixed snapshot of documents to ensure repeatable results across runs
Breaking Change Flags and Remediation Hints
Given a draft blueprint introducing inconsistencies (e.g., required field becomes hidden, trigger references removed field, orphaned workflow step) When the impact analysis completes Then all breaking changes are flagged with severity (Critical, Major, Minor) and a plain-language description And each flag includes a remediation hint with the impacted component, suggested fix, and a deep link to the relevant editor location And the system prevents enabling rollout actions until all Critical items are acknowledged by the user And a summary widget shows total flags by severity and their current acknowledgment status
Staged Cohort Rollouts
"As a release manager, I want to roll out blueprint changes to staged cohorts so that I can minimize risk and control exposure."
Description

Enable phased deployment of blueprint versions to targeted cohorts defined by percentage, role, business unit, geography, carrier/MGA, or line of business. Support schedules, manual and auto-promotion gates, and runtime cohort resolution based on claim attributes. Track key rollout metrics (error rate, completion time, abandonment) and expose real-time status to allow safe, controlled exposure within ClaimFlow.

Acceptance Criteria
Percentage-based staged rollout with manual gates
Given blueprint version v2 of template T has a rollout plan with stages [10%, 50%, 100%] and manual promotion gates enabled And the eligible population is defined by predicate P When the rollout is started Then 10% ±0.5pp of the eligible population resolved at runtime is served v2 and 90% remains on v1 And no promotion occurs until an approver with role "Blueprint Admin" approves the gate When the approver promotes to the next stage Then exposure increases to 50% ±0.5pp within 5 minutes and remains stable for at least 30 minutes When the approver promotes to the final stage Then exposure reaches 100% and v1 is not assigned to new sessions while in-flight v1 sessions continue unaffected
Multi-attribute cohort targeting
Given a rollout cohort defined by role=Adjuster, businessUnit=Commercial, geography in [TX, FL], carrier in [ACME MGA], lineOfBusiness=Property When evaluating a new intake session and determining blueprint assignment Then only sessions initiated by users with role=Adjuster in Commercial BU for claims in TX or FL for ACME MGA Property LOB are eligible for exposure to v2 And all other sessions are routed to v1 (control) And percentage splits are applied within the filtered cohort, not the entire population
Runtime cohort resolution and stickiness
Given cohort eligibility is evaluated from claim (carrier, LOB, geography) and user (role, BU) attributes at session start When any of these attributes change mid-session Then the assigned blueprint version remains sticky for the duration of the session And subsequent sessions for the same claim re-resolve eligibility on session start And cohort resolution completes within 100 ms p95 And the assignment decision, input attributes, and version ID are logged with a unique decision ID
Scheduled rollout with auto-promotion by metrics
Given a rollout plan with scheduled stages [20%, 60%, 100%] at T0, T0+24h, T0+72h and auto-promotion gates with thresholds: errorRate<=2.0%, abandonmentRate<=5.0%, medianCompletionTimeDelta<=10%, p95CompletionTimeDelta<=15% When the 24h window for the 20% stage completes and all thresholds are met over the last 6 continuous hours Then the system automatically promotes to 60% within 10 minutes without manual action When any threshold is not met at a scheduled promotion time Then the promotion is skipped and an alert is sent to rollout owners and the rollout remains at the current stage
Automatic rollback on threshold breach
Given an active rollout stage with guardrail thresholds configured: errorRate>2.5% OR abandonmentRate>6% OR p95CompletionTimeDelta>20% sustained for 15 consecutive minutes When any guardrail condition is breached Then the system automatically rolls back exposure to the previous stable stage within 5 minutes And an incident record is created with the metrics, time window, and affected cohorts And new sessions are routed to the previous version; in-flight sessions continue with their assigned version
Real-time rollout status and audit visibility
Given a user with permission "Blueprint Rollout Viewer" When viewing the rollout status panel or calling GET /rollouts/{id}/status Then the response includes current stage, exposure %, eligible population size, counts by cohort filter, error rate, abandonment rate, median and p95 completion time, next scheduled promotion, gate status (manual/auto), last promotion actor/time, and rollback state And metrics freshness is <=60 seconds And all administrative actions (start, promote, pause, resume, rollback, override) are recorded with actor, timestamp, and reason
Rollout metrics collection and accuracy
Given instrumented events for sessionStart, sessionEnd (with completion time), errorOccurred, and abandoned (no submission within 30 minutes of sessionStart) When 1000 synthetic sessions are executed with a known distribution (e.g., 30 errors, 40 abandoned, predefined completion times) Then computed error rate, abandonment rate, median and p95 completion time for the rollout match ground truth within ±0.1 percentage points for rates and ±2% for times And metrics are segmented by blueprint version and cohort and exclude sessions where test=true And partial sessions older than 24h are classified as abandoned
Automatic Rollback & Safeguards
"As a site reliability engineer, I want automatic rollback based on predefined guardrails so that we can quickly recover from harmful changes without manual intervention."
Description

Provide configurable guardrails and health checks (e.g., error spikes, SLA breaches, KPI regressions) that trigger automatic rollback to the prior stable blueprint for affected cohorts. Support one-click manual rollback, idempotent state handling, stakeholder notifications, and preservation of audit artifacts to ensure quick recovery from harmful changes without data loss in ClaimFlow.

Acceptance Criteria
Auto Rollback on Error Spike (Cohort-Scoped)
Given blueprint version X is active for cohort A and prior stable version S exists And guardrails are configured: error_rate_threshold=2.5% over a 5-minute window and >=3x the 24h baseline When two consecutive 5-minute windows for cohort A exceed the configured thresholds after rollout of X Then the system halts new task starts on X for cohort A within 5 seconds of detection And the system rolls back cohort A from X to S within 2 minutes of detection And all in-flight tasks retain their identifiers and are completed or retried under S with 0 lost records and 0 duplicates And deployment status for cohort A shows from_version=X, to_version=S and state=Rolled back And an audit log entry is created with event_type=auto_rollback, trigger=error_spike, cohort=A, from_version=X, to_version=S, detection_metrics, timestamp, and correlation_id
Auto Rollback on SLA Breach (Latency Regression)
Given baseline metrics for cohort B are computed over the prior 24h: median T50_base and P95 P95_base And minimum sample size is configured as >=200 completed intake tasks per 10-minute window When for 10 consecutive minutes after deploying blueprint X the median exceeds T50_base by >=20% and P95 exceeds P95_base by >=30% with sample size met Then the system blocks further exposure of X to cohort B within 5 seconds of detection And the system rolls back cohort B to the prior stable version S within 3 minutes of detection And a rollback reason "SLA breach" with current vs. baseline metrics is attached to the audit record And notifications are sent to stakeholders with cohort, versions, metrics deltas, and correlation_id
One-Click Manual Rollback (UI & API)
Given an authorized user with permission rollback:execute selects blueprint version X and cohorts [A, B] with prior stable version S available When the user triggers rollback via UI button or POST /api/rollbacks with body {cohorts:[A,B], reason:"..." (>=10 chars)} and confirms Then the system initiates a rollback operation with rollback_id and shows real-time progress per cohort And each selected cohort transitions to S within 2 minutes unless blocked by a hard validation error And the operation is idempotent: repeat submissions with the same rollback_id produce no additional side effects and return status=already_rolled_back And partial failures are reported with error codes and remediation hints in UI and API response And the action is recorded in audit with actor=user_id, trigger=manual, cohorts, from/to versions, reason, timestamp
Idempotent Rollback Execution and Exactly-Once Effects
Given a rollback for cohort A from version X to S is initiated with rollback_id=R When the same rollback is retried (duplicate R) or two operators initiate concurrent rollbacks for cohort A Then at most one state transition record is committed for cohort A (no more than one version change) And downstream side effects (notifications, re-queues, metric snapshots) occur no more than once per cohort, deduplicated by R And subsequent attempts return 200 with status=already_rolled_back and do not emit duplicate notifications And a distributed lock with max hold <=30 seconds ensures single executor, with automatic release on failure And audit shows exactly one rollback event with correlation to any duplicate requests
Stakeholder Notifications and Operational Visibility
Given a rollback (automatic or manual) is initiated for any cohort When the rollback starts Then Slack, email, and webhook notifications are dispatched to configured recipients within 60 seconds with payload fields: correlation_id, trigger, severity, cohorts, from_version, to_version, start_timestamp And a persistent UI banner and incident panel appear in ClaimFlow within 30 seconds linking to live status When the rollback completes or fails Then completion/failure notifications are sent within 60 seconds with outcome, duration, error summary (if any), and links to audit artifacts
Audit Artifact Preservation & Export
Given any rollback operation executes When the operation completes (success or failure) Then the system preserves immutable artifacts for >=365 days: pre/post metrics snapshots, version diff (X vs. S), impacted permissions/access changes, cohort membership at trigger time, triggering guardrail config and observed values, actor/trigger, reason, and execution timeline And artifacts are tamper-evident (SHA-256 hash recorded) and access-controlled (viewable by roles: Compliance, Admin) And artifacts are exportable via UI and API to JSON and CSV within 30 seconds of request And audit trail entries are correlated by correlation_id across monitoring, rollout, and notification subsystems
Staged Cohort Guardrails and Scoped Rollback
Given a staged rollout plan for blueprint X (Pilot=5%, Canary=20%, General=100%) with guardrail thresholds configured per stage When a guardrail breach is detected in any stage (Pilot or Canary) Then only the impacted stage cohorts are rolled back to S within 2 minutes and promotion to the next stage is automatically blocked for 60 minutes And unaffected cohorts remain on their current stable version with no interruption And the rollout pipeline shows state=Blocked with the guardrail breach details and required approvals to resume And audit captures stage, cohorts, thresholds, observed metrics, and automatic block action
Approval Workflow & Compliance Reporting
"As a governance lead, I want a complete audit trail and approval workflow for blueprint changes so that changes are transparent, reviewable, and defensible to auditors."
Description

Introduce a role-based, multi-step approval process that packages the diff, impact analysis, rollout plan, and rollback strategy into a single review artifact. Capture approver comments, decisions, and timestamps, and generate immutable, exportable compliance reports (PDF/CSV/JSON) suitable for audits (e.g., SOC 2). Provide APIs and UI to search, filter, and present evidence of change control for permission transparency and defensibility.

Acceptance Criteria
Role-based multi-step approval bundles diff, impact, rollout, rollback into a single artifact
Given a blueprint diff is submitted for review And impact analysis, rollout plan, and rollback strategy are defined When the submitter starts the approval workflow Then the system creates a single, versioned review artifact with a unique ID And the artifact includes: diff summary, detailed changes, impacted users/groups (gains/losses), affected fields/workflows, staged cohorts, rollback plan, and related version hashes And approver stages and approver roles are resolved from role policy And notifications are sent to all approvers in the first stage
Capture approver decisions, comments, and timestamps per stage
Given an approver in the current stage opens the review artifact When they choose Approve or Reject Then a non-empty comment is required And the decision is recorded with approver user ID, role, stage number, decision value, UTC timestamp (ISO 8601), and artifact ID And the record is write-once and cannot be edited And the next stage is unlocked only when all required approvers in the current stage approve And on Reject, the workflow moves to Rejected state and the submitter is notified
Immutable audit trail with tamper evidence
Given any approval workflow event is recorded When the event is persisted Then it is stored in an append-only log with a cryptographic hash chain linking previous entries And delete and update operations are disabled; corrections create new compensating entries And the artifact and log expose a verification checksum (SHA-256) and sequence number And retention policy is configurable (default 7 years) and enforced
Export compliance reports in PDF, CSV, and JSON
Given a review artifact in Approved or Rejected state When a user with Reporting permission requests an export in PDF, CSV, or JSON Then the generated report includes: artifact ID, submitter, approvers and decisions with timestamps, diff summary, impacted entities, rollout/rollback details, audit log hash, and verification checksum And PDF exports are digitally signed and include a visible report ID and checksum And CSV and JSON adhere to the published schema and include headers/keys And exports for artifacts with ≤50k impacted entities complete within 30 seconds
Search and filter change-control evidence via UI and API
Given multiple review artifacts exist When a user searches by keyword and filters by date range, status, approver, decision, blueprint/template ID, cohort, and permission change type (gain/loss) Then the UI returns results and renders the first page within 2 seconds for datasets ≤50k artifacts And the API supports pagination (cursor-based), sorting, and the same filters via documented parameters And responses include total count, page cursor, and selected fields And access control restricts results to artifacts the requester is authorized to view; unauthorized requests return 403
Staged cohort rollout with automatic rollback and approval gates
Given a rollout plan defines N staged cohorts with gates (e.g., error rate threshold, incident flag) When an approver approves rollout Then the system enforces gates between stages and blocks progression until gate conditions are satisfied for the prior stage And if a gate is tripped, automatic rollback executes for the current and pending cohorts and notifications are sent to submitter and approvers And gate metrics, rollback trigger reason, and timestamps are recorded in the audit trail And manual override requires Admin role and creates a compensating audit entry

Timed Sharelinks

External share links that are purpose‑limited, field‑filtered, and auto‑expiring. Apply de‑identification and watermarks by template, restrict download/reshare, and track exactly who viewed what and when. Enables secure vendor/counsel collaboration without manual redaction or open‑ended access.

Requirements

Link Expiration & Purpose Limiting Controls
"As a claims manager, I want to set an explicit purpose and expiration on any external share so that access ends automatically and remains constrained to the stated need."
Description

Provide external share links that require a declared purpose and enforce auto-expiry at a specified date/time or after a defined number of views. Support per-recipient links, instant revocation, and controlled extensions with audit justification. Expiration applies uniformly across all shared assets (documents, images, messages) and prevents access via stale URLs or cached tokens. Integrates with ClaimFlow’s case record to log purpose, creator, recipients, TTL, revocations, and extensions for compliance review and reporting.

Acceptance Criteria
Purpose Declaration Mandatory at Share Creation
Given a user initiates an external share for a case, When they attempt to create a link without entering a purpose, Then the action is blocked with a validation message indicating purpose is required. Given a non-empty purpose is provided, When the link is created, Then the purpose is stored immutably with the link record and displayed on the recipient landing page and in the case audit log. Given an existing link, When a user attempts to edit the purpose via UI or API, Then the request is rejected and the user is instructed to revoke and create a new link. Given an API request to create a link omits the purpose or provides an empty string, When processed, Then the API returns HTTP 400 with an error code PURPOSE_REQUIRED and no link is created.
Time-Based Auto-Expiry Enforcement
Given a link is created with an absolute expiry date/time, When the current system time reaches or exceeds the expiry, Then access via the landing page and any direct asset URLs is blocked, the user sees an Expired message, and API/static requests return HTTP 410, and the event is logged to the case record. Given a user attempts to set an expiry in the past, When they submit the form or API request, Then the request is rejected with a validation error and no link is created/updated. Given a link has a defined expiry, When accessed before the expiry time, Then recipients can view the assets normally. Rule: Expiry must be specified for every external link; links without an expiry cannot be created.
View-Count Limited Access
Given a link is created with a maximum view count N, When N successful recipient sessions have occurred, Then subsequent attempts to access the link are blocked with a View limit reached message and API returns HTTP 410, and the event is logged. Rule: A view is counted when the landing page loads and the recipient successfully accesses at least one shared asset; reloads within the same session do not increment the count. Given the link has remaining views > 0, When a recipient accesses the link, Then the remaining view counter decrements by 1 and is displayed to the owner in the share management UI and via API. Given the view limit is reached, When a recipient tries to access a previously generated direct asset URL or cached token, Then access is denied and returns HTTP 410/403, preventing bypass via stale URLs.
Per-Recipient Links and Viewer Identity Tracking
Given per-recipient links are enabled and recipients A and B are specified, When the share is created, Then unique URLs are generated for each recipient and bound to their email identities. Given a recipient opens their unique URL, When they complete the one-time verification challenge (e.g., email OTP), Then access is granted only to that recipient and the view is attributed to their identity. Given any recipient accesses the link, When the session starts, Then the system logs viewer identity (recipient email), timestamp, IP, device/browser fingerprint, and assets accessed to the case record. Rule: A recipient cannot use another recipient’s URL to gain access; attempts are blocked and logged as denied with HTTP 403.
Instant Revocation and Stale URL Invalidation
Given a share link exists, When the owner selects Revoke and confirms, Then access to the landing page and all associated asset URLs is immediately blocked, active sessions are terminated, and API/static requests return HTTP 410/403. Given the link is revoked, When a recipient attempts to use a previously loaded page, bookmarked URL, or cached token, Then access is denied and the attempt is logged with reason Revoked. Given revocation occurs, When viewing the case audit log, Then an entry shows who revoked, when, which recipients were affected, and the reason (if provided).
Controlled Expiration Extensions with Audit Justification
Given a link is active and approaching expiry, When the owner requests an extension, Then the UI/API require an audit justification text and a new expiry date/time. Rule: The new expiry must be in the future and comply with tenant policy limits (e.g., not exceeding the maximum TTL measured from the original creation time); requests violating policy are rejected with validation errors. Given an extension is approved, When saved, Then the prior expiry, new expiry, justification, approver (if applicable), and requester are recorded in the case audit log and visible in reporting. Given a link is already expired but not revoked, When an authorized user extends it per policy, Then the link becomes accessible again until the new expiry, and the reactivation is logged.
Uniform Expiration Across Assets and Case Record Logging
Rule: Expiration state (time-based or view-based or revoked) applies uniformly to all shared assets (documents, images, messages) under the link; no asset remains accessible once the link is expired or revoked. Given a link has expired or reached its view limit, When a recipient attempts to access any direct asset URL previously issued (including CDN-cached or pre-signed URLs), Then the request is denied (HTTP 410/403), preventing access via stale URLs or cached tokens. Given any share lifecycle event occurs (creation, purpose, recipients, expiry settings, view consumption, revocation, extension), When the event is committed, Then the case record is updated to include purpose, creator, recipients, TTL, revocations, extensions, and timestamps, and the data is available via audit log UI and export/reporting API.
Field-Level Redaction & De-Identification Templates
"As an adjuster, I want to share only the minimum necessary claim details with a vendor so that privacy is protected while enabling them to do their work."
Description

Enable selectable, role-based templates that apply field filtering and de-identification before generating a sharelink. Templates leverage ClaimFlow’s NLP-extracted entities (PII, PHI, policyholder identifiers, contact details, location data, payment info) to auto-mask or exclude sensitive fields, scrub metadata, and blur/redact regions in images and PDFs. Preserve originals in ClaimFlow while sharing only transformed renditions. Provide preview and per-item overrides with an auditable record of what was included/excluded.

Acceptance Criteria
Role-Based Template Selection at Sharelink Creation
Given a user with role R in workspace W and multiple templates exist with role-based access controls When the user initiates a new sharelink for claim C Then the template picker lists only templates permitted for role R And the workspace default template for role R is preselected And the template name, version, and a concise rule summary are visible And the user cannot proceed to share without selecting an allowed template
Field-Level Filtering & De-Identification on Structured and Unstructured Data
Given a selected template that specifies field filters and de-identification rules for entity types (PII, PHI, policyholder identifiers, contact details, location data, payment info) And claim C contains structured fields and unstructured text where such entities are present When the system prepares the shareable rendition Then all entities targeted by the template are masked or removed according to rule (mask/exclude/replace) across structured and unstructured content And non-targeted fields remain unaltered And a machine-readable manifest enumerates each redaction/de-identification action by field/entity type and location
Image/PDF Region Redaction and Metadata Scrubbing
Given claim C contains images and PDFs with sensitive content and embedded metadata And the selected template includes image/PDF region redaction and metadata scrubbing rules When the system generates transformed renditions Then regions tagged as sensitive by detection/NLP are blurred or hard-redacted per template rule And EXIF, XMP, PDF properties (author, GPS, timestamps, device identifiers) are removed or normalized per template rule And the transformed files open without validation errors and without the original metadata present
Preview with Per-Item Overrides and Guardrails
Given a user has selected a template and the system has produced a draft transformed package for claim C When the user opens the preview Then a side-by-side or toggle preview shows original vs transformed for each item (documents, images, fields) And the user can apply per-item overrides allowed by the template (e.g., unmask specific fields, include/exclude specific artifacts) And overrides that would violate non-overridable rules are blocked with an explanation And all applied overrides are captured with user, timestamp, and rationale before sharelink creation
Originals Preserved; Share Serves Only Transformed Renditions
Given claim C has originals stored in ClaimFlow When a sharelink is created using a template Then originals remain unchanged and are not exposed via the sharelink And external viewers can access only the transformed renditions And internal users with appropriate permissions continue to see originals within ClaimFlow
Template-Driven Watermarking and Download/Reshare Restrictions
Given a selected template that defines watermark text/position and download/reshare restrictions When a recipient opens the sharelink Then every rendered page/image displays the configured watermark including dynamic placeholders (e.g., claim ID, share ID, expiry) And built-in download/reshare controls and file export endpoints are disabled if the template restricts them And if downloads are permitted by the template, the downloaded files contain the watermark as configured
Auditable Record of What Was Included/Excluded and Why
Given a sharelink is created for claim C using template T When the sharelink is finalized Then an immutable audit record is stored containing: template ID and version, actor, timestamp, list of included artifacts, list of excluded artifacts, field/entity-level redaction and de-identification actions, and any overrides And each transformed artifact is referenced with a checksum/hash and size And the audit record is retrievable and exportable for compliance review
Dynamic Watermarking & Traceable Overlays
"As a compliance officer, I want all externally shared materials watermarked with recipient and link details so that leaks can be deterred and traced back to the source."
Description

Apply configurable visible watermarks to all shared renditions with recipient identity, access timestamp, claim ID, and link ID. Support diagonal tiled overlays for documents and corner stamps for images/video, with opacity and size controls per template. Embed a machine-readable fingerprint (e.g., QR/code or hash) linking back to the share event for traceability. Ensure watermarking occurs server-side on-the-fly and is consistent across web viewer and any approved downloads (if allowed by policy).

Acceptance Criteria
Server-Side On-the-Fly Watermarking for Viewer and Downloads
Given an active share link with watermarking enabled by template When a recipient opens any asset in the web viewer Then the server renders the asset with the configured watermark applied before transmission, with no client-side compositing And the visible watermark content and placement match the template configuration And the unwatermarked original is never transmitted to the client Given the same share link permits download When the recipient downloads the asset Then the downloaded file is identically watermarked to the web viewer rendition for that access Given rendering load at P95 When 100 concurrent view requests are processed Then watermarking adds no more than 600 ms median and 1000 ms P95 latency per page/image and maintains successful render rate >= 99.5%
Watermark Payload Accuracy (Recipient, Timestamp, Claim ID, Link ID)
Given a share event initiated by link L and recipient R viewing claim C When R opens an asset at time T_view (UTC) Then the watermark text includes R’s display name or email, T_view in ISO 8601 UTC, C’s claim ID, and L’s link ID And those values match the system of record for R, C, and L Given R downloads an asset at time T_dl When the download is generated Then the watermark timestamp reflects T_dl, not T_view Given multiple accesses by the same or different recipients When each access occurs Then each rendition displays the precise per-access timestamp and recipient identity for that access
Diagonal Tiled Overlay Controls for Documents
Given a template configured with diagonal tiled overlays When rendering a multi-page PDF or document Then watermark tiles are applied across each page at the configured angle (default 45°), opacity (10–60%), and scale (tile repeat every 200–600 px) within allowed bounds And the overlay remains visible over light/dark content with contrast ratio >= 3:1 And no page content is obscured beyond 20% area coverage per page And administrators can adjust angle, opacity, and scale and see those changes reflected within one render cycle
Corner Stamp Controls for Images and Video
Given a template configured for corner stamps When rendering images of varying resolutions and aspect ratios Then the stamp appears in the selected corner(s) within a 4–6% margin, scales proportionally (2–6% of the shorter edge), and is not cropped Given a video asset When streamed or downloaded Then the stamp is rendered on all frames for the full duration, at a consistent position relative to frame dimensions, without desynchronization or flicker
Machine-Readable Fingerprint Linking to Share Event
Given a template with machine-readable fingerprint enabled When an asset is rendered Then a QR code or equivalent 2D barcode is embedded, encoding at minimum the share-event ID and verification endpoint URL with version prefix v1 And the code is decodable from the viewer and from a printed or screen-captured image at scales from 70% to 200% with error correction level >= M Given the fingerprint is resolved via the endpoint When the code is scanned Then the system returns the exact share-event record, including link ID, claim ID, recipient identity (if known), and access timestamp, and logs a “fingerprint_resolved” audit event Given fingerprint via hash-only mode When decoding is attempted Then the hash maps unambiguously to a single share-event in the system
Cross-Channel Consistency and Policy Enforcement
Given a share link policy that disallows downloads When a recipient views an asset Then the watermarked viewer rendition is served and no download route is exposed Given a share link policy that allows downloads When the recipient downloads Then the downloaded file contains the same watermark content and placement as the viewer rendition for that access event Given a share link with a specific watermark template When the template is updated Then subsequent views and downloads reflect the new template, and prior generated downloads remain with their original watermark
No-Download/No-Reshare Enforcement
"As a claims manager, I want to prevent external parties from downloading or resharing sensitive claim files so that materials cannot escape controlled access."
Description

Provide a secure web viewer that streams documents, images, and messages without file downloads, print, or native save where policy forbids it. Enforce single-session, device-bound tokens and disable link-forwarding by binding access to verified identity and session. Apply cache-control headers, PDF print/clipboard restrictions, and watermarking to mitigate exfiltration. Allow admins to optionally permit time-limited, watermarked downloads per template. Detect and block concurrent access patterns indicative of resharing and notify the owner.

Acceptance Criteria
Secure Viewer Blocks Download/Print/Save
Given a sharelink with policy set to "No Download/No Print/No Save" When the recipient opens content in the secure web viewer Then no direct file endpoints are requested by the client and assets are streamed only And the viewer UI shows no download or print controls And browser print shortcuts (Ctrl/Cmd+P) are intercepted with no print dialog shown And right-click save, Save As, and Open in New Tab are disabled on rendered assets And any attempt to fetch an original file URL returns HTTP 403 And responses for rendered assets never include Content-Disposition: attachment
Device-Bound Single-Session Token
Given a sharelink token has not yet been redeemed When the recipient starts a session on Device A Then the token is bound to Device A (device fingerprint + secure cookie) for the session And attempting to use the same link on Device B (different fingerprint or private window) returns HTTP 403 and shows an "Session in use" message And attempting to open a second parallel tab on Device A terminates the earlier tab or blocks the new one per policy with no content exposure beyond one active view And reusing the link after explicit logout or token expiry returns HTTP 401/403
Verified Identity Required; Forwarded Links Blocked
Given a sharelink requires identity verification to the designated recipient (e.g., email OTP or SSO) When the designated recipient completes verification Then access is granted and attributed to that verified identity When a user with a non-matching identity attempts verification using a forwarded link Then verification fails and access is denied with HTTP 403 and no content rendered And an audit event is recorded with attempted identity, timestamp, IP, and user agent
No Local Caching or Offline Retrieval
Given a view-only share with caching disabled When the recipient loads content in the secure viewer Then all HTTP responses include Cache-Control: no-store, Pragma: no-cache, and no ETag revalidation enabling storage And the app does not persist content in Service Worker, IndexedDB, localStorage, or memory caches beyond the active tab lifecycle And after closing the tab, relaunching the browser, or switching to offline mode, the content cannot be reloaded or viewed And attempting to view source or retrieve blobs from cache/storage yields no recoverable file content
Watermark Overlay and Clipboard Restrictions
Given a policy requiring watermarking and copy restrictions When the recipient views any page of a document, image, or message thread Then a semi-transparent, non-removable watermark is visibly overlaid on all pages/frames at all zoom levels showing recipient name/email, session ID, and timestamp And the watermark appears on screenshots of the viewer (visual inspection) and cannot be toggled off by user controls And text selection and copy, image copy, and PDF copy-to-clipboard actions are blocked such that the clipboard receives no protected content And attempts to print from PDF-specific controls are disabled/hidden
Template-Driven, Time-Limited Watermarked Downloads
Given a share template that permits downloads for a duration D with watermarking enabled When the recipient requests a download within the allowed window Then a file is delivered with an embedded visible watermark including recipient identity, timestamp, and link ID And the download event is logged with file identifier/hash, recipient identity, and timestamp And after D elapses, the download control is hidden/disabled and direct download endpoints return HTTP 403 And when the template does not permit downloads, no download control is shown and all download attempts return HTTP 403
Concurrent Access Detection and Owner Notification
Given concurrent access monitoring is enabled for a sharelink When two distinct IPs or device fingerprints attempt to access the same token within a 2-minute window Then the second access is immediately blocked with HTTP 403 and no content is rendered And the active session is optionally revoked per policy with a visible notice to the viewer And the share owner receives a notification within 60 seconds containing link ID, timestamps, IPs, device fingerprints, and user agents And an audit log entry is created reflecting the detection, block action, and notification status
Recipient Identity Verification & Access Logging
"As a privacy officer, I want recipients verified before viewing and a complete audit of who saw what and when so that we meet regulatory and client obligations."
Description

Gate sharelinks behind recipient identity verification via email one-time code, SMS OTP, or federated SSO (SAML/OIDC) for known partners. Capture identity, timestamp, IP, approximate geolocation, device/browser fingerprint, and item-level view events (opened, pages viewed, duration). Store immutable audit trails in ClaimFlow, with export to PDF/CSV and API access. Provide anomaly alerts (e.g., access from new country, excessive retries) and in-app timeline entries on the claim for every access event.

Acceptance Criteria
Email OTP Verification for Sharelink Access
Given a valid active sharelink configured with Email OTP verification When a recipient enters a syntactically valid email address and submits Then a 6-digit numeric OTP is sent to that email within 30 seconds And the OTP expires after 10 minutes and is single-use And a maximum of 5 OTP verification attempts per email per link are allowed within 15 minutes; additional attempts are blocked and logged Given the recipient enters the correct OTP within its validity window When verification succeeds Then access to the sharelink contents is granted for that browser session And a "verification_succeeded" event is recorded with link_id and recipient email And an "access_granted" event is recorded Given the recipient enters an incorrect or expired OTP, or exceeds the attempt limit When verification fails Then access is denied And a "verification_failed" event is recorded with reason_code (incorrect_code|expired_code|rate_limited) Given the sharelink is configured with an allowed recipient list When a non-allowed email is submitted Then the request is rejected with a generic error And a "recipient_not_allowed" event is recorded
SMS OTP Verification for Sharelink Access
Given a valid active sharelink configured with SMS OTP verification When a recipient enters a valid E.164-formatted phone number and submits Then a 6-digit numeric OTP is sent via SMS within 30 seconds And the OTP expires after 10 minutes and is single-use And a maximum of 5 OTP verification attempts per phone number per link within 15 minutes is enforced and logged And OTP resend is limited to 3 within 10 minutes per phone number Given the recipient enters the correct OTP within its validity window When verification succeeds Then access to the sharelink contents is granted And "verification_succeeded" and "access_granted" events are recorded with the normalized E.164 phone number Given the sharelink is configured with an allowed country list When a phone number from a non-allowed country is submitted Then the request is rejected And a "recipient_not_allowed" event is recorded with reason_code country_not_allowed Given an incorrect or expired OTP, or exceeded attempt limit When verification is attempted Then access is denied And a "verification_failed" event is recorded with reason_code (incorrect_code|expired_code|rate_limited)
Federated SSO (SAML/OIDC) for Partner-Restricted Sharelinks
Given a sharelink configured for federated SSO with a partner allow-list When a recipient initiates sign-in Then the user is redirected only to configured IdPs (SAML/OIDC) for that sharelink Given the IdP returns a successful assertion/token When the subject/email maps to an allowed partner identity per configuration Then access is granted And identity attributes (subject, email, display_name, idp_provider, auth_time) are captured And "verification_succeeded" and "access_granted" events are recorded Given the assertion/token is invalid, expired, or the user is not in the allow-list When the callback is processed Then access is denied And a "verification_failed" event is recorded with reason_code (idp_error|token_expired|user_not_allowed) Given the IdP conveys MFA via a standard claim (e.g., amr/acr) When verification succeeds Then an mfa_used flag is recorded in the event metadata
Comprehensive Access Logging (Identity, IP, Geo, Device)
Given any verification, access, or view event occurs for a sharelink When the event is persisted Then the record includes: event_type, event_id, link_id, claim_id, identity_type (email|phone|sso), identity_value (normalized), timestamp_utc (ISO 8601 with milliseconds), ip_address (IPv4/IPv6), approximate_geolocation (country, region/state, city), user_agent, device_fingerprint_hash (stable), and outcome (success|failure) when applicable Given an access log record exists When a write/update/delete is attempted via UI or API Then the operation is rejected (HTTP 405/409 for API) and the attempt is appended as a separate security_event Given the same device returns within 30 days without major environment changes When device fingerprinting runs Then the same device_fingerprint_hash is produced with at least a 95% match rate across sessions Given the IP geolocation provider is unavailable When an event is logged Then the event is stored with geo fields set to null and a geo_lookup_error flag set to true
Item-Level View Event Tracking and Duration Metrics
Given a recipient opens a multi-page document through the sharelink When pages are viewed Then events are recorded: document_opened, page_viewed (with page_number), and document_closed And viewing duration per page and per document is captured with 1-second granularity and excludes background/inactive tab time Given a recipient plays a video through the sharelink When playback actions occur Then events are recorded: video_play_started, video_paused, video_seeked (with from_time and to_time), and video_completed And total watch time and completion percentage are computed within ±1 second accuracy Given images are viewed via a gallery When an image is opened or switched Then image_viewed events are recorded with image_id and dwell_time in seconds
Immutable Audit Trail with PDF/CSV Export and API Access
Given access and view events exist for a claim When exporting to CSV Then the file contains one row per event with columns: claim_id, link_id, event_id, event_type, identity_type, identity_value, timestamp_utc, ip_address, country, region, city, user_agent, device_fingerprint_hash, resource_id, resource_type, page_or_time_metadata, outcome, reason_code And up to 10,000 events export in under 60 seconds Given access and view events exist for a claim When exporting to PDF Then events are listed in chronological order with the same core fields, include a summary section (totals by event_type and outcome), and generate in under 60 seconds for up to 1,000 events And the PDF footer includes the export_timestamp_utc and a checksum of included event_ids Given an API client with audit.read scope When calling the audit trail API Then results are filterable by claim_id, link_id, identity_value, event_type, and date_range And responses are cursor-paginated with stable ordering (timestamp_asc, event_id tiebreaker) And the API responds within 2 seconds for pages up to 500 events Given any attempt is made to modify or delete an existing audit event via API When the request is processed Then it is rejected with HTTP 405/409 And a security_event is appended noting the attempt
Claim Timeline Entries and Anomaly Alerts
Given any access verification, grant, denial, or item-level view event occurs When the claim timeline is updated Then a timeline entry is added within 5 seconds containing: event_type, masked recipient identity per policy, timestamp_utc, ip_address, geolocation summary, device/browser summary, and link_id And visibility follows ClaimFlow claim permissions Given an access attempt from a country not previously seen for that link or identity within the last 90 days When the event is processed Then an anomaly alert is generated within 60 seconds And the claim timeline includes an anomaly_detected entry with reason new_country Given 5 or more failed OTP attempts occur for the same link within 10 minutes When the threshold is reached Then an anomaly alert is generated and the link is temporarily locked for 15 minutes And link_locked and anomaly_detected entries are recorded Given access from a new device_fingerprint_hash for the same identity within 24 hours When detected Then an anomaly alert is generated and recorded with reason new_device
Sharelink Templates & Policy Engine
"As a system admin, I want centrally managed sharelink templates and policies so that teams apply consistent, compliant settings without manual configuration each time."
Description

Allow admins to define reusable templates that bundle TTL, purpose requirements, de-identification rules, watermark configuration, download permissions, and verification methods. Support role-, claim-type-, and environment-based policies with precedence and conflict resolution. Version templates with change history and require approval for high-risk changes. Auto-select a default template based on recipient role (e.g., counsel, contractor) and workflow context, while allowing authorized overrides with justification logging.

Acceptance Criteria
Template Creation with Full Control Set
Given an admin with Template Admin permissions and a valid session When they create a new sharelink template specifying TTL, purpose requirement, de-identification rules, watermark configuration, download/reshare permissions, and verification methods Then the API responds 201 Created with templateId, name, and version=1 and all fields persist exactly as submitted And retrieving the template by templateId returns the same configuration values And validation errors are returned (400) when required fields are missing or TTL is outside allowed bounds (15 minutes to 30 days) And a watermark preview endpoint returns an image where dynamic tokens (claimId, recipientEmail, timestamp) are rendered per configuration And the template is not usable if status is Draft until explicitly Published by an authorized user
Auto-Select Default Template by Role and Context
Given a recipient role of Counsel and workflow context of Litigation Notification for a P&C claim When a sharelink is requested without an explicit template Then the policy engine selects the highest-priority matching template and returns its templateId within 200 ms (p95) And the selection event is logged with evaluated policies, winning policyId, templateId, claimType, environment, and timestamp And if no policy matches, the global default template is selected and logged And if the selected template is in Pending Approval, selection is rejected with 409 and a remediation message
Authorized Override with Mandatory Justification and Audit Trail
Given a user with Override Template permission initiates a sharelink where a default template is auto-selected When they choose a different template And they provide a justification of at least 15 characters and select a reason code Then the override is accepted and the sharelink uses the chosen template And an audit record captures actorId, originalTemplateId, overriddenTemplateId, claimId, reasonCode, free-text justification, timestamp, and requestId And overrides by users without permission are blocked with 403 And overrides without justification or reason code are rejected with 422
Deterministic Policy Precedence and Conflict Resolution
Given multiple active policies match on role, claimType, and environment When the policy engine evaluates a selection Then it applies precedence in this order: (1) environment-specific over global, (2) higher numeric policy priority over lower, (3) more specific condition match (role+claimType) over single-dimension matches, (4) most recent effectiveAt date over older, (5) lowest policyId as final tie-breaker And the same inputs always yield the same selected template (idempotent) And the evaluation trace output lists all candidate policies with their score and the applied tie-breakers And administrators can update numeric policy priority and see the new order take effect immediately on the next evaluation
Template Versioning, History, and Rollback Integrity
Given an existing Published template at version 1 When an admin edits de-identification rules and saves Then a new immutable version 2 is created with author, timestamp, change summary, and diff of modified fields And retrieving version 1 returns the original configuration And setting version 1 as the active version creates version 3 as a rollback with a system-generated summary referencing the rollback source And the history view lists all versions in descending order with approver (if any), status (Draft/Published/Deprecated), and effectiveAt timestamps
Approval Required for High-Risk Template Changes
Given a governance policy that marks as high-risk any change that (a) disables de-identification, (b) enables downloads where previously disabled, or (c) increases TTL beyond 7 days When an admin attempts to publish such a change Then the template version transitions to Pending Approval and cannot be used for new sharelinks And only users with Template Approver permission can approve or reject, with MFA enforced at approval time And approval records include approverId, decision, comment, timestamp, and versionId And attempts to use a Pending Approval version return 409 with details of the blocking approval
Runtime Enforcement of Template Controls and Viewer Tracking
Given a sharelink created with a template that enforces de-identification=ON, watermark=ON, download=DISABLED, reshare=DISABLED, verification=Email OTP, and TTL=72h When a recipient accesses the link Then access requires successful OTP verification within 5 minutes or the attempt is logged and denied And the served content masks fields per the template’s de-identification rules and renders a visible diagonal watermark containing claimId, recipientEmail, and accessTimestamp And download and reshare controls are absent/disabled at the UI and blocked at the API/CDN layer And every view/write action is logged with viewer identity, IP, user-agent, resourceId, templateId, templateVersion, and timestamp And after TTL expiry or manual revocation, subsequent accesses return 410 Gone and are logged
Workflow Integration & Event Webhooks
"As a workflow designer, I want sharelink events to drive automated tasks and notifications so that collaboration moves forward without manual chasing."
Description

Integrate sharelink creation and status into ClaimFlow workflows: generate links from tasks, attach to case timelines, and surface real-time indicators (sent, viewed, expired, revoked). Emit webhooks and in-product notifications for key events (viewed, download attempted, expired, verification failed) to trigger follow-up tasks or SLA timers. Provide REST APIs to create, revoke, extend, and audit sharelinks, enabling partner systems to orchestrate collaboration without manual steps.

Acceptance Criteria
Generate Sharelink via Workflow Task Action
Given a claims user with "Sharelink:Create" permission is viewing a workflow task, When they click "Create Timed Sharelink" and provide required fields (template_id, expiry, restrictions), Then POST /sharelinks returns 201 with sharelink_id, url, status=Sent, and response time <= 2s p95. Then the created sharelink is associated to the correct claim_id and task_id and persisted with a unique ID. Then default policy values are applied when optional fields are omitted (e.g., ttl=7d, download=false). When validation fails (e.g., invalid expiry, missing template), Then no sharelink is created, the user sees inline error messages, and the API returns 4xx with error codes. Then an audit record is written capturing actor, timestamp, action=create_sharelink, parameters (excluding secrets), and outcome=success|failure.
Attach Sharelink Events to Case Timeline
Given a sharelink is created for a claim, When creation completes, Then a "Sharelink Created" timeline entry is added with sharelink_id, created_by, template_id, expiry, and restrictions. When the recipient views the link, Then a "Sharelink Viewed" timeline event is appended with viewer identity (if verified) or "unknown", IP, user_agent, and ISO 8601 timestamp. When the link expires or is revoked, Then a timeline entry reflects status change to Expired or Revoked and includes who/what caused it (user, policy, API). Then the timeline supports filtering by "Sharelinks" and searching by sharelink_id, returning results <= 1s p95. Then timeline entries are immutable; corrections appear as new events referencing the prior entry_id.
Real-time Status Indicators in Task and Case Views
Given a task or claim has one or more sharelinks, Then each sharelink displays a status badge from the set {Sent, Viewed, Download Attempted, Expired, Revoked, Verification Failed}. When a relevant event occurs, Then the badge updates in real time within 5s p95 without requiring a page refresh. Then the badge tooltip shows last_event_type, last_event_time, and total_view_count matching audit data. Then if multiple sharelinks are present, the aggregate badge reflects the highest severity per rule: Revoked > Expired > Verification Failed > Download Attempted > Viewed > Sent. Then badges meet accessibility: ARIA labels present, keyboard focusable, color contrast >= 4.5:1.
Webhook Emission for Key Sharelink Events
Given a partner endpoint is registered with event types and an HMAC secret, When one of {sharelink.viewed, sharelink.download_attempted, sharelink.expired, sharelink.revoked, sharelink.extended, sharelink.verification_failed} occurs, Then the system POSTs a JSON payload containing event_id (UUID), event_type, version, sharelink_id, claim_id, task_id, occurred_at (ISO 8601), actor (if available), and context. Then each request includes an X-Signature (HMAC-SHA256 of the body) and X-Idempotency-Key headers. Then delivery latency is <= 5s p95 from event time. When the receiver returns non-2xx, Then the system retries 3 times with exponential backoff (e.g., 1s, 5s, 30s); after retries fail, the event is marked failed and moved to DLQ. Then duplicate deliveries (retries) carry the same event_id and X-Idempotency-Key to enable deduplication.
Webhook Delivery Monitoring and Dead-Letter Handling
Given webhooks are configured, Then an admin view shows per-endpoint metrics: last_success_at, failure_count (rolling 1h), delivery p95 latency, and retry queue depth. When an event exhausts retries, Then it is placed into a dead-letter queue with failure_reason and next_actions=replay|discard, and an in-product alert is created for admins. When failure rate > 5% over 15 minutes for any endpoint, Then the system triggers an alert to configured channels (in-product + email) and flags the endpoint as degraded. When an admin clicks Replay on a DLQ item, Then the event is resent honoring original event_id and signature versioning; success removes it from DLQ and updates metrics. Then monitoring data is retained for at least 30 days and is exportable via API.
REST APIs to Create, Revoke, Extend, and Audit Sharelinks
Given OAuth2 access token with scope sharelinks.write, When POST /sharelinks is called with {claim_id|task_id, template_id, expires_at|ttl, allowed_actions, field_filters, deid_template_id}, Then response is 201 with sharelink resource, url, and status=Sent; Idempotency-Key is honored to prevent duplicates. When POST /sharelinks/{id}/revoke is called by an authorized user/app, Then status transitions to Revoked, access is immediately blocked, and a webhook sharelink.revoked is emitted. When POST /sharelinks/{id}/extend is called with a later expires_at (and not Revoked), Then expiry is updated, prior expiry is recorded, and webhook sharelink.extended is emitted. Given scope sharelinks.read, When GET /sharelinks/{id}/events is called, Then events are returned paginated (default 50) with type, timestamp, actor, and source (webhook|ui|api). Then all endpoints enforce RBAC (must have access to the claim), rate limiting (>= 100 req/min per client; 429 with Retry-After on exceed), and return OpenAPI-described error codes.
Event-triggered Follow-up Tasks and SLA Timers
Given a workflow builder rule "On Sharelink Event", When configured with triggers (viewed, expired_without_view, verification_failed, download_attempted), Then the engine evaluates events in real time and fires matching rules once per sharelink per rule. When a rule fires, Then the system can create a follow-up task, assign to a queue/user, set due_date, start or pause an SLA timer, and add a note referencing sharelink_id and event_id. Then rule conditions support filters: template_id, task_type, recipient_domain, first_view_only boolean, event_count >= N within T minutes. Then execution is idempotent using a rule_firing_id; repeated events do not create duplicate tasks. Then end-to-end latency from event to task creation is <= 10s p95 and actions are logged with correlation_id linking event, rule, and created artifacts.

Scope Advisor

Data‑driven recommendations to tighten roles to the minimum needed. Learns from actual task usage, SLA needs, and upcoming workflows to suggest adds/removals with productivity vs. risk tradeoffs. One‑click apply with rollback keeps access right‑sized as teams and rules evolve.

Requirements

Role Usage Telemetry
"As a Claims Operations Manager, I want to capture granular role and permission usage across tasks so that Scope Advisor can learn real access needs and avoid over-provisioning."
Description

Implement an event-driven telemetry pipeline that captures granular permission and task usage across ClaimFlow (e.g., claim intake, triage, document handling, messaging). Log user ID, team, role, permission/entitlement, task ID, claim type, action, timestamps, duration, and outcome, with contextual metadata (SLA, queue, environment). Normalize events into a schema suitable for aggregation and model training, with sampling controls, PII minimization, and configurable retention. Provide near real-time aggregation (sub-5 minutes) and backfill capabilities, resilience (at-least-once delivery), and privacy controls (regional data residency, opt-outs where applicable). Expose summarized usage features to Scope Advisor via a feature store to inform least-privilege recommendations.

Acceptance Criteria
Usage Event Capture and Schema Conformance
Given a user performs actions in intake, triage, document handling, and messaging When each action completes Then exactly one telemetry event is emitted per action at source with a unique event_id (UUIDv4) And the event conforms to schema version v1.0 with required non-null fields: event_id, user_id, team_id, role_id, permission_or_entitlement, task_id (nullable for non-task actions), claim_type, action, timestamp_start, timestamp_end, duration_ms, outcome, sla_id (nullable), queue_id (nullable), environment And 100% of actions in the test matrix produce a valid event that passes schema validation and is observable in the raw telemetry stream And field types and enumerations match the contract (e.g., outcome in {success, failure}, environment in {dev, staging, prod})
Sampling Controls Per Tenant and Event Type
Given sampling for event_type=document_view is set to 25% for Tenant A in staging When 10,000 such events occur Then 22%–28% of those events are ingested (observed in the raw stream) and carry sampling_rate=0.25 in the header And given sampling for event_type in {permission_change, task_assignment} is set to 0% (no sampling) When those events occur Then 100% are ingested regardless of global sampling settings And when the sampling configuration is updated in the config store Then the new policy takes effect within 5 minutes without service restarts and is recorded in an audit log with actor, old_value, new_value, and timestamp
PII Minimization, Residency, Opt-Outs, and Retention
Given the PII allowlist policy is enabled When telemetry events are written Then only pseudonymous identifiers for user and claim are stored; free-text message content, emails, phone numbers, and document bodies are not stored And given tenant.region=EU When events are persisted Then both raw and aggregate data reside in EU-designated storage/services with region tags verifying residency And given a tenant or user has telemetry_opt_out=true When actions occur Then no telemetry is persisted for that principal and an audit entry with reason=opt_out is recorded And given retention_raw_days=90 and retention_aggregate_days=365 When data reaches the configured age Then deletion jobs purge data within 24 hours and emit a deletion report listing partitions and counts
Near Real-Time Aggregation SLA
Given a steady ingestion rate of 100 events/sec in production When events are processed end-to-end Then the 95th percentile latency from timestamp_end to aggregate availability in the feature store is <= 5 minutes and the 99th percentile is <= 7 minutes And when a 5-minute upstream pause occurs Then the pipeline auto-recovers and returns to the <= 5-minute P95 freshness within 10 minutes of resume And windowed aggregates (last_7d, last_30d) reconcile with raw counts within 1% absolute error on a validation sample
Backfill and Reconciliation
Given a historical date range is requested for backfill When the backfill job runs Then aggregates are recomputed from raw events idempotently (no duplicate feature rows) and written partition-by-partition And backfilled aggregates match streaming aggregates for the same period within 1% for counts and within 100 ms for last_used timestamps And when backfill runs concurrently with live ingestion Then there is no downtime; consumer lag remains < 2 minutes and CPU utilization remains < 70% on the ingestion cluster
At-Least-Once Delivery and Deduplication
Given induced broker failures and consumer restarts When events are retried Then no events are lost (0 dropped events in test) and duplicates are eliminated downstream using the composite key (event_id, timestamp_start) And aggregates are updated via idempotent upserts so monotonic metrics (e.g., total_permission_uses) do not spike during retries And with a 1% random processing failure rate injected Then retry with exponential backoff succeeds and the error queue rate remains < 0.1% over a 1-hour test
Feature Store Exposure to Scope Advisor
Given Scope Advisor queries the feature store for a role_id and time window When the request is executed Then the response includes features: permission_usage_freq, task_usage_freq, last_used_at, active_user_count, sla_breach_risk_score, upcoming_workflow_need_score with schema_version And feature freshness_time is <= 5 minutes old for real-time windows and matches partition timestamps for historical windows And only the Scope Advisor service account can read these features; unauthorized principals receive 403 and the attempt is logged And data quality checks show null rate per feature < 0.1% and weekly DQ reports are generated with pass/fail status
SLA & Workflow Forecast Ingestion
"As a Team Lead, I want the system to consider upcoming SLAs and workflows so that recommendations anticipate demand and prevent access blockers during peaks."
Description

Ingest and maintain a forecast of upcoming workflow demand and SLA requirements by line of business, region, and team. Sources include current backlog, seasonality, release calendars, catastrophe events, and configured workflow schedules. Translate the forecast into predicted permission needs (e.g., features and data domains required) over a configurable horizon (e.g., 30/60/90 days). Provide APIs and UI inputs for operations to adjust assumptions and what-if parameters. Feed these features into Scope Advisor so recommendations consider near-term demand and avoid removing access needed for imminent work.

Acceptance Criteria
Multi-Source Forecast Ingestion Pipeline
Given valid connectors and credentials for Backlog, Seasonality, Release Calendar, Catastrophe Events, and Configured Workflow Schedules When the daily ingest job runs at 02:00 UTC or a manual run is triggered Then data from each source is pulled and normalized within 15 minutes And records are keyed by line_of_business, region, team, and date And per-source success rate is >= 99.0% with rejected records captured with error_code and reason And a run summary is persisted with counts, latency per source, and success/failure status
Forecast Aggregation by LOB/Region/Team
Given normalized source data for the last 24 months and current backlog When the forecast is generated Then the system produces daily buckets for the configured horizon (30/60/90 days) And each bucket contains one row per unique combination of line_of_business, region, and team And each row includes predicted_task_volume (integer), required_sla_hours (integer), and source_attribution (array) And rows exist for combinations with zero predicted volume (predicted_task_volume = 0)
Configurable Forecast Horizon and Refresh Controls
Given the forecast horizon is set to 60 days in Admin > Forecast Settings When an operator changes the horizon to 90 days via UI or PATCH /forecast/settings Then the next generation job uses 90 days and replaces prior 60-day horizon output And a manual Regenerate Now triggers a full recompute within 10 minutes And all changes are audited with user_id, old_value, new_value, and timestamp
Permission Needs Translation from Forecast
Given a mapping table links workflows and tasks to required features and data domains When a forecast is generated for a time bucket Then the system outputs permission_needs per LOB/region/team/bucket with feature_ids and data_domains And each permission_need includes min_user_count_required derived from predicted volume and SLA And each permission_need includes a justification referencing the driving workflows or tasks And permission_needs are retrievable via GET /permission-needs and displayed in the UI
Ops What-If Adjustments (UI & API)
Given an operator with role Operations_Manager When they create a what-if scenario that applies +25% catastrophe uplift and excludes Release Calendar via UI or POST /forecast/what-if Then the system validates inputs and returns a scenario_id And a forecast is generated for the scenario without overwriting the baseline And the UI shows deltas vs baseline by LOB/region/team with percentage and absolute changes And the scenario can be promoted to baseline only via an explicit Promote to Baseline action
Scope Advisor Consumption and Safe-Removal Guardrails
Given the forecast indicates feature FNOL_Edit is required for Team Alpha within the next 30 days When Scope Advisor evaluates access removals for Team Alpha members Then it does not recommend removal of FNOL_Edit unless the operator enables an explicit override flag And the recommendation includes a warning with the forecast time window and demand justification And all suppressed or overridden removals are logged with user_id, permission_id, and reason
Failure Handling and Data Freshness Indicators
Given one or more sources are unavailable during ingestion When the job retries up to 3 times with exponential backoff Then, if the source remains unavailable, the forecast is generated using the last successful snapshot for that source And the affected forecast segments are marked stale with stale_since timestamp And an alert is sent to Ops via the configured channel and GET /forecast returns X-Data-Freshness headers
Explainable Access Recommendations
"As a Claims Manager, I want clear, explainable access recommendations so that I can trust and act on them quickly."
Description

Generate add/remove suggestions at the user, team, and role level based on observed usage, SLA-driven forecasts, and policy constraints. Provide explanations that cite top evidence (e.g., last-used dates, frequency, similar peers, upcoming workflows requiring access) and a confidence score. Allow filtering by team, role, permission, and confidence threshold, with batch selection and export. Surface predicted impact metrics (e.g., minutes saved/week if applied) and identify dependencies (e.g., feature bundles). Deliver recommendations via UI and API on a daily cadence with incremental updates.

Acceptance Criteria
Cross‑Level Explainable Recommendations
Given historical permission usage, SLA targets, and policy constraints are available When the system generates the daily recommendation set Then it produces add/remove suggestions at the user, team, and role levels And each suggestion includes a confidence score between 0.00 and 1.00 (two decimal places) And each suggestion includes at least two evidence items from: last-used date, usage frequency, similar peers, upcoming workflow requirements, each with concrete values And no suggestion violates stated policy constraints (e.g., segregation-of-duties rules) And each suggestion has a globally unique ID and generated_at timestamp in ISO 8601 UTC
Filter and Sort Recommendations
Given a recommendations list exists When filters are applied for team(s), role(s), permission(s), and a minimum confidence threshold Then only suggestions matching all selected filters (AND semantics) are returned And confidence threshold filters out any suggestion below the specified value And results are sorted by confidence descending, then by generated_at descending for ties And applying the same filters returns the same ordered results deterministically And the total count and page count reflect the filtered result set
Batch Selection and Export
Given a user selects N (1–10,000) recommendations in the UI When the user exports as CSV or JSON Then the export completes within 10 seconds for N <= 5,000 and within 30 seconds for N <= 10,000 And each record includes: recommendation_id, entity_type (user|team|role), entity_id, action (add|remove), permission_or_bundle, confidence, top_evidence (max 3), predicted_impact.minutes_saved_per_week, dependencies (list), generated_at And CSV uses UTF-8 with headers; JSON is UTF-8 with an array of objects And the API export endpoint returns HTTP 200 with correct Content-Type and supports server-side pagination for result sets >10,000
Predicted Impact Metrics Display
Given impact modeling is enabled When recommendations are displayed Then each suggestion shows minutes_saved_per_week as a non-negative integer with units And at least 90% of suggestions include a populated minutes_saved_per_week value; those without display "N/A" And the UI summarizes the total minutes_saved_per_week for the current selection And the API includes minutes_saved_per_week in the recommendation payload
Dependency Identification and Handling
Given some permissions are part of feature bundles or have prerequisites When a recommendation involves a dependent permission Then the recommendation lists all required dependencies by name and ID And the UI prevents selecting a dependent recommendation without its required dependencies or clearly flags missing dependencies And exports include the full dependency list for any dependent recommendation And the API payload includes dependencies as a list of permission_or_bundle IDs with relationship type (bundle|prerequisite)
UI and API Field Parity and Filtering
Given the Recommendations API is queried with the same filters used in the UI When the API is called with team, role, permission, and min_confidence parameters Then the API returns the same count and ordered results as the UI for the same snapshot And the API response schema includes: recommendation_id, entity_type, entity_id, action, permission_or_bundle, confidence, top_evidence, predicted_impact, dependencies, generated_at And API supports pagination (page, page_size up to 500), sorting by confidence and generated_at, and returns X-Total-Count header And unauthorized requests receive HTTP 401; rate-limited requests receive HTTP 429 with Retry-After
Daily Cadence and Incremental Updates
Given the daily schedule is set to 02:00 UTC When the job runs successfully Then a new recommendation snapshot is published with last_refreshed timestamp And an incremental feed is available that returns only recommendations created, updated, or retired since a provided since timestamp And each recommendation includes a change_type (created|updated|retired) in the incremental feed And if the job fails, an alert is emitted and the system retries with exponential backoff; upon recovery, a single consolidated incremental update is produced without duplication
Risk-Productivity Tradeoff Scoring
"As a Security Officer, I want each change scored for productivity and risk so that I can balance efficiency with least-privilege obligations."
Description

Compute a composite score for each proposed access change that balances predicted productivity impact against risk exposure. Risk inputs include separation-of-duties conflicts, PII/sensitive data access, regulatory tags (e.g., HIPAA/GLBA), cross-region data movement, and stale-but-active entitlements. Productivity inputs include task completion latency, handoff reduction, and historical usage recency/frequency. Provide tunable weights by policy profile and display risk tiers (Low/Med/High) with rationale. Expose the score to drive recommendation sorting, approval routing, and guardrail enforcement.

Acceptance Criteria
Composite Score Calculation with Tunable Weights
Given a policy profile with defined weights for risk and productivity factors And a proposed access change with quantified inputs (SoD conflict severity, PII category access, regulatory tags present, cross-region movement flag, stale entitlement age; predicted task latency delta, handoff reduction count, usage recency/frequency) When the composite tradeoff score is computed Then the score is calculated as the weighted sum of normalized inputs and returned as a numeric value in the range 0–100 with 2-decimal precision And given identical inputs and the same policy profile version, repeated computations return an identical score And changing any single weight by +10% changes the score proportionally to that factor within 0.10 absolute tolerance due to rounding And the response includes the policy profile ID and version used for scoring
Risk Tier Assignment and Rationale Display
Given risk inputs for a proposed access change and a policy profile with risk-tier thresholds (default: Low 0–29.99, Medium 30–69.99, High 70–100 if not configured) When risk exposure is evaluated Then a risk tier of Low, Medium, or High is assigned consistently with the thresholds And the output includes a numeric risk score (0–100) and a structured rationale list with at least the top 3 contributing factors And rationale entries include reason codes and details: SoD rule IDs for conflicts, regulatory tag names (e.g., HIPAA, GLBA), source/destination regions for cross‑region movement, and entitlement age in days for stale access And the risk tier label, numeric risk score, and rationale are all present and non-empty
Recommendation Sorting by Tradeoff Score
Given a list of proposed access changes with computed composite scores and sub-scores When the list is requested in sorted order Then items are ordered descending by composite tradeoff score And ties are broken by higher predicted productivity impact first, then by lower risk exposure, then by ascending change ID And the sort is stable such that items fully equal in keys preserve original relative order And the API response includes each item's sort keys for verification
Approval Routing and Guardrail Enforcement
Given policy profile routing thresholds for composite score (T_block < T_review < T_auto) and rules that any High risk tier requires Compliance review When a recommendation is submitted for apply Then if risk tier is High, the action is blocked from one‑click apply and routed to Compliance; override requires role RiskApprover and a mandatory justification of at least 15 characters And if composite score >= T_auto and risk tier is Low, the action is auto-approved; if new PII category access is present, it is routed to Manager approval instead of immediate apply And if T_review <= composite score < T_auto or risk tier is Medium, the action is routed to Manager review with a 24h SLA; on timeout it escalates to Compliance And all decisions are logged with timestamp, actor IDs, composite score, risk tier, thresholds used, policy profile ID, and correlation ID
Auditability and Reproducibility of Scores
Given any scored recommendation When an audit record is retrieved Then it contains a complete snapshot: input features and values, normalization version, weight profile ID and version, risk and productivity sub-scores, composite score, risk tier, rationale list, routing outcome, actor IDs, and timestamps And an offline recomputation using the same versions reproduces the composite score within 0.01 precision And audit records are immutable (append-only) and retained for at least 24 months with a verifiable checksum
Performance and Scalability Under Load
Given a batch request to score 1,000 proposed access changes on the standard service tier When processing is executed Then the 95th percentile per-item scoring latency is <= 50 ms and the batch completes within 2 seconds And the service sustains >= 200 items/second for 10 minutes with error rate < 0.1% And during the test, CPU utilization remains < 80% and memory < 70% of allocated limits
Handling Missing or Conflicting Inputs
Given a proposed access change with incomplete telemetry When scoring is attempted Then if any critical risk signal is missing (SoD evaluation, regulatory tags, or cross-region mapping), the risk tier is set to High with rationale reason code signal_missing; one‑click apply is disabled and the item routes to Compliance And if productivity inputs are missing, their contributions are treated as neutral (zero benefit), and rationale includes data_gap entries for each missing field And if stale entitlement age is unknown, a default of 365 days is used for scoring and marked as imputed in rationale And the response includes a machine-readable completeness score between 0 and 1 and a list of missing fields
One-Click Apply with Auto-Rollback
"As an IAM Administrator, I want to apply recommended changes in one click with automatic rollback so that I can safely enforce right-sized access without downtime."
Description

Enable transactional application of selected recommendations with pre-change snapshots and time-bound automatic rollback. Support batch operations, scheduled changes (e.g., after hours), and dry-run validation for conflicts. Propagate changes to ClaimFlow RBAC and, where configured, to external identity providers via SCIM/Okta/Azure AD connectors with drift detection and reconciliation. Provide success/failure reporting, idempotency keys, and circuit breakers to prevent partial application. Maintain full change history for traceability and recovery.

Acceptance Criteria
One-Click Apply Transaction with Pre-Change Snapshot and Auto-Rollback
Given a set of selected recommendations and an auto-rollback window T is set, When the user triggers One-Click Apply, Then the system records an immutable pre-change snapshot with a unique Snapshot ID, And applies all changes as a single transaction, And if any individual change fails or a circuit breaker triggers, Then the entire transaction is rolled back to the snapshot within 60 seconds, And the user receives a failure report referencing Apply ID and Snapshot ID, And if no "Confirm Keep" is received before T elapses, Then the system automatically reverts to the snapshot and issues a rollback report; No partial changes persist in any target system.
Batch Apply Across Multiple Users and Roles
Given N recommendations across M users/groups are selected in one request, When One-Click Apply executes, Then either all N changes succeed or the entire batch is rolled back, And the response includes counts per target system (attempted, succeeded, failed) and the list of affected principals, And the system supports at least 1,000 changes per batch completing within 10 minutes or returns a capacity error without applying any changes.
Scheduled Off-Hours Apply with Pre-Execution Dry-Run
Given a user schedules an apply job for a specified future time window and a change-freeze calendar is configured, When the scheduled time arrives, Then the system executes only if the window is allowed, Else it defers and notifies the requester with the reason, And a dry-run is executed 15 minutes before execution and again at start time; If new blocking conflicts are detected, Then the job is marked Blocked and no changes are applied; All results and notifications include the scheduled job ID.
Dry-Run Conflict Validation and Deterministic Plan Hash
Given a set of recommendations, When Dry-Run is executed, Then no changes are applied to internal RBAC or external IdPs, And a deterministic plan hash and conflict report are returned listing policy violations, missing resources, dependency cycles, and connector health, And running Dry-Run with identical inputs returns the same plan hash, And any Error-severity conflict prevents One-Click Apply until resolved.
External IdP Propagation with Drift Detection and Cross-System Consistency
Given SCIM/Okta/Azure AD connectors are configured and healthy, When changes are applied, Then internal RBAC and all configured external IdP updates complete successfully or the operation is rolled back across all systems to the snapshot state, And the system detects state drift before and after propagation; It attempts reconciliation up to three retries with exponential backoff, And unresolved drift results in abort and rollback with an alert; All target systems reflect a consistent pre-change or post-change state within 15 minutes.
Idempotent Apply with Circuit Breakers and Outcome Reporting
Given an idempotency key K is supplied with an apply request, When the same request with K is retried within 24 hours, Then no duplicate changes occur and the original Apply ID and outcome are returned, And if external connector failure rate exceeds 20% or median latency exceeds 30 seconds during execution, Then a circuit breaker opens, the operation aborts, and all changes are rolled back to the snapshot; A structured outcome report is produced including per-target status, timings, counts, and links to logs.
Full Change History and Snapshot-Based Recovery
Given any apply or rollback completes (success, failure, or abort), When querying change history for a date range or specific Apply ID, Then entries include actor, timestamp, scope, idempotency key, Snapshot ID, Apply ID, dry-run plan hash, before/after diffs, external propagation results, and rollback references, And authorized users can export history as JSON or CSV, And authorized users can restore system state from a specific Snapshot ID with audit logging of the recovery action.
Policy Guardrails & Time-Bound Exceptions
"As a Compliance Manager, I want guardrails and time-bound exceptions so that policy is enforced while allowing controlled deviations when necessary."
Description

Define organization-wide guardrails that enforce minimum baselines and prohibited entitlements (e.g., no production data access for contractors), geography/legal constraints, and separation-of-duties rules. Ensure recommendations respect guardrails and flag violations. Allow authorized users to grant exceptions with required justification, scope (user/team), and expiry, with automated reminders and re-certification prompts. Centralize guardrail and exception policies with versioning and auditability.

Acceptance Criteria
Enforce Organization-Wide Guardrails at Role Assignment
Given a user classified as Contractor and a role that grants Production Data Access, When an admin attempts to assign the role to the user, Then the assignment is blocked, Then the UI displays the guardrail name and ID causing the block, And a policy-violation event is recorded with actor, target, role, guardrail ID, and timestamp. Given a user whose location is outside the allowed geography for PII access, When a permission with PII Access is requested or assigned, Then the action is blocked, Then the UI displays the applicable geography/legal constraint, And a policy-violation event is recorded. Given an assignment import via API that would violate any organization-wide guardrail, When the import is processed, Then violating rows are rejected with error codes per guardrail and the non-violating rows are applied.
Time-Bound Exception Granting with Mandatory Justification and Expiry
Given a user with the Policy Exception Approver permission, When they create an exception, Then the form requires: justification (minimum 20 characters), scope (User or Team), subject selection, guardrail reference, start datetime, expiry datetime, and impact assessment; And the Save button remains disabled until all required fields are valid. Given an exception is submitted, When saved, Then it is assigned a unique ID, version 1.0, status Active (or Scheduled if start > now), and is visible in the centralized Exceptions list with filters by guardrail, scope, owner, and expiry. Given a user without Policy Exception Approver permission, When they attempt to create or edit an exception, Then access is denied and the attempt is audited.
Automated Exception Expiry, Reminders, and Rollback
Given an Active exception with an expiry date 7 days away, When the daily scheduler runs, Then reminder notifications are sent to the exception owner and resource owner including the exception ID, scope, and link to re-certify or cancel. Given an Active exception reaches its expiry, When the expiry time passes, Then all entitlements granted solely by the exception are automatically revoked within 5 minutes, And an audit event is written, And notifications are sent confirming rollback. Given an expiring exception, When the owner re-certifies and extends it before expiry, Then a new version is created (e.g., v1.1) with updated expiry and linked to the prior version; the old version is marked Superseded, preserving the audit trail.
Recommendations Respect Guardrails and Flag Violations
Given Scope Advisor generates access recommendations, When a suggested add/remove conflicts with a guardrail, Then the recommendation is labeled Violates Guardrail with the specific rule ID and reason, And one-click Apply is disabled unless an Active exception covering the conflict and scope exists for the effective period. Given a recommendation would drop a user's access below required minimum baseline for their role, When displayed, Then it is labeled Baseline Breach and blocked from Apply. Given an Active exception exists that permits a conflict, When viewing the recommendation, Then it displays Exception Applied with the exception ID, and Apply is enabled only within the exception's effective window.
Separation-of-Duties Conflict Detection and Prevention
Given a Separation-of-Duties rule prohibits holding both Approve Claim Payment and Issue Claim Payment, When a user would end up with both via assignment, import, or recommendation, Then the system blocks the change, displays the SoD rule details, and records the attempt. Given an authorized approver attempts to allow an SoD conflict, When they create an exception scoped to the user/team and SoD rule, Then the system allows the change only while the exception is Active; outside that window, the SoD-conflicting entitlements are revoked automatically. Given a team-level assignment could create SoD conflicts for some members, When the assignment is attempted, Then the system identifies impacted members and blocks the team assignment unless an exception covers the team scope.
Policy Versioning and Immutable Audit Trail
Given a guardrail policy is edited, When changes are saved, Then a new version number is created (e.g., v2.0), the prior version remains read-only, and a human-readable diff is available showing added/removed/changed rules. Given any policy or exception change, When saved, Then the audit log records who, what, when, why (mandatory change reason), previous values, new values, and the source (UI/API), and the log is append-only and tamper-evident. Given compliance needs to review policies, When they access the centralized policy repository, Then they can filter by policy type, status, version, date range, owner, and export versions and audit logs to CSV/JSON with hash signatures for integrity verification.
Approval Workflow & Audit Export
"As an Auditor, I want an approval trail and exportable reports so that we can demonstrate control over access changes during audits."
Description

Provide configurable, multi-stage approval flows for applying access changes, with routing based on risk tier, department, and value thresholds. Include inline rationale, attachments, and reviewer comments. Persist a tamper-evident audit log of recommendations, decisions, changes, and rollbacks with timestamps and actors. Offer export in CSV/PDF and an API for GRC systems, with retention settings aligned to compliance requirements.

Acceptance Criteria
Risk- and Value-Based Multi-Stage Approval Routing
- Given routing rules configured by risk tier, department, and value thresholds, when an access change request is submitted that matches a rule, then the generated approval path exactly matches the configured stages, order, and required approvers per stage. - Given no routing rule matches a request, when it is submitted, then the system applies the configured global default route and logs the fallback in the audit log. - Given an approver is unavailable with a defined delegate, when a stage reaches that approver, then the task auto-assigns to the delegate and the delegation is recorded. - Given a stage SLA of X hours is configured, when the stage is assigned, then the stage breaches only after X hours of no action and the breach is logged and escalated per configuration. - Given a request with High risk tier and value above threshold, when computed, then the path includes a Risk Officer stage as configured; when risk is Low and value below threshold, then the path excludes that stage. - Given a user without “Submit Access Change” permission, when they attempt submission, then the request is blocked with a 403/permission error and no approval route is created. - Given route computation starts, when rules are evaluated, then the route is determined in under 500 ms for 95th percentile of requests.
Inline Rationale, Attachments, and Reviewer Comments Capture
- Given a submitter initiates an approval request, when they click Submit, then a rationale text field is required (min 10 characters) and must be present to proceed. - Given attachments are enabled, when the submitter or reviewer uploads files, then only allowed types (PDF, PNG, JPG, DOCX) up to 25 MB each and max 10 files are accepted, malware-scanned, and stored encrypted at rest. - Given a reviewer chooses Reject, when they submit the decision, then a comment is mandatory; when they choose Approve, then a comment is optional. - Given inline rationale, attachments, and comments are provided, when the decision is saved, then all are persisted, immutable in the audit log, and visible to authorized users. - Given an attachment upload fails scanning, when the user attempts to attach it, then the upload is blocked and the decision cannot be submitted until non-malicious files are attached or attachments are removed. - Given a request contains PII in comments, when stored, then PII is not exposed in exports unless the requester has “View Sensitive Data” permission (redaction applied otherwise).
Tamper-Evident Audit Log with Complete Event Coverage
- Given lifecycle events (recommendation created, approval requested, stage approved/denied, request escalated, change applied, rollback initiated/completed), when they occur, then each is recorded as an immutable audit entry with event_type, object_id, actor_id, actor_role, timestamp (ISO 8601 UTC), request_id, prior_state, and new_state. - Given a new audit entry is written, when persisted, then it includes a cryptographic hash and a previous_hash linking to the prior entry (hash chain) for the same request stream. - Given the integrity verification endpoint is called for a date range, when executed, then it returns Valid if and only if all hash chains verify and no gaps exist; any anomaly returns Invalid with the first failing record id. - Given any user attempts to modify or delete an existing audit entry, when performed via UI or API, then the system blocks the operation and logs the unauthorized attempt. - Given system clocks differ, when timestamps are recorded, then all entries are normalized to UTC with millisecond precision and monotonic ordering per request_id. - Given a decision is changed (e.g., re-approve after revision), when the new decision is saved, then a new entry is appended and the prior entry remains unchanged, with both linked via correlation_id.
CSV and PDF Audit Export with Filters
- Given the user has “Export Audit” permission, when they request an export with filters (date range, department, risk tier, decision status, actor), then the exported dataset contains only matching records. - Given a CSV export is generated, when downloaded, then it is UTF-8 encoded with a header row, RFC 4180 compliant quoting, UTC timestamps, and includes columns: request_id, event_type, actor_id, actor_role, department, risk_tier, value_bucket, decision, rationale, reviewer_comment, attachment_count, stage_name, timestamp, hash, previous_hash. - Given a PDF export is generated, when downloaded, then it includes a summary page (filters applied, record count, generation timestamp), paginated entries with the same fields as CSV (truncated where necessary with full values available via API), and an embedded export identifier for traceability. - Given a large export request of up to 100,000 records, when executed, then CSV completes within 60 seconds and PDF within 120 seconds at 95th percentile, or the system provides an asynchronous download link within those times. - Given attachments exist, when exporting, then attachment file names and IDs are included as metadata in CSV/PDF (not the binaries) and counts match the audit entries. - Given an export is generated, when verified, then record counts and checksum (SHA-256) of the CSV or PDF match the counts shown in the UI and are logged in the audit log.
Audit Log API for GRC Integration
- Given a GRC client with valid OAuth2 client credentials, when it calls GET /api/v1/audit-logs with filters (from, to, decision, actor_id, department, risk_tier), then it receives HTTP 200 with a JSON array of entries matching the filters. - Given pagination is required, when the client passes a cursor token, then the API returns the next page with a new cursor until no more results; each page size respects the requested limit up to a maximum of 5,000. - Given rate limits are configured at 600 requests per minute per client, when exceeded, then the API returns HTTP 429 with a Retry-After header and no data loss. - Given each audit entry is returned, when inspected, then it contains hash and previous_hash fields enabling client-side integrity verification; verification across a page boundary succeeds when pages are fetched sequentially. - Given a client requests an entry by request_id, when called, then the API returns the full chain of events for that request in chronological order. - Given an invalid or expired token, when the API is called, then it returns HTTP 401; given insufficient scopes, it returns HTTP 403. - Given API versioning is enabled, when the client specifies Accept: application/vnd.claimflow.audit.v1+json, then the v1 schema is returned; missing or unsupported versions return HTTP 406.
Retention Policy Configuration and Enforcement
- Given an admin sets retention policies per record type (e.g., approvals, changes, rollbacks) and jurisdiction, when saved, then policies store duration, scope, and legal hold exceptions and are validated against configured minimum/maximum bounds. - Given retention is active, when the daily purge job runs, then records past their retention period and not on legal hold are irreversibly purged and a purge summary (counts by type, ids range, timestamp) is appended to the audit log. - Given legal hold is applied to a request_id or actor_id, when purge runs, then affected records are retained until the hold is removed, and the hold audit entry references the policy basis. - Given a user requests export for a period that includes purged records, when generated, then those records are absent and the export header indicates the retention policy that caused omissions. - Given a retention policy is changed, when updated, then the change is recorded in the audit log with old_value, new_value, actor_id, and effective_from timestamp; retroactive deletion does not occur unless explicitly confirmed by an admin with “Purge Now” permission. - Given a data subject access request requires extended retention, when a temporary extension is set, then the system defers purge for matching records until the extension expiry and logs the extension.
Rollback of Applied Access Changes with Full Auditability
- Given an access change was applied, when a user with “Rollback Access Change” permission clicks Rollback within 30 days, then the system restores the prior entitlements exactly and records a rollback_initiated and rollback_completed audit entry with diff details. - Given conflicting pending approvals exist for the same subject, when rollback is requested, then the system blocks rollback with a clear error and guidance, and no partial changes occur. - Given rollback is executed, when complete, then post-state entitlements equal the pre-change snapshot (byte-for-byte for policy JSON) and automated verification passes with zero discrepancies. - Given rollback fails on any target system, when detected, then the operation is marked Partially Failed, compensating actions are attempted per connector config, and the user is presented with a retry option; all outcomes are logged. - Given a rollback is performed, when viewed in exports and via API, then the rollback events, rationale, actor, timestamp, and linked original change request_id are present and integrity-verifiable. - Given a rollback is requested for changes older than the configured rollback window, when attempted, then the system requires a new approval request rather than immediate rollback.

Product Ideas

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

PhotoFact Flash

Capture a photo; AI extracts VINs, serials, damage types, and timestamps in 2 seconds, auto-filling fields. Highlights confidence and missing essentials.

Idea

VoiceNote Digest

Converts adjuster voice notes into structured facts, tasks, and timestamps instantly. Detects hazards and creates checklists.

Idea

DocChase Microforms

Sends claimants personalized micro-forms via SMS to collect missing documents and details. Auto-validates files and updates workflows without agent touch.

Idea

Fraud Ember Map

Visualizes anomaly scores across claims in heatmaps and timelines. Flags pattern clusters and auto-routes to SIU with explainable triggers.

Idea

SLA Breach Radar

Monitors every intake step with live countdowns and color-coded risk. Auto-reprioritizes queues and pings owners before breaches.

Idea

Redaction Guardrail

Auto-detects PII/PHI in uploads and messages; redacts and tags consent. Exports audit-ready reports per jurisdiction.

Idea

Least-Privilege Blueprints

Prebuilt permission templates by role and carrier size; enforce field-level access and time-bound shares. One-click audits of who saw what.

Idea

Press Coverage

Imagined press coverage for this groundbreaking product concept.

P

ClaimFlow Launches AI-Driven Claims Intake, Cutting FNOL Time by 60% for Small-to-Mid Insurers

Imagined Press Article

New York, NY — ClaimFlow today announced the general availability of its AI-driven claims intake platform designed for small-to-mid insurers and managing general agents (MGAs). Built for claims managers and independent adjusters, ClaimFlow digitizes first notice of loss (FNOL) and early investigation by extracting facts from photos, documents, and voice notes in seconds, auto-tagging loss details, and routing tasks into configurable workflows. Early adopters report up to a 60% reduction in intake time, faster approvals, and fewer follow-ups and rekeys. ClaimFlow streamlines end-to-end intake with a modern AI stack purpose-built for the realities of field work and multi-channel claimant communication. Angle Assist guides adjusters to capture clear images of VIN plates, serial stickers, and damage zones using augmented reality borders and a live quality meter for glare and blur. When confidence is low, Burst Boost fuses a short burst of frames to enhance clarity before re-running extraction, raising accuracy without extra steps. Severity Map applies computer vision to outline damaged areas, classify dent, crack, hail, or rust, and estimate severity and affected parts, auto-tagging triage tasks that standardize scoring and reduce rework. For voice and notes, Live Factline transcribes as the adjuster speaks and instantly lifts key facts like policy numbers, VINs, parties, locations, causes of loss, and timestamps. With Timecode Anchors, every extracted fact is pinned to the exact snippet in the audio, enabling rapid verification and audit transparency. Gap Coach prompts for missing essentials based on claim type and carrier rules, while Confidence Nudge highlights low-confidence items and suggests quick confirmations without breaking the two-second flow. Phrase Normalizer harmonizes jargon and abbreviations into standardized terms and codes so downstream systems receive clean, consistent data. “Intake is the heartbeat of the claims experience, but for too many teams it still relies on manual data entry and back-and-forth that slows honest customers,” said Maya Chen, CEO of ClaimFlow. “ClaimFlow was built to get the facts right the first time—at the photo, at the word, at the moment—and to route work intelligently so cycle times shrink and trust grows.” Operations leaders gain precise control with Smart Pathing micro-forms that ask only what’s missing and adapt to jurisdiction and claim type, alongside QuickQueue Offline for on-device extraction when connectivity is poor. Proof Seal binds each capture with a cryptographic timestamp, geofence validation, and a tamper-evident hash embedded in EXIF and the claim record, strengthening chain-of-custody for auditors and SIU. Tap Verify overlays tappable boxes on extracted elements for in-line edits, guided recapture, and transparent QA at the source. “In our pilot, ClaimFlow helped us standardize FNOL across auto and property without slowing adjusters,” said Jordan Alvarez, Claims Operations Lead at HarborPoint Insurance. “Angle Assist and Tap Verify cut retakes and keystrokes, while Live Factline and Gap Coach lifted our first-pass completeness. The combination pushed approvals forward days faster on straightforward claims.” The platform’s orchestration layer turns high-quality intake into momentum. Route Orchestrator adapts risk-tier routing by line of business, jurisdiction, and exposure, ensuring low-risk claims flow to fast-track while complex scenarios reach SIU or senior reviewers. Capacity Sync monitors real-time availability and queue saturation to auto-prioritize at-risk items, while Business Hours applies fair, compliant countdowns by local calendars and time zones. Critical Path visualizes dependencies, bottlenecks, and next best actions, and Escalation Ladder coordinates multi-step alerts via Slack, Teams, SMS, email, and voice to prevent silent misses. “Configuring ClaimFlow to our rules took hours, not weeks,” said Priya Nair, Integration and Workflow Administrator at HarborPoint Insurance. “Smart Pathing, Role Composer, and Access Simulator gave us confidence to roll out gradually, and Blueprint Diff kept our permission changes transparent. We saw immediate reductions in rework and audit back-and-forth.” ClaimFlow was designed with privacy and compliance at its core. Live Mask continuously redacts PII/PHI in screens and transcripts, with just-in-time reveals gated by role, consent, and purpose and fully audit-logged. Consent Ledger binds consent to specific data, purposes, and durations, while Purpose Lock enforces use limitation end-to-end. SafeShare De‑ID creates share-safe datasets for vendors and counsel, and RuleSync keeps redaction and retention rules current by jurisdiction with versioning and impact previews. SendGuard intercepts outbound messages to prevent leaks, and JIT Pass provides time-boxed access grants with reason codes and automatic expiry. ClaimFlow is available today to carriers and MGAs in North America and select international markets. Standard onboarding includes role blueprints tailored to Claims Operations Leads, Independent Field Adjusters, FNOL Intake Specialists, SIU Screeners, Compliance & QA Auditors, and Integration & Workflow Administrators. Prebuilt integrations connect to common core, document, and collaboration systems, with open APIs for custom workflows. For product demos, pricing, and technical documentation, contact ClaimFlow’s media and analyst team below. Media Contact: ClaimFlow Communications press@claimflow.ai +1 415 555 0137 www.claimflow.ai/press About ClaimFlow: ClaimFlow digitizes claims intake for claims managers and independent adjusters at small-to-mid insurers and MGAs, extracting facts from photos and messages with an NLP engine, tagging loss details, and routing tasks into configurable automated workflows to cut intake time 60%, eliminate manual entry, accelerate approvals, and reduce follow-ups.

P

ClaimFlow Debuts DocChase Microforms to Eliminate Follow-Ups and Accelerate Approvals Across Channels

Imagined Press Article

Chicago, IL — ClaimFlow today introduced DocChase Microforms, a suite of claimant-friendly, mobile-first experiences that gather missing documents and details without agent intervention. The new capability combines Smart Pathing adaptive forms, Live Proofcheck validation, Quick Prefill from policy data, AutoLocale language detection, TapSign e‑sign, Nudge Cadence reminders, and Seamless Handoff across devices—turning slow, back-and-forth requests into a one-session completion flow. DocChase Microforms meet claimants where they are—on SMS, email, or WhatsApp—then guide them through exactly what’s needed based on claim type, jurisdiction, and what’s already on file. Smart Pathing asks only the questions that remain, skipping items already validated by intake or core systems. Quick Prefill securely ties the link to the claim and auto-populates names, policy numbers, contact blocks, vehicle or property details, and relevant dates so claimants simply verify or edit. Live Proofcheck confirms document type, page count, glare/blur, and date/name matches via OCR, offering plain-language fix tips or auto-recapture prompts in real time to prevent rework. “Claims teams succeed when claimants can finish in one try,” said Evan Ruiz, VP of Product at ClaimFlow. “DocChase Microforms turn a historically fragmented process into a clear, inclusive, and secure interaction that respects people’s time. By validating as you go, we eliminate the ping-pong and accelerate approvals without adding to agent workload.” Nudge Cadence adapts reminders to claimant response patterns, respecting quiet hours and offering snooze or “I’ll do it later” options that keep momentum without pressure. AutoLocale detects the preferred language and reading level from context, localizing guidance, units, and date formats and automatically inserting jurisdiction-specific disclosures. For longer tasks or heavier uploads, Seamless Handoff lets claimants start from an SMS link on mobile and continue on desktop with a QR or magic link—no restart required—with progress saved across devices. “First-pass completeness has been our white whale,” said Samira Patel, FNOL Intake Specialist at Lakeside Mutual. “With DocChase Microforms, we’re seeing claimants finish the same day, often within minutes. Live Proofcheck stops bad scans before they hit our queue, and Quick Prefill means we’re verifying, not typing. Our follow-up volume dropped noticeably in week one.” DocChase integrates natively with ClaimFlow’s intake and workflow engine so downstream steps update automatically as items are completed. Timecode Anchors and Proof Seal extend to claimant uploads, pinning facts to their source moments and binding each artifact with a cryptographic timestamp, geofence validation, and tamper-evident hash. Confidence Nudge flags low-confidence extractions for quick confirmation, while Tap Verify keeps any human corrections transparent and audit-ready. For compliance and privacy, Live Mask redacts sensitive tokens by default in screens and transcripts, and Consent Ledger binds e‑sign and attestations captured via TapSign to specific data, purposes, and durations. Purpose Lock enforces the declared use of data across access and exports, and Timed Sharelinks allow purpose-limited, field-filtered, auto-expiring shares with watermarks and de-identification templates via SafeShare De‑ID. RuleSync maintains up-to-date redaction and retention rules by jurisdiction. “From a QA perspective, DocChase gives us clean, consistent artifacts the first time,” said Noah Briggs, Compliance & QA Auditor at Lakeside Mutual. “We spend less time chasing missing pages or illegible proofs and more time resolving exceptions. The chain-of-custody from Proof Seal plus TapSign’s bound attestations has simplified our audit prep.” Operationally, DocChase Microforms reduce queue friction with Capacity Sync and Business Hours managing fair countdowns and staffing-aware prioritization. Escalation Ladder orchestrates reason-coded nudges and multi-channel alerts when risk of delay is high, and SLA Switchover can shift work to approved fast-track paths or simplified checklists when breach risk spikes—all within compliance. Root Cause and SLA Simulator quantify delays, forecast breach rates under staffing or surge scenarios, and recommend fixes that keep service levels on track. DocChase Microforms are available today as an add-on to ClaimFlow’s core intake platform for carriers and MGAs in North America and select international markets. Standard templates support auto, property, and specialty lines, with the ability to extend fields, disclosures, and routing rules by jurisdiction. Open APIs enable bi-directional updates with core, document management, and collaboration systems. For demos, implementation guidance, and pricing, contact ClaimFlow’s media and analyst team below. Media Contact: ClaimFlow Communications press@claimflow.ai +1 415 555 0137 www.claimflow.ai/press About ClaimFlow: ClaimFlow digitizes claims intake for claims managers and independent adjusters at small-to-mid insurers and MGAs, extracting facts from photos and messages with an NLP engine, tagging loss details, and routing tasks into configurable automated workflows to cut intake time 60%, eliminate manual entry, accelerate approvals, and reduce follow-ups.

P

ClaimFlow Rolls Out Fraud Intelligence and Access Governance Suite for Safer, Faster SIU Decisions

Imagined Press Article

Columbus, OH — ClaimFlow today announced the availability of an integrated Fraud Intelligence and Access Governance suite that helps Special Investigations Units (SIU) spot emerging schemes sooner, explain anomaly scores clearly, and collaborate securely under least-privilege controls. The release combines Cluster Explorer, Signal Lens, Ring Radar, Route Orchestrator, Evidence Bundle, Outcome Trainer, and HeatPulse Alerts with privacy-by-design capabilities including Live Mask, Consent Ledger, SafeShare De‑ID, Purpose Lock, RuleSync, SendGuard, Role Composer, JIT Pass, Access Simulator, Creep Guard, Blueprint Diff, Timed Sharelinks, and Scope Advisor. As fraudulent rings become more organized and bursty, SIU teams need timely signals they can trust and defensible governance to share only what’s necessary. Cluster Explorer reveals related-claim clusters by shared entities and behaviors—such as phones, VINs, addresses, IPs, or repairers—using interactive heatmaps and timeline drilldowns. Signal Lens provides human-readable explanations of why a claim scored as anomalous, surfacing top contributing signals with weights, examples, and data lineage. When risk crosses thresholds, Route Orchestrator adapts routing by line of business and exposure to ensure the right experts review the right work at the right time. “Speed without clarity is noise, and clarity without security is risk,” said Derrick Wong, Chief Risk and Compliance Officer at ClaimFlow. “We built this suite so SIU teams can move fast with evidence they can defend. You can see the pattern, understand the score, and share a precise, purpose-limited packet with counsel or vendors—all without leaving compliant guardrails.” Ring Radar continuously monitors the claims graph and auto-expands suspected networks as new claims arrive, suggesting watchlists and optional payout holds when ring risk is elevated. HeatPulse Alerts detect anomaly surges by region, vendor, or channel and notify Ops and SIU via Slack, Teams, or email with deep links into the affected clusters. With Evidence Bundle, investigators export a one-click, audit-ready packet that assembles anomaly rationale, cross-claim links, Proof Seal hashes, geofence checks, Timecode Anchors, and source images and documents to save hours of manual compilation and strengthen case quality. Outcome Trainer closes the loop by ingesting SIU outcomes—confirmed fraud, cleared claims, and recoveries—plus analyst feedback to auto-tune rules, refresh thresholds, and flag model drift. Over time, the system recommends new triggers based on recent patterns, steadily reducing false positives and catching novel fraud faster. “Explainability has been the missing link,” said Alana Brooks, SIU Screening Lead at Summit County Insurance. “Signal Lens shows us exactly which signals drove the score and how they relate across the cluster. When we package a case, Evidence Bundle captures the data lineage we need to brief counsel and regulators, while Live Mask and Consent Ledger keep access tight. Our investigators spend more time investigating and less time gathering and redacting.” The Access Governance layer that ships with the suite operationalizes least privilege without slowing teams. Live Mask auto-hides PII/PHI by default, with just-in-time reveals gated by role, consent, and purpose. Consent Ledger binds consent to specific data, purposes, and durations, propagating limits across workflows and alerting on expirations. Purpose Lock enforces declared use end-to-end, while SafeShare De‑ID creates share-safe datasets and documents using tokenization, date shifting, and smart generalization with watermarks and Proof Seal hashes. Administrators can shape precise roles in minutes with Role Composer’s visual builder, toggling field-level read, edit, and mask permissions and layering conditions by line of business, jurisdiction, and claim state. Access Simulator offers an instant “see-as” preview for any user on a specific claim so teams can verify visibility and masks before rollout. JIT Pass adds time-boxed access grants with reason codes and automatic expiry. Creep Guard monitors for permission creep and recommends removals, while Blueprint Diff shows side-by-side permission versioning and impact analysis. Timed Sharelinks enforce purpose-limited, field-filtered, auto-expiring external collaboration, and Scope Advisor suggests right-sizing roles based on real task usage. “Governance should be a speed enabler, not a speed bump,” added Wong. “With policy-aware controls embedded in the flow of work, investigators minimize exposure while staying fast and defensible.” The Fraud Intelligence and Access Governance suite is available today to ClaimFlow customers. Implementation includes outcome mapping, signal calibration workshops, least-privilege role blueprints, and integration with common collaboration and case systems. Open APIs and export formats (PDF and JSON) support bi-directional sharing with counsel, law enforcement, and recovery partners. For demos, pricing, and technical details, contact ClaimFlow’s media and analyst team below. Media Contact: ClaimFlow Communications press@claimflow.ai +1 415 555 0137 www.claimflow.ai/press About ClaimFlow: ClaimFlow digitizes claims intake for claims managers and independent adjusters at small-to-mid insurers and MGAs, extracting facts from photos and messages with an NLP engine, tagging loss details, and routing tasks into configurable automated workflows to cut intake time 60%, eliminate manual entry, accelerate approvals, and reduce follow-ups.

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.