critical priority low complexity backend pending backend specialist Tier 3

Acceptance Criteria

A Dart script `bin/validate_manifest_contrast.dart` reads the Accessibility Token Manifest JSON file path from a CLI argument or a hardcoded default path
The script iterates over every `color_pair` entry in the manifest
Each pair is validated using `ContrastRatioValidator.validatePair()` with the correct `textSize` from the manifest entry
The script prints a table-format report: pair name | foreground | background | ratio | level | PASS/FAIL
If all pairs pass AA, the script exits with code 0
If any pair fails AA, the script prints a FAILED PAIRS summary section and exits with code 1
The script is added as a step named `validate-contrast` in the CI configuration (e.g., GitHub Actions workflow YAML)
The script handles malformed manifest JSON gracefully with a descriptive error message and exit code 2
Running the script on the current manifest with all correctly defined token pairs produces a fully green report

Technical Requirements

frameworks
Dart
dart:io
dart:convert
data models
Accessibility Token Manifest schema
ValidationResult
performance requirements
Script completes validation of up to 100 color pairs in under 1 second
security requirements
Manifest file path must be resolved relative to project root — do not allow absolute paths from untrusted input in CI contexts

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Read the manifest file with `File(manifestPath).readAsStringSync()` and parse with `jsonDecode`. Iterate over the pairs list. Use `ContrastRatioValidator` (from task-009) for each pair. Collect results and print the report using `stdout.writeln` with ANSI color codes for terminal readability (green for PASS, red for FAIL) — but check `stdout.hasTerminal` before applying ANSI codes so CI log output remains plain text.

Use `exit(1)` from `dart:io` for failure. Do not use `process.exit()` or `Platform.exit()`. Add this script invocation to `.github/workflows/` (or equivalent CI config) as a job step: `- run: dart bin/validate_manifest_contrast.dart`. This step should run on every PR touching the manifest or the design token files.

Testing Requirements

Write integration tests using `dart:io` Process to invoke the script as a subprocess. Test scenarios: (1) provide a manifest JSON with all passing pairs — assert exit code 0 and stdout contains 'PASS' for each entry, (2) provide a manifest with one failing pair — assert exit code 1 and stdout identifies the failing pair by name, (3) provide malformed JSON — assert exit code 2 and stderr contains an error message. Keep test manifest fixtures in `test/fixtures/` as small JSON files with 2-3 pairs each.

Component
Contrast Ratio Validator Service
service medium
Epic Risks (3)
high impact medium prob technical

The WCAG 2.2 relative luminance formula requires gamma-corrected sRGB calculations. Floating-point rounding differences between Dart and reference implementations could produce off-by-one classifications for near-threshold color pairs, resulting in pairs that just pass or just fail in CI but behave differently at runtime.

Mitigation & Contingency

Mitigation: Implement the algorithm directly from the WCAG 2.2 specification using the exact linearisation constants. Validate the Dart implementation against the W3C reference test vectors and against a known-good JavaScript implementation for at least 50 color pairs spanning the compliance boundaries.

Contingency: If discrepancies are found, add a configurable tolerance margin (e.g., ±0.005 on the ratio) and flag near-threshold pairs as warnings rather than hard failures, escalating to the design team for manual review.

medium impact high prob scope

The token manifest is a static data file. If developers add new color tokens to the design-token-provider without updating the manifest, the manifest becomes stale and the CI validator produces false negatives — passing builds that contain unvalidated color pairs.

Mitigation & Contingency

Mitigation: Add a CI step that cross-references every token constant exported by the design-token-provider against the manifest at build time, failing if any token is present in the provider but absent from the manifest. Document this requirement clearly in the contributing guide.

Contingency: If drift is detected post-merge, run a full manifest regeneration script and treat the resulting manifest diff as a blocking pull request with mandatory accessibility review.

medium impact medium prob dependency

The flutter_accessibility_lints package (or custom lint rules) may produce false positives on patterns the team deliberately uses — for example, decorative icon widgets that intentionally omit semantic labels. Excessive false positives will lead developers to add blanket ignore comments, undermining the entire lint strategy.

Mitigation & Contingency

Mitigation: Audit the full lint rule set against the existing codebase before enabling rules. Create a documented list of approved ignore-comment patterns with mandatory justification comments. Restrict ignore patterns to decorative-only contexts.

Contingency: If false positive rates exceed 10% of lint output, disable the highest-noise individual rules and replace them with targeted custom lint rules scoped to the specific patterns the team controls.