Skip to content

Release the TestFlight build after a day, gated by CI reference images - #1101

Merged
2 commits merged into
mainfrom
work/1097-simple-release
Nov 9, 2026
Merged

2 commits merged into
mainfrom
work/1097-simple-release

Conversation

@shiny-code-app

@shiny-code-app shiny-code-app Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Why

Chris, during the 1.0.80 App Store proof round: "I hate this part." He approved making an App Store release the TestFlight build plus CI screenshots, and later clarified that the wait is automatic and that visual correctness is judged in the pull request that changes a screen.

Closes #1097

Do not land before Context Panel 1.0.80 is submitted to App Review.

What changes

Submit App Store Review now submits a platform's TestFlight build when:

  • the release commit, read from Ship's release record for that platform, version and build, has a passing shared-view-simulator-references CI job; and
  • the build has been on TestFlight for 24 hours, counted from when Ship (or a Ship retry) reported its TestFlight distribution as successful, and the TestFlight crash watcher filed no crash report for that exact platform and build in those 24 hours. Watcher issues are found by their build marker, so a retitled one still counts.

skip_soak_reason skips the wait and the crash check, never the reference job, and the run log and summary record it. A dry run reports the gate without stopping. A build with no Ship record is refused. The gate is scripts/app_store_submission_gate.py; it reads the existing records (the Ship release record and the crash watcher's issues), so there is no second crash reader. One command submits all four platforms (a loop over per-platform dispatches, so each platform keeps its own release record update).

A pull request that changes a Tests/SharedViewReferences/*.png image must carry a ## Reference images section with the old and new images and the author's statement of what the screen should show and that it does. The CI scope job reads the current body and fails the pull request without it. AGENTS.md and docs/validation-authority.md say so.

What the simulator job launches

It launches the real Release app on each simulator, so a launch crash fails it:

  • iPhone, iPad and Vision Pro: the UI test launches Context Panel and waits for it to reach the foreground. The cell image is drawn in the test runner, not by the app.
  • Watch and Apple TV: the job launches the app with the gallery arguments and screenshots the app itself.

It does not launch the Mac app, any widget extension, the Watch complication extension, the Top Shelf extension or the Mac refresh agent; macOS cells come from a host SwiftPM renderer. Watch and Apple TV launch in gallery mode, so a crash only on the normal launch path is not caught there either. No new machinery was added for these.

Removed

  • Signed validation coordinator, operator flow, runtime receipt ingestion and session, visual approval ledger, reference approvals, ASC evidence reader (scripts/context_panel_validation/, scripts/context-panel-validation.py, scripts/context-panel-runtime-session.py)
  • Release evidence gate, policy and report validator (scripts/context_panel_release_gate/, scripts/context-panel-release-gate.py, scripts/validate-release-evidence-report.py, Config/ContextPanelReleaseEvidencePolicy.json, Config/ContextPanelHistoricalPolicyArchive.json)
  • Submission evidence bundle and its release-evidence/* branch route (scripts/submission-evidence-bundle.py), and evidence_bundle_sha256, validation_train and release_evidence_mode inputs
  • Release-time capture executor and the hosted Shared-View Capture Evidence workflow (.github/workflows/shared-view-capture.yml, scripts/context-panel-shared-view-capture-workflow.py)
  • Surface comparison and its schemas (compare and evidence-template subcommands, comparison_v6, comparison_schema_v2..v4, artifact_comparison, scripts/context_panel_comparison_schema.py)
  • The runtime baseline's --candidate-manifest option
  • Their tests, the operator-flow and runtime-receipts docs, and their github.json routes

Kept: signing, notarization, uploads and the expected-build manifests they write, the CI reference jobs (their capture code moved to scripts/context_panel_shared_view_capture.py and scripts/context_panel_shared_view_matrix.py, and pinned-xcode and capture-config moved into scripts/context-panel-shared-view-references.py), the TestFlight crash watcher, App Store Release Status and the release records, App Review submission, and the runtime baseline's local check, install and reset.

Not removed here: the Swift runtime receipt writers and their CloudKit record types are still in the apps. They are product code on every platform, so removing them is a separate change that should ship through its own TestFlight build.

Removed: about 43,100 lines across code, tests and docs, and the concepts of release evidence, carry-forward, visual approval and capture receipts.

Net lines: -41,365 (code -20,745, tests -18,551, docs -2,069).

Verification

  • python3 scripts/context-panel-test-lanes.py run --lane fast-local-python and --lane routine-ci-python: pass
  • scripts/commit-gate.sh --skip-swift (surface manifest validate, lanes validate, fast Python lane): pass. No Swift changed.
  • uv run scripts/check-release-approvals.py: pass
  • New tests: a passing reference job is required and the override never skips it; the day starts at successful TestFlight distribution, including a Ship retry; a crash report for the build in its first day blocks, including one in a comment, one in a retitled issue and one with an unreadable time; other builds and platforms do not block; the override records what it skipped and proceeds; a dry run reports without stopping; the scope job fails a reference-image pull request without the statement.
  • JetBrains inspection (native PyCharm, changed Python files): RED on the changed lines. What remains: unresolved imports of scripts/ modules that tests add to sys.path (the existing pattern in this repo; the inspection profile does not treat scripts/ as a source root, and the gate test's type warnings follow from that), and type warnings in capture code moved unchanged from the deleted package. Fixed the real ones it found (a min() type, a redundant regex escape, static helpers, an unused parameter).

Review

Reviewed by an OpenAI model through the catalog's model-review helper (author: Anthropic; the CLI did not report the exact model). It found four issues, all acted on:

  1. High: the day started at upload even when TestFlight distribution failed or came later. Fixed: it starts at Ship's successful distribution report, or a retry's; with neither, the build waits unless overridden. Reproduced by the reviewer and now covered by tests.
  2. High: a retitled crash watcher issue was ignored. Fixed: watcher issues are found by their build marker as well as title. Covered by a test.
  3. Medium: two HTML image tags alone passed the reference statement check. Fixed: whole tags are stripped before counting words. Covered by a test.
  4. Low: a matrix test asserted a config literal. Removed.

Noted, not changed: CI run and job lookups read the first 100 results, so an old passing job could be missed after many reruns; the helper then prints how to get a fresh run.

A rereview of the fixes found all four fixed and no new findings.

Chris decided an App Store release is the TestFlight build plus CI
screenshots (#1097). Submit App Store Review now submits a platform's build
when the Ship record's source commit has a passing
shared-view-simulator-references job and the build has been on TestFlight
for 24 hours with no crash report from the TestFlight crash watcher, or when
skip_soak_reason records Chris's override.

Deletes the release-time proof round: the signed validation coordinator and
operator flow, runtime receipt ingestion and session, the visual approval
ledger, reference approvals, the release evidence gate and policy, the
submission evidence bundle, the hosted Shared-View Capture Evidence workflow,
the surface comparison schemas, and their tests and docs. CI keeps only the
capture code it runs.

A pull request that changes a reference image must now carry a Reference
images section with old and new images and the author's statement; the CI
scope job enforces it.
…sues

From the cross-provider review: count the day from when Ship reported a
successful TestFlight distribution, find crash watcher issues by their
build marker as well as title, require whole HTML image tags in the
reference statement, and drop a test that asserted a config literal.
@shiny-code-app

shiny-code-app Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

Review result: weighed
Head: 5263585

Cross-provider review weighed (OpenAI reviewer, author Anthropic). Four findings, all fixed in 5263585: TestFlight day now starts at successful distribution, retitled watcher issues still count, HTML-only reference sections fail, config-literal assertion removed. Rereview: all fixed, no new findings. Details in the PR body.

@shiny-code-app

shiny-code-app Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

Ready for the merge train

Head: 5263585

@shiny-code-app

shiny-code-app Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor Author

Launchplane completed the merge-train step for this pull request.

Launchplane landed this pull request through protected batch PR #1105.

Launchplane manages this comment and will update it as the train moves.

shiny-code-app Bot added a commit that referenced this pull request Nov 9, 2026
@shiny-code-app shiny-code-app Bot closed this pull request by merging all changes into main in ed3a5ba Nov 9, 2026
@shiny-code-app
shiny-code-app Bot deleted the work/1097-simple-release branch November 9, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make an App Store release the TestFlight build plus CI screenshots, and delete the proof round

0 participants