docs: prepare iOS release records and fail-closed candidate checks

Merged
HE
2mo ago
+459-1

Summary

Prepare the repository-owned release records from #47 without pretending the iOS app is release-ready. Add a mobile-only changelog, an App Store tracker with owners and manual approval points, editable English listing/review/release-note drafts, a screenshot manifest and a 1.0.0/build-1 candidate template.

Acceptance criteria

  • Keep iOS release records separate from the Windows version.
  • Distinguish Unreleased, proposed copy and future shipped entries. No shipped iOS version or date is invented.
  • Map candidate version/build to source, native config, App Store version, archive hash, test notes, screenshots and future tag.
  • Provide an agent-runnable draft check and fail-closed release consistency check, with tests and Linux/Windows CI coverage.
  • Keep owner legal/commercial approvals, signing validation, device qualification and publication outside the script's authority.

Definition of done

This is partial preparation for #47. Its dependency #40 and the actual accepted native version/build/source mapping are not complete, so this PR Leaves issue #47 open. The templates deliberately retain null fields and draft warnings. No App Store metadata sync, upload, submission, public website or legal declaration occurs.

Validation

Head ffd98b648249447275ee96385ff49eee659e6ad9.

  • node --test scripts/ios-release/*.test.mjs: thirteen tests pass.
  • node scripts/ios-release/check.mjs: structural draft check passes and reports consistent: false with the actual release blockers.
  • node scripts/ios-release/check.mjs --release: exits 1 for the incomplete proposal, as required.
  • Bun 1.4.2 frozen install and bun run lint: pass.
  • CI runs the tests and draft check on Linux and Windows. No runtime UI changes; screenshots do not apply.

Risks and deferred work

The checker validates consistency, not signatures, genuine human approval or actual device behavior. Build-number monotonicity must also be checked against App Store Connect and earlier archives before signing. The final record belongs beside the archive, outside the source commit, to avoid a self-referential commit hash. Dynamic Expo config will require the checker to consume resolved config if introduced. All native release and owner approval gates remain open.


Summary by cubic

Tracks iOS 1.0.0 release preparation as source-controlled records so the repo can capture drafts, evidence, and candidates without pretending the app is release-ready.

  • Adds a mobile-only changelog, App Store tracker, TestFlight notes, editable en-US listing drafts, and a screenshot manifest naming the open release gates.
  • Marks all copy and release/candidate.json as unapproved drafts; no shipped version, date, or build is claimed.
  • Adds scripts/ios-release/check.mjs with tests: draft mode reports blockers and --release exits 1 on any inconsistency, but never uploads, signs, or approves anything.
  • The check selects the listing by its assigned role rather than filename, requires every listing field including primary category, binds approved-copy receipts to LF-normalized source text, and decodes each screenshot's PNG under bounded allocation before accepting its receipt's dimensions and checksum, without escaping its artifact folder.
  • Upgrades pngjs to 7.0.0 for PNG decoding.
  • Runs the checker and tests on Linux and Windows CI.

Leaves issue #47 open; ios/v1.0.0 mapping awaits #40 and an accepted native build, so the final tag and record stay outside the source commit.

Review fixes: source copy must exist in HEAD and match normalized text; every copy role needs an approved hash; every PNG capture needs a matching source/device/locale/appearance/dimension/hash receipt. The accepted screenshot manifest is an external hash-bound artifact to avoid a self-referential source commit. Missing/draft/stale records fail closed. Release tooling moved to scripts/ios-release alongside repository tooling, rather than being misclassified as untested mobile runtime code. The production-risk gate is unchanged; full local quality qualification passes.

PNG receipts are now decoded with pinned pngjs 7.0.0 and CRC validation, with bounded memory allocation. Matching hashes cannot authorize truncated or corrupt images. Local release-tooling tests and dependency audit pass.