Frozen candidate readiness packet
Status: reviewed preparation only; the release freeze has not been invoked
This packet reconciles the source and evidence needed to designate the next Cookery Trove App Store candidate. Issue #278 is the launch dashboard, #341 controls the freeze, and #335 controls the remaining subscription evidence. This document does not authorize a build, archive, upload, deployment, App Store Connect change, credential action, Apple request, merge, or production mutation.
Reconciled source identity
| Item | Current evidence | Candidate implication |
|---|---|---|
Current master |
37b4973a4b5452419486845526fa311219e7f2c5 |
Validated unsigned baseline after merges #478 and #479 |
| Repository version/build | 110.0.1+7 |
Proposed identity only; not frozen or approved for upload |
| Prior recorded TestFlight build | 110.0.0+58 at bb166031fbb01011514f2d549f91a64e4de8fe67 |
Historical evidence; not the submission candidate |
| Frozen candidate | None | #341 entry criteria are not satisfied |
| Submission archive/commit | None recorded | Must be captured from the eventual clean frozen commit |
| Open pull requests at reconciliation time | #456, #459, #460, #461, #462, #477 | Each must be merged or explicitly deferred before freeze |
The current master contains release-affecting Flutter client, Firebase
Functions, Firestore rules, operational tooling, and documentation changes
since the earlier 110.0.1+3 packet. Those changes include ingredient identity
and cost features, provider-startup fixes, production ingredient migration,
and the App Store Server API-independent subscription mode. The earlier
classification of all post-version changes as backend/readiness-only is no
longer valid.
The clean 37b4973a baseline passed flutter analyze, 385 Flutter tests, 97
Functions tests, and an unsigned production-flavor iOS build. The bundle
reported com.seachellemz.myrecipes, Cookery Trove, version/build 110.0.1 (7),
minimum iOS 15.6, non-exempt encryption false, and 37 lint-clean packaged
privacy manifests. This evidence does not establish a signed or frozen
candidate.
Material release changes
| Group | Representative work | Release effect | Required revalidation |
|---|---|---|---|
| Request-surface security | #458 | Versioned Function inventory and request bounds | Reconcile intended and deployed endpoint state under #183 |
| Ingredient identity and costs | #473–#475 | Client models, editors, cost UI, rules, migration, cleanup, and provider startup | Final candidate regression and migration evidence |
| API-independent subscription launch | #478–#479 | Entitlement refresh without an App Store Server API dependency and guarded deployment tooling | Signed-build StoreKit and App Store Server Notifications V2 evidence under #335 |
| Production recovery | #391 | Validated development-to-production promotion completed and owner accepted | Closed; retain its evidence without reopening the gate |
Current production subscription state
The bounded API-independent cutover completed from exact merge commit
37b4973a4b5452419486845526fa311219e7f2c5:
refresh_subscription_entitlementis active on revisionrefresh-subscription-entitlement-00005-ley;reconcile_apple_subscriptionsis active on revisionreconcile-apple-subscriptions-00005-wig;- both use the existing scoped subscription runtime identity and explicitly
set
APPLE_SERVER_API_ENABLED=false; - existing numeric Apple secret bindings were unchanged and no secret value was read or changed;
- the six-hour reconciliation Scheduler job is paused, not deleted;
app_store_server_notificationsremains active on its unchanged revision; and- no post-cutover severity-ERROR log was returned for either updated consumer.
The former Apple App Store Server API HTTP 401 is no longer on the launch-critical runtime path. Issue #335 remains open for frozen-TestFlight StoreKit and App Store Server Notifications V2 physical evidence, not for an Apple Support response or another authenticated Server API canary.
Open pull-request disposition
| PR | Scope | Freeze disposition |
|---|---|---|
| #456 | This readiness packet | Refresh against current master, review, and merge before freeze |
| #459 | Sanitized legacy Python source recovery | Draft explicitly marked do-not-merge/do-not-deploy; defer from the release branch unless separately redesigned as a safe archive |
| #460 | Mixed-version concurrency compatibility | Conflicts with current master; rebase and complete coordinated client/rules/backend plus two-device validation, or explicitly accept and defer the risk |
| #461 | Interrupted recipe operation integrity | Stacked on #460; decide with #460, then retarget and revalidate |
| #462 | Upgrade and migration readiness | Stacked transitively on #460/#461; retarget after that decision before merging independent documentation/tests |
| #477 | Ingredient-cost backup completeness | Draft backend data-integrity change; rebase and validate v1.0 compatibility, v1.1 round trip, rollback, and deletion behavior before merge, or explicitly defer |
Do not merge the #460 to #462 stack solely because its CI is green against its historical bases. A freeze decision must record the final disposition of every open release-affecting PR.
Evidence ownership and dependencies
| Gate | Evidence required before submission | Current dependency/owner |
|---|---|---|
| #335 subscription cutover | Signed frozen-build purchase, restore, account-switch, lifecycle, offline/degraded, and notification scenarios | Final candidate, configured products/accounts, and physical devices |
| #334 administrative grants | Exact bounded roster inventory, activation timestamps/state, rollback and canary evidence | Product owner and final cutover sequencing |
| #182 App Check | Final per-service enforcement/exception state and timestamp | Technical audit plus product-owner enforcement decision |
| #183 Function controls | Intended/deployed inventory, auth, App Check, IAM, secret-binding, monitoring, and candidate canaries | Technical owner; #459 is quarantine material, not release code |
| #303 paid operations | Representative allowed and denied deployed-operation canaries | Frozen client/backend state and #305 window |
| #264/#267 subscriptions | Final-device purchase, restore, account-switch, lifecycle, and entitlement scenarios | Signed candidate and physical devices |
| #265/#270/#273 integrity | Final disposition of #460–#462 and corresponding concurrency, interruption, and upgrade evidence | Product-owner risk decision followed by technical/device validation |
| #304 cost controls | Budgets, alerts, limits, escalation owner, and measured forecast check | Product-owner financial decisions and production evidence |
| #271 compliance | Legal/support/product/privacy answers, review path, screenshots, and signed-archive validation | Product owner, App Store Connect, and final signed archive |
| #305 final canaries | Exact binary/commit, rules, Functions, App Check, App Store state, PASS evidence, and tested-equals-submitted proof | Frozen candidate and bounded approvals |
| #341 freeze | Explicit owner invocation with exact version/build/SHA and approved release PR list | Every intended release input settled |
App Store submission packet
The repository source of truth for English (U.S.) listing text is
app-store-metadata.md. Before freeze, reconcile it
with the current product and the following owner-controlled inputs.
Repository-backed inputs
- Display name: Cookery Trove.
- Product-page description and private/direct-sharing behavior.
- Support, marketing, and privacy-policy URLs.
- Monthly and annual subscription, restore, renewal, trial, account-deletion, and Apple-subscription-cancellation explanations.
- No public discovery for v1 under #261.
- Unsigned baseline evidence: 37 packaged privacy manifests linted successfully; no packaged manifest declared tracking.
- Export-compliance baseline: the built app reports non-exempt encryption as false.
Owner and App Store Connect inputs still required
- Final localized subscription titles, descriptions, durations, prices, territories, tax category, subscription group, availability, trial, grace-period, and upgrade/downgrade/crossgrade behavior.
- Apple standard Terms of Use selection/link and final legal/product approval.
- App Privacy questionnaire reconciled with actual Firebase, Google Cloud, StoreKit, diagnostics, import, backup, retention, sharing, and deletion behavior.
- Final screenshots showing only shipped behavior.
- Review notes, clean-install test path, and protected review credentials.
- Sign in with Apple assessment against final shipped sign-in providers.
- Current-device and oldest-supported-iOS regression evidence.
Signed-archive-only checks
Do not mark these complete from an unsigned local build:
- clean source equals the owner-designated frozen SHA;
- archive version/build, display name, icon, entitlements, and resolved dependencies match the freeze record;
- Xcode/Organizer validation reports no privacy-manifest, required-reason API, entitlement, export-compliance, or signing error;
- installed legal/support links and localized purchase disclosures work;
- archive upload identity is recorded without exposing private identifiers;
- final TestFlight/device regression and #305 canaries use the same release state; and
- the product owner confirms the tested archive is the submitted artifact.
Freeze entry checklist
- [ ] Every intended v1 change is merged or explicitly deferred with its risk recorded.
- [ ] No unaccepted Implementation-phase P0 remains.
- [ ] Every gate in the evidence table has an owner and available dependency or a documented stop condition.
- [ ] Exact proposed version/build/SHA and approved release PR list are recorded in #278 and #341.
- [ ] Intended rules, Functions, App Check, subscription products, monitoring, and operational state are reconciled in #278.
- [ ] The final clean baseline is rebuilt after the last accepted merge.
- [ ] Product owner explicitly invokes #341.
Until every item is satisfied, 110.0.1+7 is a validated repository baseline,
not a frozen submission candidate.
Stop conditions
Stop preparation and return to #278/#341 if any step requires or discovers:
- an Apple Server API canary, credential rotation/revocation, secret-version action, or secret/private-key disclosure;
- an App Store Connect mutation, agreement acceptance, payment, archive upload, deployment, production mutation, or issue closure without explicit approval;
- a source/version mismatch, dirty candidate checkout, unreviewed client change, open release-affecting PR without disposition, unresolved Implementation-phase P0, or missing evidence owner; or
- private identifiers or review credentials entering source control or public issue text.
Cost and rollback
Preparation and review cost engineering time only and create no provider or production cost. Rollback for this packet is a repository-only revert. It does not authorize rollback of credentials, Functions, App Store configuration, or customer data.
Next decision
Resolve the open PR dispositions, rerun the clean baseline after the final accepted merge, and complete owner/App Store inputs. Then record the exact version/build/SHA and approved PR list before requesting the single #341 freeze decision.