Follow-ups: dart-run replay CLI via pure-Dart i18n split + page-level a11y audit#91
Merged
Merged
Conversation
… a11y audit Closes the two concrete follow-ups documented in PR #89. 1. Local-AI replay CLI (unblocked after three PRs) - Split the Flutter-facing i18n members out of app_i18n.dart into a new lib/core/i18n/app_i18n_context.dart (BuildContext extension, AppState provider lookup, Locale mapping as appI18nLocaleFor). app_i18n.dart is now pure Dart, so the whole recommendation stack compiles under `dart run`. The 13 UI files + app.dart import the context file (which re-exports app_i18n.dart); pure-Dart consumers are untouched. No behaviour change. - New tool/run_recommendation_scenario_replay.dart (+ .mjs wrapper, `npm run recommend:replay`): replays the five archetypes with the same offline scripted Local AI stand-in as the test harness and writes build/recommendation_scenario_replay/latest.{json,md}. Verified the CLI and `flutter test test/local_ai_replay_report_test.dart` produce byte-identical artifacts. Exits non-zero iff the Local-AI candidate-set invariant is violated. - Docs: LOCAL_AI_REPLAY_REPORT.md "Why there is no dart run CLI" replaced with the CLI notes; PUBLIC_VERIFICATION.md reviewer order + snapshot section now reference `npm run recommend:replay`. 2. Page-level accessibility audit - test/accessibility_semantics_test.dart gains a real CatalogPage widget test: a stub CachingAssetBundle serves a valid 1x1 PNG (and a StandardMessageCodec AssetManifest.bin) so brand images render under flutter_test, with a local-mode AppState in a guarded zone and a phone viewport. Asserts the accessible "view details" labels are exposed by the real page semantics tree. Educational prototype only; synthetic/demo data only; deterministic; no medical advice; not calibrated for real care; no PHI. Gates: dart format clean, flutter analyze clean, flutter test 745 passed, public:preflight 0 BLOCKER, privacy:preflight 0 blocker, `npm run recommend:replay` runs end-to-end, git diff --check clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the two concrete follow-ups documented in #89.
1.
dart runLocal-AI replay CLI — finally unblockedThe CLI had been documented as future work in three consecutive PRs because the
recommendation orchestrator transitively imported Flutter via
app_i18n.dart.The actual Flutter surface there turned out to be just three members, so this
PR splits them out instead of refactoring i18n broadly:
lib/core/i18n/app_i18n_context.dart(new) — theBuildContext.appI18nextension (AppState provider lookup) and
appI18nLocaleFor(tag →Locale),re-exporting
app_i18n.dart. The 13 UI files +app.dartnow import this;app_i18n.dartitself is pure Dart. No behaviour change (same logic,same
listen: falsesemantics).tool/run_recommendation_scenario_replay.dart+.mjswrapper +npm run recommend:replay— replays the five archetypes with the sameoffline scripted Local AI stand-in as the test harness, writes
build/recommendation_scenario_replay/latest.{json,md}, and exits non-zeroiff the candidate-set invariant is violated.
flutter test test/local_ai_replay_report_test.dart(md5-compared), so thetwo entry points cannot drift from each other.
dart runCLI" section is replaced withCLI notes; the reviewer order in
PUBLIC_VERIFICATION.mdnow starts withnpm run recommend:replay.2. Page-level accessibility audit (was blocked on asset loading)
test/accessibility_semantics_test.dartgains a realCatalogPagewidgettest: a stub
CachingAssetBundleserves a valid 1×1 PNG plus aStandardMessageCodec-encodedAssetManifest.bin, so the brand images renderunder
flutter_test; a local-modeAppStateis constructed in a guarded zone(sqlite init is unavailable on the test VM and irrelevant); a phone-sized test
viewport avoids layout overflow. The test asserts the accessible "view details"
labels are exposed by the real page's semantics tree — upgrading the previous
construct-level checks to a page-level audit.
Validation (all run, all green)
dart format --set-exit-if-changed .clean;flutter analyzeno issuesflutter test --concurrency=1→ 745 passednpm run recommend:replay→ 5 scenarios, invariant held, exit 0npm run public:preflight0 BLOCKER;npm run privacy:preflight0 blockergit diff --checkcleanRemaining follow-ups (intentionally untouched)
LocalizedAlias) — only if per-locale aliasfiltering becomes a requirement; flat lists still suffice.
_hasCjkwouldshift existing confidence assignments; deliberately left alone.
Educational prototype only; synthetic/demo data only; no medical advice; not
calibrated for real care.
🤖 Generated with Claude Code