Junior goldplate — overnight report, 24 Sept 2026

Branch feat/junior-goldplate (from 4b38778, the audit commit), pushed after every item. Plan: docs/audit/junior-sweep-2026-09-23.md §6, items A1–A6, B1–B7, C1–C5 (C6 and C7 skipped as instructed). Secondaire was read from a git archive main export only; its working tree and branches were not touched.

Result: all 18 items done, none reverted or skipped. Gates at the end: flutter analyze says No issues found, flutter test 164/164, integration suite green on the iPhone 17 Pro simulator and the Pixel 9 API 36 emulator (details in §1). TestFlight: see §7.


1. Items

# Item Status Commit(s) Evidence
A1 Write-mode focus theft: port Secondaire’s WrittenIndicativeStudyWidget; VerbTestModel.add() stops notifying done d6df1d9 test/regression/write_to_test_focus_test.dart (fails before, passes after — §2); test/widgets/written_indicative_study_widget_test.dart
A2 Focus-safe test fields (FocusEnabledTextField), keyboard next/done done 7dd2ebd test/routes/verb_indicative_test_route_focus_test.dart (types all 6 persons char by char)
A3 Child-safe keyboard flags on every answer field done 4d869fa test/widgets/answer_text_field_test.dart
A4 Answer normalisation (trim, spaces, ’/ʼ → ‘, NFC) + same-length-wrong bug done e36d018 test/util/answer_normaliser_test.dart, test/util/answer_comparison_test.dart
A5 Fields visible before tapping; 48 dp targets done d948c0c test/theme/answer_field_visibility_test.dart (≥3:1, 6 palette/brightness combos); screens/before_after/
A6 Smoke async* loops run; controllers disposed; write→test→evaluate integration test via testTextInput done 3c85749, 4cc5723 integration_test/write_flow_test.dart green on iOS sim + Android emu; scripts/run_integration_tests.sh
Phase A gate   green a58386e write flow 1/1, smoke 5/5 on both platforms; screens/A/ (3 devices × light/dark/XXL)
B1 One MaterialApp, one navigator, clean stack, back buttons done dc4c762 (+ 30e203c) test/app/back_navigation_test.dart (6), also on devices via integration_test/back_navigation_test.dart
B2 M3 theme, colours in one token file, 3 palettes (P1 default) done a5d23f3, ef9251d, 1ced30b, 9eaa8df test/theme/palette_test.dart (no colour literal outside palette.dart; WCAG AA per palette × light/dark); palettes/
B3 SafeArea inside Scaffold (black bands) done c2bc9fc test/app/edge_to_edge_test.dart (fails on pre-B3 code, passes)
B4 Flexible layouts, full “ils/elles”, iPad 600 pt cap, iPhone portrait done f42f005 test/layout/layout_test.dart (SE, 17 Pro, iPad Air 11”)
B5 TextScaler, cap 2.0× done 32e9538, 7245bc3 test/layout/text_scale_test.dart (3 devices × 1.3/2.0/3.1×)
B6 Secondaire-style header, cover-all, result rows, animated check done c061580 test/widgets/study_screens_test.dart
B7 Dutch only, all strings in app_nl.arb, delegates everywhere done ffd7167 test/l10n/dutch_only_test.dart (runs nl-BE on an en-US device; guard against literal UI strings)
Phase B gate   green 2554d9b at 7245bc3: write flow 1/1, smoke 5/5, back navigation 6/6 on both platforms; screens/B/
C1 App icon single-size 1024, 15 orphans gone, LaunchImage done 7bca9c0 actool compiles with no warning; test/platform/ios_assets_test.dart
C2 Dart 3 SDK, analyzer clean, dependency + dead-code hygiene done af5cbc0 flutter analyze: No issues found (audit: 65)
C3 .gitignore/tracked files, .gitattributes + CRLF, Android build done 0bd68c0 flutter build appbundle --release OK; merged release manifest has no INTERNET; clean git status after builds
C4 savoir = weten, sorted list, search crash, duplicate results done 14dd242 test/routes/verb_list_search_test.dart
C5 Settings/app coverage; capture harness committed done 9b25cfe coverage 96.3% (audit 82.2%); lib/settings 92.6% (was 28.8%), app.dart 100% (was 43%); test/privacy/no_personal_data_test.dart
Phase C gate   green 9eaa8df (tested), 1b3b7e9 (4.1.0+21) analyze clean; 164/164; write flow 1/1, smoke 5/5, back navigation 6/6 on iOS sim + Android emu; screens/C/
C6, C7 More tenses; history/streak skipped (instructed) — Decisions #7, #8

Fixes found by the gates themselves (each its own commit):

  • 30e203c — B1 Android gate: write mode’s keyboard next used Flutter’s default geometric nextFocus() mid-animation.
  • ad029ca — phase C Android gate: write mode could skip a person (≈1 run in 4 on the emulator). Instrumented: one next, but the page went 1 → 2 because the viewport shrank mid-animation (keyboard inset) and the animation kept its old pixel target. The carousel now snaps to the page it was heading for; focus moves only at rest. 5/5 after, 1/5 with a first (wrong) hypothesis — both runs logged in the commit message.
  • 9eaa8df — phase C screenshots: result rows were saturated green/red with a blue pronoun. Pastel feedback containers + a palette test for them.
  • cef6546 / 4e56ddf — the capture harness rendered “dark” runs light; phase A dark sheets were re-captured at the phase A commit.
  • Android integration tests had never been able to run: the debug AndroidManifest.xml was a copy of main without INTERNET, so the Flutter tool could not reach the Dart VM service. Standard debug-only manifest restored in A6; main/release still have no INTERNET (verified in C3).

2. The focus test, before and after (A1)

Full output: logs/focus_test_before.txt, logs/focus_test_after.txt.

BEFORE (4b38778 + test)                          AFTER (d6df1d9)
REPRO iOS       focus after 1st char: false  ✗   focus after 1st char: true   ✓
                text after 2nd char: "a"         text after 2nd char: "ai"
                hidden write field has focus: true   ... has focus: false
REPRO Android   focus after 1st char: false  ✗   focus after 1st char: true   ✓
CONTROL (cover) "ai"                         ✓   "ai"                          ✓
WRITE MODE      "ai"                         ✓   "ai"                          ✓
                +2 -2: Some tests failed.        +4: All tests passed!

3. Screens, before and after

One image per device, audit (top) against phase C (bottom), light, normal text:

Full sweeps per phase gate (each: iPhone 17 Pro, iPhone SE, iPad Air 11” × light, dark, largest accessibility text): screens/A/, screens/B/, screens/C/. Audit “before” sheets, including dark + XXL: docs/audit/img/sheet_junior_*.png.

4. Palettes

palettes/palette_p1.jpg (default) · palette_p2.jpg · palette_p3.jpg — every screen, light (top row) and dark (bottom row), iPhone 17 Pro.

  • P1 · Mascotte (shipped): the mascot’s steel blue, the indigo the app already used, the mascot’s orange for the cover blocks.
  • P2 · Zonnig: sea green, sunflower yellow, coral.
  • P3 · Kermis: grape purple, sky cyan, candy pink.

All three pass the same AA checks (test/theme/palette_test.dart); the answer-feedback colours (green/red/orange) are shared.

To switch: in lib/theme/palette.dart, change the one line const JuniorPalette activePalette = JuniorPalette.p1Mascot; to p2Zonnig or p3Kermis. (To preview without editing: --dart-define=JUNIOR_PALETTE=p2.)

5. Choices I made

Write path

  • The write widget was ported as-is (vertical carousel); cards got a 48 pt input row, so the carousel shows two cards per screen instead of 2.4.
  • Secondaire’s FocusEnabledTextField re-requests focus in onChanged/onTapOutside; I left that out — tapping the next field fires onTapOutside on the current one and the two would fight.
  • Answers are compared case-sensitively (autocapitalisation is off, so a capital is a real typo). One line to relax in lib/util/answer_normaliser.dart.
  • NFC is a small built-in composer for the accents French uses, not a package.
  • Also set enableIMEPersonalizedLearning: false (Android keyboards must not learn from a child’s typing).
  • Deleted TextChecker and ExpectedRow (dead after the port) and two trivial tests (1+1, an empty file).

Navigation (B1)

  • Stack: home → (start replaces) verb list → mode choice → study → test → (replaces) result. Android back on the verb list leaves the app. Back from the test goes to the study screen (to look again); “repeat” on the result goes to the mode choice; “home” to the verb list.
  • State restoration dropped (the restorable* calls restored nothing).
  • A changed singular/plural choice returns to the verb list (or home if settings was opened from home).

Design (B2, B4, B6)

  • Colour schemes are generated from each palette’s seeds (ColorScheme.fromSeed) instead of Secondaire’s hand-written tables: a palette is six colours and every pair keeps Material’s tone contrast. Accent and feedback containers use pastel variants (the “fidelity” variant made them the raw seed colour — unreadable; found twice, both fixed and tested).
  • Kept Junior’s larger type scale (25/22/20/16 sp) rather than Material’s defaults.
  • Dark mode field borders use onSurfaceVariant (the outline was 2.9:1 on the tinted write card).
  • App bars name the step (Afdekken, Kaartjes, Schrijven, Test, Resultaat); the verb sits in the header card. The “indicatif · présent” chip stays French (content, not UI copy).
  • Cover blocks are the palette’s accent (orange in P1) with a tap icon; revealed forms in the “correct” green.
  • The result screen shows the right form inline and keeps the “?” dialog.
  • iPhone is portrait-only; iPad keeps every orientation. Android is not locked (the decision named iPhone only).

Text size (B5)

  • One cap, 2.0×, at the root. I did not go higher: the app bars and the write carousel are fixed-height beyond that. Tested at 3.1× (clamped).

Languages (B7)

  • The app always runs in nl-BE, whatever the device language; Info.plist declares CFBundleLocalizations = nl so system UI inside the app is Dutch too (not a usage string, no permission).

Polish (C)

  • The icon is the existing hand-made icon1024.png (no new artwork — still yours to approve). The launch screen now shows the mascot on white.
  • C3 untracks generated plugin registrants and IDE files; the gradle wrapper scripts stay tracked. The release AAB is 124 MB because the existing debugSymbolLevel 'FULL' puts native symbols in bundle metadata (not shipped to devices).
  • After choosing a verb in search there was no way back to the whole list: added “Toon alle werkwoorden”.
  • The verb list keeps its scroll position now (it used to be rebuilt).

Signing (end of night)

  • The provisioning profile “Verbomatique Junior App Store 2026” contains one certificate (SHA-1 B283EB36…, Apple Distribution: Dries Bellen (Z4HB79CS69), expires 30 June 2027). I signed with that keychain identity. That it is the certificate Apple calls KJ972AVRN3, and that the profile is Apple’s 4BQW8ARL38, is an inference: neither ID is stored in the files on this Mac.

6. New packages

None. Removed: test (duplicated flutter_test), shared_preferences_web, flutter_web_plugins. flutter_launcher_icons moved to dev_dependencies. No network, analytics, crash reporting, ads, IAP or notifications were added; no permissions or usage strings (main AndroidManifest.xml: 0 uses-permission; Info.plist: 0 UsageDescription).

7. TestFlight

Uploaded; processed; not submitted. Build 4.1.0 (21), commit 1b3b7e9.

  • Archive: flutter build ipa --release --no-codesign (unsigned), then xcodebuild -exportArchive with manual signing: profile Verbomatique Junior App Store 2026, identity Apple Distribution: Dries Bellen (Z4HB79CS69) (SHA-1 B283EB36…, see §5), team Z4HB79CS69, no -allowProvisioningUpdates.
  • IPA checks (all pass): CFBundleDisplayName = Verbomatique Junior · CFBundleShortVersionString = 4.1.0 · CFBundleVersion = 21 · ITSAppUsesNonExemptEncryption = false · MinimumOSVersion = 15.0 in the app and in App.framework · bundle id com.teamwabisabi.verbomatique · codesign --verify --deep --strict: valid, satisfies its Designated Requirement · TeamIdentifier Z4HB79CS69 · get-task-allow false · 0 usage strings.
  • Upload: fastlane upload_to_testflight with the Secondaire ASC API key (by path, never printed), apple_id 1587030454, skip_submission: true, at 01:57.
  • 15 minutes later (02:12): processing_state = VALID, not expired. It is in TestFlight for internal testing. No review submission, no external testers, no metadata edits.
  • Nothing was done in Play Console.

8. Real-iPhone check for Dries (≈10 minutes)

Install the TestFlight build, set iPhone language to Dutch or English (the app must be Dutch either way).

  1. QuickType off? Open schrijven for any verb. The suggestion bar above the keyboard must be gone; type suis and tap space — no word is inserted, no autocorrect. The field must show exactly what you typed.
  2. Accents and j’ai. In the être test, type êtes with a long-press on e — it must count as right. For avoir, the pronoun shows as j' and you type only ai; check it reads “j’ ai” correctly in the result. Also type a curly apostrophe (’, long-press on ') somewhere — it must be treated like '. A trailing space (suis ) must still count as right.
  3. Focus never jumps. Write mode → forward → test: tap the first field once and type all six persons using only the keyboard’s volgende key. Every letter must land where you look. Then the same starting from afdekken and kaartjes.
  4. Hardware keyboard (iPad or a Bluetooth keyboard): Option-i then e gives ê; Tab/Return move on; nothing is capitalised.
  5. Dictation: dictate “sommes” into a test field; it should land in that field and be judged normally.
  6. Large text: Settings → Accessibility → Larger Text, max. Walk verb list → schrijven → test → resultaat. Nothing cut off; “ils/elles” in full; pronouns move above the field on narrow rows.
  7. Dark mode: in the app’s settings pick Donkere kleuren; every screen dark, fields visibly outlined, results readable.
  8. Back navigation: from the result screen, swipe back (→ study screen), home icon (→ verb list), repeat icon (→ mode choice). The verb list has no back button; it is the start.
  9. Singular/plural: turn Meervoud off in settings mid-verb → you land on the verb list; the next verb shows only je/tu/il/elle.
  10. iPad: content centred, never wider than a phone; rotate — still fine; Scribble into an answer field.

Anything odd: the fastest repro is integration_test/write_flow_test.dart and the screenshots in screens/C/.


Build 22

24 Sept 2026, same branch, same method (one commit per item, pushed, each with a test) and the same hard limits. Items from Dries’s test of build 21. Screenshots: build22/items.jpg (one per item), build22/lt_ios.jpg and build22/lt_android.jpg (the large-text walk).

Result: all 7 items done, none reverted or skipped. Build 4.1.0 (22) uploaded to TestFlight, not submitted.

# Item Commit Test Screenshot (build22/items.jpg)
1 P2 “Zonnig” is the default palette (icon unchanged, approved) fd358d0 test/theme/palette_test.dart ‘the shipped default is P2 “Zonnig”’ (all three palettes still AA) every frame; item1_4_cover_zonnig_no_chip
2 Per-keystroke traffic light on each write-mode field: amber = right so far, red = deviates, green = complete (animated check kept); empty = no colour; test screen gives none 3e80881, 20104d4, f781552 test/util/answer_comparison_test.dart ‘traffic light’ (ê, decomposed ê, curly apostrophe, dead-key accent); test/widgets/write_feedback_test.dart (border colour + 3 pt width + icon + spoken label per state; none on the test screen); palette_test: feedback colours ≥ 4.5:1 on the field item2_a_empty, item2_b_red, item2_c_amber, item2_d_green
3 Search ignores accents and case; ‘e’, ‘et’, ‘etre’ find être; prefix matches first c4ff1a7 test/util/text_fold_test.dart; verb_list_search_test types ‘etre’ and ‘e’ item3_search_e (entendre, entrer, être first), item3_search_etre
4 No “indicatif · présent” chip or any tense/mode label 7683774 test/layout/no_tense_labels_test.dart walks every screen; verb_selection_route_test (one start button even for a verb with an imparfait) item1_4_cover_zonnig_no_chip
5 Enkelvoud/Meervoud mid-verb: study updates in place (answers kept), test restarts after confirmation, result applies next round; never both off; logic in VerbTestModel 9313d1d test/model/cardinality_in_progress_test.dart (every outcome); test/app/cardinality_change_test.dart (write mode keeps answers, test cancel/confirm, result deferred + snackbar, switches) item5_a_settings_last_switch_locked, item5_b_cover_updated_in_place, item5_c_test_restart_dialog, item5_d_test_restarted_all_persons
6 Android: portrait on phones, all orientations on tablets (sw ≥ 600 dp) 8954b6e test/platform/android_orientation_test.dart; on emulators: Pixel 9 requestedOrientation=SCREEN_ORIENTATION_PORTRAIT, stays ROTATION_0 with landscape forced; Pixel Tablet SCREEN_ORIENTATION_UNSPECIFIED item6_android_phone_landscape_forced
7 Automated large-text walk (home → list → search → mode → write → test → result → settings) in scripts/run_integration_tests.sh fbd4580 integration_test/large_text_test.dart build22/lt_ios.jpg, build22/lt_android.jpg
— Gate, screenshots, release 0f01bed, 14ecd4e see below  

Large-text test result (from the final gate, scripts/run_integration_tests.sh):

Platform Size set Result Screenshots Restored
iOS, iPhone 17 Pro simulator accessibility-extra-extra-extra-large 11 steps, no FlutterError, no clipped “ils/elles” — All tests passed 11 content_size = large
Android, Pixel 9 API 36 emulator font_scale 2.0 (the maximum) 11 steps, same checks — All tests passed 11 font_scale = 1.0

The test proves it can fail: at 1.0× it refuses to run (“the device must be at its largest text size (got 1.0x)”), and with the pronoun column deliberately halved it failed at the test screen: “ils/elles clipped (71.7 < 139.5)”.

Gate before the build (code at f781552): flutter analyze — No issues found; flutter test — 195/195; integration on both platforms — write flow 1/1, smoke 5/5, back navigation 6/6, large-text walk green.

Choices I made (build 22)

  • Item 2 semantics come from Secondaire’s write widget (_validateInput, ported as compareAnswer in A1), not the pre-port Junior TextChecker, which kept the previous colour for a same-length wrong answer. Added: an accent a hardware keyboard is still composing (ˆ before the e) is not red yet.
  • Item 2: amber is a dots icon, red a cross, green a check — in the field and in the big status icon (which used the check for amber too; fixed in f781552).
  • Item 5: the test’s “cancel” keeps you in settings with the change still showing, so you can undo it; confirming restarts the same verb. On the result screen a snackbar says “Je keuze geldt vanaf de volgende ronde.” Write mode also keeps what was typed for a person that is switched off and on again (the spec asked only for persons that remain). The old silent “switch the other one back on” is replaced by a disabled last switch.
  • Item 5: the mode-choice screen counts as “study” (updates in place); the verb list and home just remember the choice for the next verb.
  • Item 6: done with a resource qualifier (values-sw600dp) read in MainActivity.onCreate, because android:screenOrientation cannot depend on screen size.
  • Item 7: Android’s maximum font scale is 2.0 on current versions, so “2.0, then the maximum” is the same value; the script prints the value it set.

New packages: none. Permissions / usage strings: none added. Play Console: untouched.

TestFlight (build 22)

Uploaded; processed; not submitted. Build 4.1.0 (22), commit 14ecd4e.

  • Archive and export exactly as build 21: flutter build ipa --release --no-codesign, then xcodebuild -exportArchive with manual signing (profile Verbomatique Junior App Store 2026, Apple Distribution: Dries Bellen (Z4HB79CS69)), no -allowProvisioningUpdates.
  • IPA checks, all pass: display name Verbomatique Junior · 4.1.0 (22) · ITSAppUsesNonExemptEncryption false · MinimumOSVersion 15.0 in the app and in App.framework · codesign --verify --deep --strict valid and satisfies its Designated Requirement · team Z4HB79CS69 · get-task-allow false · 0 usage strings.
  • Uploaded with fastlane upload_to_testflight (ASC API key by path, skip_submission) at 08:17.
  • 15 minutes later (08:32): processing_state = VALID, not expired. Available for internal testing. No review submission, no external testers, no metadata edits.

Build 23

Dries tested build 22 on his iPhone and marked it “All OK → merge”, with four fixes for build 23. Same method and limits as build 22: one commit per item with a test, pushed after each.

Step 0 — merge. feat/junior-goldplate at e0e0a5c (build 22) merged into main with --no-ff: merge commit 3e4c653, pushed (a2c6fec..3e4c653). main’s tree equals e0e0a5c’s tree: both 625fc14442fea36a3b50df6b96b89ff792565c7c. Build 23 work continued on feat/junior-goldplate.

# Item Commit Test Screenshot (build23/items.jpg)
1 Write mode: only the in-field feedback icon (dots / cross / check, with its spoken label); the big status icon is gone c37ce24 written_indicative_study_widget_test (icon read from the field, no comparisonStatusIcon), write_feedback_test (no icon larger than 48 pt), verb_indicative_study_write_mode_form_state_test item1_a…d (empty, amber, red, green)
2 Result: no “?” button, no dialog; the right form is on the card (→ sommes). Dead code and the three dialog strings deleted b3cab35 study_screens_test (“evaluate: no ‘?’ button or dialog”), verb_indicative_evaluate_route_test; smoke_test and write_flow_test read the card instead of the dialog item2_result_no_question_mark
3 P3 “Kermis” is the default — still one line in lib/theme/palette.dart (activePalette) 70dd2a1 palette_test (“the shipped default is P3 ‘Kermis’”) + the AA contrast checks for every palette item3_kermis_verb_list (and every other shot)
4 Automated iPad walk: the 11 large-text steps on iPad Air 11” (M3) and iPad mini (A17 Pro), portrait and landscape 3c5acd0, fix 753f7e8 integration_test/ipad_test.dart, in scripts/run_integration_tests.sh (iOS target) build23/ipad_*.jpg
— Version 4.1.0+23 4267682    

iPad result (final gate at 753f7e8; per step: no FlutterError, content ≤ 600 pt and centred, write card not clipped, no clipped “ils/elles”):

Device Portrait Landscape Screenshots
iPad Air 11-inch (M3) pass, 11 steps pass, 11 steps 22 (ipad_air11_portrait.jpg, ipad_air11_landscape.jpg)
iPad mini (A17 Pro) pass, 11 steps pass, 11 steps 22 (ipad_mini_portrait.jpg, ipad_mini_landscape.jpg)

The test found a real bug before it went green: in landscape, on both iPads, it failed at step 05_write — the write carousel sized its cards from the viewport height, and with the keyboard up the card was too short for its own content (“the expected form (208–238) is outside the card (237–255)”). My first fix (card size from the screen height) broke typing on Android. 753f7e8 removes the height dependency: one person per carousel page, the card centred at its natural height with its own scroll view. Visible change: the neighbouring cards no longer peek in from the sides.

Not automated: Scribble (Apple Pencil handwriting into the field). It needs a Pencil on real hardware; the simulator has no Scribble input and Flutter’s test binding can’t inject it. It stays a manual check when an iPad is at hand.

Gate before the build (code at 753f7e8): flutter analyze — No issues found; flutter test — 194/194 (one test fewer than build 22: the dialog-key test went with the dialog). Integration, iOS (iPhone 17 Pro): write flow 1/1, smoke 5/5, back navigation 6/6, large-text walk pass (11 shots, text size restored), iPad walk as above. Android (Pixel 9 API 36): write flow 1/1, smoke 5/5, back navigation 6/6, large-text walk pass (font_scale 2.0, restored to 1.0).

Choices I made (build 23)

  • Item 1: the in-field icon keeps its spoken label, so VoiceOver/TalkBack still say “Goed bezig / Fout / Juist” — nothing was lost by removing the big icon.
  • Item 2: the wrong answer stays struck through above → <right form>; showAnswerTooltip, correctAnswerTitle, gotIt and the now-unused statusNotStarted were removed from app_nl.arb.
  • Item 4: landscape is set through the Flutter binding (tester.view.physicalSize swapped), not simctl — simctl has no rotate command. In landscape the screenshots are rendered from the layer tree, because the capture driver grabs the device in its physical (portrait) orientation.
  • Item 4: the iPad walk also caught the verb-list search results running full width; they are now capped at 600 pt like the list (part of 3c5acd0).
  • The iPad test refuses to run on a screen narrower than 600 pt (“run on an iPad simulator”), so a phone run can’t pass it by accident. The script only runs it on the two iPads.

New packages: none. Permissions / usage strings: none added. Play Console: untouched.

TestFlight (build 23)

Uploaded; processed; not submitted. Build 4.1.0 (23), commit 4267682.

  • Archive and export exactly as build 22: flutter build ipa --release --no-codesign, then xcodebuild -exportArchive with manual signing (profile Verbomatique Junior App Store 2026, team Z4HB79CS69), no -allowProvisioningUpdates.
  • IPA checks, all pass: display name Verbomatique Junior · 4.1.0 (23) · ITSAppUsesNonExemptEncryption false · MinimumOSVersion 15.0 in the app and in App.framework · codesign --verify --deep --strict OK · team Z4HB79CS69 · get-task-allow false · 0 usage strings.
  • Uploaded with fastlane upload_to_testflight (ASC API key by path, skip_submission) at 11:37.
  • 15 minutes later (11:52): processing_state = VALID, not expired. Available for internal testing. No review submission, no external testers, no metadata edits.