DAY-109: Land manual QA remediation and native flow hardening#316
Conversation
Replace the broken vector export that embedded a clipped JPEG logo and repeated placeholder copy. Render the first intro illustration natively with the transparent Dayova mark and the descriptive Figma task examples.
Keep RN styles limited to responsive and artboard geometry, document the SVG-versus-native rendering decision, and remove the superseded broken SVG export.
Replace the temporary HugeIcons flame with the exact 14px SVG supplied for the onboarding streak artwork.
# Conflicts: # src/components/onboarding/onboarding-flow.ts
# Conflicts: # src/app/notifications.tsx # src/components/ui/icon.tsx # src/features/auth/dayova-auth-flow.tsx
Document the app icon provenance and exception policy.\n\nRefs DAY-171
|
Final local/Android/CI checkpoint for DAY-109
Still required before this draft is marked ready: the Mac iOS Debug/Release result, authenticated persistence/revocation evidence, TalkBack/VoiceOver acceptance, and fresh human approval. Unsafe OTA/native runtime continuity remains the separate DAY-248 release blocker; merging this PR is not release authorization. |
…qa-pass # Conflicts: # patches/matt-pocock-skills/dayova.patch
PARTIAL — Dayova PR #316 final verificationAll code, dependency, compilation, runtime, Android-isolation, regression, complete-timeline, and CI gates pass at Source state
Build and runtime result
Complete-timeline findings
Authenticated iOS matrix
VoiceOver matrix
Apple's testing guidance explicitly says to install on a physical device because VoiceOver is unavailable on Simulator. This Mac sees LogsNo Swift/Objective-C exceptions, missing modules/symbols, JavaScript exceptions, React Native appearance errors, appearance-event loops, unexpected root remounts, Fabric/native-view failures, or crashes attributable to the module were found. The first Debug launch attempted host-only ConclusionThe Swift implementation was verified on iOS, and Android was verified to remain isolated from it while preserving equivalent appearance behavior. The code and CI are green. Keep the PR draft until the physical-device VoiceOver matrix is completed. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 49c027e8d0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const verifyPasswordResetCode = async (code: string) => | ||
| withSubmitting(async () => { | ||
| try { | ||
| await verifyPasswordResetAttempt(getPasswordResetSignIn(), code); |
There was a problem hiding this comment.
Short-circuit reset-code checks without an attempt
When beginPasswordReset() returns delivery_not_confirmed for an unknown email, startPasswordReset() records passwordResetHasRemoteAttemptRef.current = false but the UI still advances to the code-entry step; entering any 6-digit code then reaches this verifier and calls Clerk even though no reset attempt exists. In that scenario Clerk can return an internal/no-attempt error instead of the generic German reset-code response, breaking the privacy-preserving “Falls ein Konto existiert …” flow. Gate this path the same way resend already does when no remote attempt was created.
Useful? React with 👍 / 👎.
Outcome
Lands the current DAY-109 remediation as one atomic change before the remaining open product PRs are rebuilt on the resulting
main. DAY-109 is not complete until its outstanding manual-device and final-evidence acceptance criteria are recorded.Important
Merge-order freeze: this PR must merge before PR #271 and the other currently open product PRs. Do not merge those PRs into
mainfirst and do not fold them into this branch. After this PR lands, rebuild or rebase each remaining PR on the newmain.Checkpoints
codex/day-109-manual-qa-passd13aa2c11cc504be4b1f7dc34fb44330f9fa5d481d0204ddbaec02606df8d5f4a2079a350cda37a25250c6c24e44eff1e0389bc2ec08ddb53c03216a(merged into the branch at4dc7bcfcfbab01c51262350b47c0a1bf6064e79a)checkpoint/day-109-pre-pr-2026-07-21checkpoint/pr-271-pre-day-109-2026-07-21The recovery tags preserve both pre-integration histories. The intended final merge method is squash merge, after all merge gates below pass.
Why
The real-device QA pass exposed connected failures across authentication, routing, password security, keyboard handling, accessibility, native controls, notification settings, onboarding, and Expo 57 runtime integration. Fixing those failures required shared UI and platform foundations, so this PR intentionally proposes the current DAY-109 remediation state as the next application baseline, subject to the unresolved merge gates and manual acceptance evidence below.
What changed
Authentication, session persistence, and routing
Shared UI, accessibility, and native controls
Notification settings
Onboarding and manual-QA polish
Expo 57 and engineering standards
User impact
Learners receive recoverable and understandable authentication, consistent secure session behavior, usable forms while the keyboard is open, more reliable notification settings, cohesive native controls, and materially improved screen-reader support.
Tracked work
PR #271 remains a dependent follow-up. Its current branch will be rebuilt on the new
mainafter this PR merges.Accepted bundled engineering work
This branch also contains the standards/tooling work requested during the DAY-109 remediation (Matt/Expo skill composition, validation scripts, lint architecture rules, and supporting dependency changes). That work is broader than DAY-109's learner-flow wording but is intentionally included in this all-at-once PR; reviewers should evaluate it as an explicit bundled scope rather than infer it from the learner QA ticket.
Explicitly excluded
Merging this PR is not authorization to publish an OTA or native release. The production workflow must remain fail-closed until the separate release gates are satisfied.
Review map
Because this is a large atomic PR, review it by seam:
CodeRabbit's single-review limit is 150 files while this PR contains more reviewable files, so local CodeRabbit review is being run through WSL in scoped partitions. Findings will be consolidated below.
Validation completed at
d13aa2c11ccpnpm checkpnpm check:unusedpnpm format:checkorigin/mainand re-ran all repository gates on the exact final head79a22ec6dc6f, completed successfullySHA256 6584778BA0B617F6A9B4A4B384D7E11C960270BB896A30020184D3B40C678ADC) installed on the physical Pixel 9; clean cold start, stopped-state reinstall, and Android's automatic foreground package-replacement relaunch all remained active without Clerk/Fatal logsinstall -r; the normal package-update lifecycle did not reproduce it, and the source contains one Clerk provider callsiteFinal merge and broader closure gates
d13aa2c11ccin Debug and optimized Release arm64 simulator builds; Release embeds Hermes bytecode and launches without Metrod13aa2c11cc(@Gamius00 requested)Review findings and merge checklist
CodeRabbit via WSL
src/features/auth: initial focused review atd1e3997bb983; zero findings.srcpartition: 114 changed files reviewed through WSL atd1e3997bb983; four findings, all manually verified (one overlaps the standards review below).scripts: six changed files reviewed through WSL; two verified minor tooling findings.modules: Swift bridge and README reviewed through WSL; one verified major native-lifecycle finding.srcWSL reviews ataa4b8d0d60fefound two minor test-harness issues (fresh app-config module evaluation and an explicit async resolver assertion); both were verified, fixed, and targeted tests pass.srcfindings were individually verified at79a22ec6dc6f: shell-operator boundary coverage, whitespace-only OTA identifiers, complete main-queue iOS teardown, the snapshot-shield bridge contract, WindowsAPP_VARIANT, and the Linear review-status lifecycle are fixed.srcreview of exactly0ec7724..79a22ecfound two valid package-script detector gaps; empty assignments and quoted operator-like text are covered at6728338.79a22ec..6728338found escaped shell-tokenization gaps; escaped separators and quotes are covered atf99bf4c.6728338..f99bf4ccompleted with zero findings.No paid usage was enabled, and the GitHub bot was not used to bypass the WSL-only review policy.
Standards axis — actionable
All prior concrete findings were re-verified against the current code and remain fixed at
d13aa2c11cc:accessibilityRole="alert".theme-variables.tsas the runtime mirror andtheme.tsas orchestration.---anything, with regression coverage.Final standards/build audit additions retained at
d13aa2c11cc:Standards axis — judgement calls
PasswordResetStagebranches. They represent materially different Clerk states, and a descriptor map would obscure control flow without removing a current defect.Spec/acceptance axis
The implementation may become merge-ready independently, but the following remain blockers for closing DAY-109 or treating this as a release-ready build:
Rollback
Squash-merging creates one atomic mainline commit that can be reverted if post-merge verification finds a severe regression. The source branch and checkpoint tags retain the detailed history and both pre-integration states.
Decision record