critical priority medium complexity backend pending backend specialist Tier 1

Acceptance Criteria

CognitiveLoadRuleEngine is a singleton Dart class instantiable via CognitiveLoadRuleEngine.instance
validateScreen(ScreenConfig config) returns List<CognitiveViolation> — empty list means compliant
Rule: wizard step count > 5 produces a CognitiveViolation with severity 'error' and message in plain English ≤80 words
Rule: primary choice count > 3 on a single screen produces a CognitiveViolation with severity 'error'
Rule: more than one primary CTA widget registered on a screen produces a CognitiveViolation with severity 'error'
Rule: nested modal detected (modal opened from within a modal) produces a CognitiveViolation with severity 'error'
In debug mode (kDebugMode == true), any violation triggers a Flutter assertion that halts navigation and prints violation details to console
In release mode, violations are silently logged (no crash, no navigation block)
CognitiveViolation model exposes: ruleId (String), severity (enum: error/warning/info), message (String), screenId (String?)
Engine exposes registerScreen(String screenId, ScreenConfig config) for declarative registration
All rule thresholds are defined as named constants (kMaxWizardSteps = 5, kMaxPrimaryChoices = 3, kMaxPrimaryCtas = 1)
Unit tests pass for all 4 rules with both compliant and non-compliant inputs
No dependency on Flutter widgets — pure Dart service usable in tests without a widget tree

Technical Requirements

frameworks
Flutter
Dart
data models
ScreenConfig
CognitiveViolation
CtaConfig
WizardConfig
performance requirements
validateScreen() must complete in < 1ms for typical screen configs (no I/O, no async)
Engine must not allocate memory during validation beyond the returned violation list
security requirements
No user data passed through rule engine — only structural screen metadata
Debug-mode assertions must not leak screen config details to production logs

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Implement as a pure Dart singleton with no Flutter widget dependencies to maximise testability. Use kDebugMode from 'package:flutter/foundation.dart' to gate assertion behaviour. Define ScreenConfig as a simple immutable Dart class (not a widget) with fields: stepCount, primaryChoiceCount, primaryCtaCount, hasNestedModal, screenId. Violations should be collected — not thrown — so a single validateScreen() call returns all issues at once (fail-all, not fail-fast).

Keep rule logic in private methods (_validateStepCount, etc.) for easy extension. Avoid any async code — the engine is a synchronous validation service. Consider making constants overridable via a CognitiveLoadRuleConfig object passed at engine initialisation, to allow org-specific threshold customisation in future without breaking the API.

Testing Requirements

Unit tests using flutter_test (dart:test). Test each of the 4 rules independently with boundary values (e.g., exactly 5 steps = pass, 6 steps = fail). Test validateScreen() with a fully compliant ScreenConfig returns empty list. Test that kDebugMode assertion fires — use FlutterError.onError override in test harness to capture assertion failures.

Test release-mode path by mocking kDebugMode constant. Test CognitiveViolation model serialization. Minimum 90% line coverage on rule engine class. No integration or e2e tests required for this pure service.

Component
Cognitive Load Rule Engine
service medium
Epic Risks (4)
high impact medium prob technical

The error message registry and help content registry both depend on bundled JSON assets loaded at startup. If asset loading fails silently (e.g. malformed JSON, missing pubspec asset declaration), the entire plain-language layer falls back to empty strings or raw error codes, breaking the accessibility guarantee app-wide.

Mitigation & Contingency

Mitigation: Implement eager validation of both assets during app initialisation with an assertion failure in debug mode and a structured error log in release mode. Add integration tests that verify asset loading in the Flutter test harness on every CI run.

Contingency: Ship a hardcoded minimum-viable fallback message set directly in Dart code so the app always has at least a safe generic message, preventing a blank or code-only error surface.

medium impact medium prob dependency

The AccessibilityDesignTokenEnforcer relies on dart_code_metrics custom lint rules. If the lint toolchain is not already configured in the project's CI pipeline, integrating a new linting plugin may cause unexpected build failures or require significant CI configuration work beyond the estimated scope.

Mitigation & Contingency

Mitigation: Audit the existing dart_code_metrics configuration in the project before starting implementation. Scope the lint rules to a separate Dart package that can be integrated incrementally, starting with the most critical rule (hard-coded colors) and adding others in subsequent iterations.

Contingency: Fall back to Flutter test-level assertions (using the cognitive-accessibility-audit utility) to catch violations in CI if the lint plugin integration is delayed, preserving enforcement coverage without blocking the epic.

medium impact low prob technical

WizardDraftRepository must choose between shared_preferences and Hive for local persistence. Choosing the wrong store for the data volume (e.g. shared_preferences for complex nested wizard state) can lead to serialisation bugs or performance degradation, particularly on lower-end Android devices used by some NHF members.

Mitigation & Contingency

Mitigation: Define a clean repository interface first and implement shared_preferences as the initial backend. Profile serialisation round-trip time with a realistic wizard state payload (≈10 fields) before committing to either store.

Contingency: Swap the persistence backend behind the repository interface without touching wizard UI code, which is possible precisely because the repository abstraction isolates the storage detail.

medium impact high prob scope

The AccessibilityDesignTokenEnforcer scope could expand significantly if a large portion of existing widgets use hard-coded values. Discovering widespread violations during this epic would force either a major refactor or a decision to exclude legacy components, potentially reducing the enforcer's coverage and value.

Mitigation & Contingency

Mitigation: Run a preliminary audit of existing widgets using a simple grep for hard-coded hex colors and raw pixel values before implementation begins. Use the results to set a realistic remediation boundary for this epic and log all out-of-scope violations as tracked tech-debt items.

Contingency: Scope the enforcer to new and modified components only (via file-path filters in dart_code_metrics config), shipping a partial but immediately valuable coverage rather than blocking the epic on full-codebase remediation.