critical priority medium complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

The declaration text renders in a scrollable region with a visible scroll indicator when content exceeds the viewport
The confirmation checkbox is disabled and visually distinct (grayed out) until the user has scrolled to the bottom of the declaration text
Scroll-to-bottom detection triggers when ScrollController.position.pixels >= ScrollController.position.maxScrollExtent - 8.0 (8dp tolerance for sub-pixel rendering)
Once scroll-to-bottom is detected, the checkbox becomes enabled and a Semantics announcement is made: 'You have read the full declaration. You may now confirm.'
The checkbox has an accessible Semantics label: 'I have read and understood the confidentiality declaration'
The submit button is disabled when the checkbox is unchecked and enabled when checked
The submit button is labeled 'Confirm' with a Semantics hint: 'Submits your acknowledgement of the confidentiality declaration'
All interactive elements (checkbox hit area, submit button) meet minimum 44x44dp touch target size
Text color contrast ratio meets WCAG 2.2 AA minimum 4.5:1 for normal text and 3:1 for large text against the background
The screen passes Flutter accessibility checks (SemanticsFlag validation) via flutter_test semantics tester
An ISO 8601 timestamp is recorded locally in widget state at the moment the checkbox is checked (for submission in task-007)
The screen supports dynamic font scaling up to 200% without layout overflow or text clipping
Screen is wrapped inside DriverFeatureFlagGuard

Technical Requirements

frameworks
Flutter
data models
confidentiality_declaration
declaration_acknowledgement
performance requirements
Scroll detection must not degrade scroll performance — use ScrollController listener, not polling
Screen must render within 3 frames on first mount regardless of declaration text length
security requirements
Declaration text must be displayed as read-only — no copy/paste or share affordances on the text content
The timestamp recorded must use UTC (DateTime.now().toUtc().toIso8601String()) — not device local time
Screen must not be accessible to unauthenticated users — route guard must verify active Supabase session before rendering
ui components
ScrollController with listener
SingleChildScrollView (declaration text area)
Checkbox with Semantics wrapper
AppButton (submit, primary)
Semantics (live region announcements)
DriverFeatureFlagGuard
ScrollProgressIndicator (optional visual aid)

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Use a ScrollController attached to the SingleChildScrollView. In initState, add a listener: _scrollController.addListener(_onScroll). The _onScroll method checks if position.pixels >= position.maxScrollExtent - 8.0 and sets a _hasScrolledToBottom boolean in setState. This boolean gates the checkbox's enabled state.

For the checkbox, use a Row with a SizedBox(width: 44, height: 44, child: Checkbox(...)) to ensure touch target compliance — Flutter's default Checkbox may be smaller than 44dp depending on theme. Wrap the checkbox Row in a Semantics widget with label set to the required string. For the live region announcement when scroll completes, use SemanticsService.announce('You have read the full declaration. You may now confirm.', TextDirection.ltr).

Record the timestamp as a final DateTime in local widget state — do NOT persist it yet; that is task-007's responsibility. Ensure the declaration text uses Theme.of(context).textTheme styles bound to design tokens, not hardcoded font sizes, so dynamic font scaling works correctly.

Testing Requirements

Widget tests using flutter_test. Test cases: (1) checkbox is disabled on initial render, (2) scrolling to bottom enables checkbox, (3) checking checkbox enables submit button, (4) unchecking checkbox disables submit button, (5) semantics label on checkbox matches required string, (6) submit button touch target >= 44x44dp (verify via SemanticsNode rect), (7) screen renders without overflow at 200% font scale using MediaQuery override, (8) timestamp is set to a UTC ISO 8601 string when checkbox is checked. Accessibility audit using tester.getSemantics() to verify no missing labels. Color contrast must be verified manually against design tokens — document contrast ratios in PR description.

Epic Risks (3)
high impact medium prob technical

The declaration acknowledgement screen has the most complex accessibility requirements of any screen in this feature: scrollable long-form legal text, a conditional checkbox that is only enabled after reading, and a timestamp capture. Incorrect focus management or missing semantics annotations could fail VoiceOver navigation or cause the screen reader to announce the checkbox as available before the driver has scrolled, undermining the legal validity of the acknowledgement.

Mitigation & Contingency

Mitigation: Build the acknowledgement screen against the WCAG 2.2 AA checklist from the start, not as a post-hoc audit. Use semantics-wrapper-widget and live-region-announcer from the platform's accessibility toolkit. Include a VoiceOver test session in the acceptance criteria with a tester using the screen reader.

Contingency: If WCAG compliance cannot be fully achieved within the sprint, ship the screen with a documented list of accessibility gaps and a follow-up sprint commitment. Do not block the declaration workflow launch if the core interaction works but a non-critical semantics annotation is missing.

medium impact medium prob integration

Drivers receive a push notification with a deep link to the declaration acknowledgement screen for a specific assignment. If the deep link handler does not correctly route to the right screen and assignment context — particularly when the app is launched cold from the notification — the driver may see a blank screen or the wrong declaration.

Mitigation & Contingency

Mitigation: Implement and test all three notification scenarios: app foregrounded, app backgrounded, and cold start. Use the platform's existing deep-link-handler infrastructure. Add integration tests that simulate notification tap events and assert correct screen and data loading.

Contingency: If cold-start deep link routing proves unreliable, implement a notification-centre fallback where the driver can find the pending declaration from the notification centre screen, ensuring the workflow can always complete even if the direct deep link fails.

medium impact low prob technical

If the driver-feature-flag-guard has any rendering edge case — such as a brief flash of driver UI before the flag value is loaded, or a guard that fails open on a flag service error — driver-specific UI elements could be momentarily visible to coordinators in organizations that have not opted in, causing confusion and potentially a support escalation.

Mitigation & Contingency

Mitigation: Default the guard to rendering nothing (not a loading indicator) until the flag value is definitively resolved. Treat flag service errors as flag-disabled to fail closed. Write widget tests covering the loading, disabled, and enabled states including the error case.

Contingency: If fail-closed cannot be guaranteed within the sprint, add a server-side RLS check on the driver assignment endpoints so that even if the UI guard leaks, the data layer refuses to return driver data for organizations without the flag enabled.