# v1.2.0 release checklist

**Status (2026-05-19):** post-#779 arc; v1.2.0 reindex in flight (PID 25122 on Studio, started 08:09 against the post-#779-fix binary, ETA ~17:00-18:00). This checklist is for the ship sequence that kicks off the moment the save completes.

For the **HOW** of each step (commands, environment setup, automated tooling): see `docs/DEPLOYMENT.md`. This file is the **WHAT and IN-WHAT-ORDER**, with checkable boxes, references to DEPLOYMENT.md sections, and links to the post-#779 artifacts.

For the **STATE-OF-THE-WORLD** at v1.2.0 (test count, CHANGELOG audit, version anchors): see `docs/audits/release-readiness-v1.2.0.md`. That audit is from 2026-05-17 and predates the #779 arc; numbers below supersede it.

## Pre-flight (all done before this file was written)

- [x] Develop tests green: 2,351 / 332 suites passed (4948212 post-PR #796)
- [x] `scripts/check-pre-index.sh` all 6 gates green (PR #795 + #796 just before the production reindex kickoff)
- [x] Brew DB untouched baseline recorded: `May 17 21:51:29 2026 / 2,475,872,256 bytes`
- [x] Release binary built post-fix: `Packages/.build/release/cupertino` mtime `May 19 06:12:42` (post-`face50f` #779 fix landing)
- [x] Disk free: 54 GiB on the save target volume
- [x] `disksleep = 0`, `sleep = 1` (with caffeinate preventing system sleep)
- [x] Launcher `~/bin/reindex-cupertino-dev.sh` pre-flight green; production save kicked off as PID 25122 at `2026-05-19T08:09:54+0200`

## Phase 1: wait for the save to complete (~17:00-18:00)

Monitor `b5hkucl0z` is armed on `~/.cupertino-dev/reindex-20260519-080940.log`. It fires when the log emits `Search index built successfully` (clean finish) OR any of `Error:` / `Traceback` / `Killed` / `FAILED`.

- [ ] Save completes successfully
- [ ] Final log line: `✅ Search index built successfully` present
- [ ] Brew DB still untouched: `stat -f '%Sm %z' ~/.cupertino/search.db` matches the baseline
- [ ] `~/.cupertino-dev/.reindex.pid` cleaned up by the launcher
- [ ] caffeinate (the launcher's helper, PID `caffeinate -i -w 25122`) exited cleanly

## Phase 2: validate the produced search.db (~5-10 min)

Manual version of what #792 would automate. Targets the new `~/.cupertino-dev/search.db`.

- [ ] **Per-source row counts** look right (compare against brew baseline):

  ```bash
  sqlite3 ~/.cupertino-dev/search.db "SELECT source, COUNT(*) FROM docs_metadata GROUP BY source ORDER BY 2 DESC;"
  ```

  Expected (approximate; numbers can drift):
  - `apple-docs`: 350K+
  - `swift-evolution`: 480+
  - `apple-archive`: 360+
  - `hig`: 170+
  - `swift-org`: 110+
  - `swift-book`: 70+

- [ ] **`packages` table gone** (post-#789):

  ```bash
  sqlite3 ~/.cupertino-dev/search.db "SELECT name FROM sqlite_master WHERE type='table' AND name IN ('packages', 'package_dependencies');"
  ```

  Expected: zero rows.

- [ ] **Schema version is 18** (post-#789):

  ```bash
  sqlite3 ~/.cupertino-dev/search.db "PRAGMA user_version;"
  ```

  Expected: `18`.

- [ ] **Enrichment passes ran** (post-#779 fix):

  ```bash
  sqlite3 ~/.cupertino-dev/search.db "SELECT 'fw_aliases_with_syn: '||COUNT(*) FROM framework_aliases WHERE synonyms IS NOT NULL UNION ALL SELECT 'generic_constraints_populated: '||COUNT(*) FROM doc_symbols WHERE generic_constraints IS NOT NULL AND generic_constraints != '';"
  ```

  Expected:
  - `fw_aliases_with_syn`: at least 20 (mini-corpus had 22)
  - `generic_constraints_populated`: 100K+ rows (mini-corpus had 3,474 on 10% sample → expect ~35K+ at full scale)

- [ ] **Smoke a few `cupertino search` queries** against the new DB to confirm sanity:

  ```bash
  Packages/.build/release/cupertino search "SwiftUI View"
  Packages/.build/release/cupertino search "Hashable" --source swift-evolution
  Packages/.build/release/cupertino search "Color" --min-ios 17.0
  ```

  Expected: each returns sensible top-N results. If any throws or returns empty for a query that worked against brew, **stop and investigate before promoting**.

**If any validation fails:** do NOT proceed to Phase 3. Fix on develop, re-build, re-run save. The whole point of this gate is to catch problems before promoting.

## Phase 3: pre-tag chores (~15-30 min)

The four easy-to-forget edits before tagging.

- [ ] **Bump `Shared.Constants.App.version` from `1.1.0` to `1.2.0`** in `Packages/Sources/Shared/Constants/Shared.Constants.swift`. Also bump `databaseVersion` if the bundle schema changed (yes for #789 → v18; bump it too).

- [ ] **Update `README.md` on cupertino main** to reference v1.2.0 (version badges, install instructions, any "current release" prose). Per the standing `v1.0.0-readme-chore` memory rule.

- [ ] **Promote `## Unreleased — staged for 1.2.0` → `## [1.2.0] - 2026-05-19`** in `CHANGELOG.md`. Add the date. Open a fresh `## Unreleased` at the top for future work.

- [ ] **Update `#183` roadmap** per the standing `feedback_update_roadmap` memory rule. Mark v1.2.0 as shipped; note the next milestone.

## Phase 4: promote + tag + bundle + release

Per c1's recommended sequence (chat-channel 08:00, 2026-05-19): main only advances when there's a verified bundle to ship from it.

- [ ] **FF-promote develop → main**:

  ```bash
  git fetch origin
  git push origin develop:main   # fast-forward; refuses if not FF
  ```

  Per the `feedback_develop_to_main_release_branch` memory: don't open a release PR with develop as the head (auto-delete-on-merge would kill develop). Direct FF push is the canonical promote.

- [ ] **Tag v1.2.0 on main**:

  ```bash
  git checkout main
  git pull --ff-only
  git tag -a v1.2.0 -m "v1.2.0: #779 symlink-resolve, #786 FileManager wrapper, #789 packages cleanup, #793 regression test, #794 pre-index gate"
  git push origin v1.2.0
  ```

  Per the `feedback_no_version_bumps_without_go` memory: this whole phase happens only after you (Mihaela) explicitly say go.

- [ ] **Build v1.2.0 bundle**: see `docs/DEPLOYMENT.md` "Automated Release" section. The `cupertino-rel` binary handles the bundle zip + sha256 + GitHub release.

  Or manually:

  ```bash
  cd ~/.cupertino-dev
  zip -r cupertino-databases-v1.2.0.zip search.db samples.db packages.db
  shasum -a 256 cupertino-databases-v1.2.0.zip
  ```

- [ ] **Create GH release** on `mihaelamj/cupertino` with the tag + bundle zip as asset:

  ```bash
  gh release create v1.2.0 \
      --title "v1.2.0" \
      --notes-file <release notes file> \
      cupertino-databases-v1.2.0.zip
  ```

  Release notes should cross-link `docs/postmortems/2026-05-18-save-symlink-enotdir.md` (the postmortem the bundle's #779 fix ships from).

## Phase 5: Homebrew formula (~10 min)

Different repo. Per the `v1.0.0-homebrew-formula-chore` memory:

- [ ] **Bump formula in `mihaelamj/homebrew-tap`** to the new tag URL + new sha256

  ```bash
  cd <homebrew-tap clone>
  # edit Formula/cupertino.rb: url, sha256
  git add Formula/cupertino.rb
  git commit -m "cupertino 1.1.0 -> 1.2.0"
  git push
  ```

- [ ] **Verify a fresh `brew install`** on a clean Mac (or a `brew upgrade` on the Studio) pulls v1.2.0

  ```bash
  brew upgrade mihaelamj/tap/cupertino
  cupertino --version  # should print 1.2.0
  cupertino setup      # downloads the new bundle
  ```

## Phase 6: cleanup chores

- [ ] **Write `docs/handoff/2026-05-19.md`** for cross-Mac continuity. Captures: what shipped, what's in flight, what's open. Per the existing `docs/handoff/` pattern.

- [ ] **Close c1/c2 coordination issue #783**. Collab ended at 08:53; transcript at `~/Downloads/claude-chat.jsonl` is the audit trail.

- [ ] **Clean up local-only artifacts** (per-Mac, not committed):
  - `~/.cupertino-mini-corpus/` (the 10% fixture; keep if you want; delete with `scripts/setup-mini-corpus.sh` rebuild later)
  - `/Volumes/Code/DeveloperExt/public/cupertino-perf-test/` (perf-test base-dir; empty unless future benchmarks)
  - `/Volumes/Code/DeveloperExt/public/cupertino-mini-corpus-inspect/` (the post-#789 partial-corpus snapshot c1 inspected; safe to delete)
  - `/tmp/save-mini-corpus-*.log`, `/tmp/pre-index-check.out`, `/tmp/cupertino-pre-index.*` (transient logs)

- [ ] **File the launcher active-failure-notification issue** (the unfiled gap from the #779 postmortem's §7.2). Low priority but tracking it closes the postmortem's open follow-up.

## References

- `docs/DEPLOYMENT.md` — the canonical HOW for all phase 3-5 commands; this checklist is the WHAT-AND-WHEN around it
- `docs/audits/release-readiness-v1.2.0.md` — May 17 readiness snapshot (predates the #779 arc; superseded by this file)
- `docs/postmortems/2026-05-18-save-symlink-enotdir.md` — the postmortem that drove the #779 / #786 / #789 / #793 / #794 / #796 changes shipping in v1.2.0
- `docs/fun-facts.md` — the indexing-throughput curve data + Mihaela's accept-the-SQLite-limitation stance
- `docs/perf/2026-05-19-fts5-bulk-load-research.md` — deferred FTS5 perf-research note (not a v1.2.0 ship item; for future reference)
- Chat coordination transcript: `~/Downloads/claude-chat.jsonl` (per-Mac, not committed)
