diff --git a/docs/release-0.6.7-prep.md b/docs/release-0.6.7-prep.md new file mode 100644 index 0000000..59f0c57 --- /dev/null +++ b/docs/release-0.6.7-prep.md @@ -0,0 +1,295 @@ +# PeerSpeak 0.6.7 release prep + +Prepared: 2026-08-22 + +Planned work day: 2026-08-23 (confirm the actual date before updating the changelog) + +Release target: GitButter release page with a verified Linux x86_64 AppImage + +This is a checklist, not release authorization. Pushing `main`, creating or +pushing a tag, creating the GitButter release, and uploading assets remain +explicit approval gates. + +## Starting checkpoint + +Recheck every value live tomorrow; these are the known-good handoff values from +2026-08-22. + +- PeerSpeak: `main` at `0823f617`, 17 commits ahead of `origin/main`. +- PixelPass: `main` at `ce909afc`, 14 commits ahead of `origin/main`. +- Latest published PeerSpeak tag: `v0.6.6`. +- Current Cargo/Windows version: `0.6.6`. +- Current field-test build: + `packaging/appimage/peerspeak-0.6.6-unofficial-20260822-ps0823f617-ppce909afc-fieldtest-x86_64.AppImage` +- Current field-test SHA-256: + `f094a665dbd719929d6def32c8fd3d4943e4b88b6290e371e57b127c4e91ec45`. +- The same build was staged for Lindsay at + `/home/lindsay/Downloads/peerspeak-0.6.6-unofficial-20260822-ps0823f617-ppce909afc-fieldtest-x86_64.AppImage`. +- Preserve the existing user-owned `docs/FEATURES.md` modification and + untracked `.codex/` directory. Do not include either in release-prep commits + unless the user explicitly puts them in scope. + +The current one-row audio-picker build passed local AppImage artifact checks, +but it still needs the final two-machine field pass. Earlier two-machine passes +proved that desktop audio was heard, call voices were not echoed, and no warning +was visible. They also exposed the now-fixed stale viewer/warning behavior. Do +not substitute those earlier passes for testing the current build. + +## Version decision + +The expected release is **0.6.7**. + +`VERSIONING.md` defines pre-1.0 MINOR bumps as breaking wire-protocol changes, +not as a measure of feature size. The diff from `v0.6.6` through `0823f617` is a +large screen-share implementation and local UI/lifecycle change, but it does +not change `src/protocol.rs` or bump an audio, friends, files, or gossip protocol +version. Under the repository's policy, that makes this a PATCH release. + +Use `0.7.0` only if tomorrow's final source review finds or adds an actual +incompatible wire change. If that happens, identify and bump the affected +Layer-2 protocol constant/domain in the same change and plan a coordinated +upgrade for every peer. + +## Critical build-label rule + +The first/home screen visibly identifies the binary as: + +```text +PeerSpeak v (<8-character commit hash>) +``` + +The same label also appears in Settings. The two pieces come from different +places: + +- `Cargo.toml` supplies the version through `CARGO_PKG_VERSION` and must be + bumped from `0.6.6` to `0.6.7`. +- `build.rs` runs `git rev-parse --short=8 HEAD` and embeds the result as + `PEERSPEAK_GIT_SHORT`. **Do not edit or bump the hash by hand.** + +Consequences for the release order: + +1. Make and commit all source, version, changelog, and field-evidence changes. +2. Build the final AppImage from that clean final commit. +3. On first launch, verify the title screen says exactly + `PeerSpeak v0.6.7 ()`. +4. Verify the displayed hash equals `git rev-parse --short=8 HEAD`. +5. Tag that exact commit as `v0.6.7`. + +If any commit is added after an AppImage is built—even a field-evidence or +release-note commit—the embedded hash is now old. Rebuild and revalidate the +AppImage. Never publish an artifact whose visible hash differs from the tag +target. + +## Tomorrow's runbook + +### 1. Re-establish live state + +From `/home/mollusk/git/butter/peerspeak`: + +```sh +git status --short --branch +git log -1 --oneline --decorate +git -C ../pixelpass status --short --branch +git -C ../pixelpass log -1 --oneline --decorate +git fetch --prune --tags origin +git ls-remote --heads --tags origin +df -h / /mnt/superjar +pgrep -af 'peerspeak|pixelpass|mpv|gst-launch' || true +``` + +Confirm that: + +- the checkpoint commits above are still the intended source; +- neither repository has unexpected changes; +- the existing `docs/FEATURES.md` and `.codex/` state is preserved; +- no stale call/share processes are running; +- `v0.6.7` does not already exist locally, remotely, or on GitButter; +- there is enough space for one-job release builds and extracted AppImages. + +### 2. Complete the current-build two-machine field test + +Use the stamped `0823f617` AppImage on this machine and Lindsay's staged copy. +Start with PeerSpeak and any old screen-share helper/player processes closed. + +Run both directions, with Lindsay keeping software encode enabled where needed: + +1. Mollusk hosts; Lindsay views. +2. Lindsay hosts; Mollusk views. +3. In each direction select the sole visible **All system audio** row. +4. Play desktop audio after the share begins, including starting a new audio + stream/application during the share. +5. Talk from both machines while the desktop audio plays. +6. Stop sharing while the voice call remains active. +7. Start one more share, then have both peers leave the call. + +Record all of these results explicitly: + +- the picker has one desktop-audio row, not duplicate legacy/safe choices; +- desktop audio is heard by the viewer; +- neither person's call voice loops back through the shared audio; +- no transient or persistent missing-output-port warning appears; +- stopping a share clears the viewer and warning promptly; +- the viewer PixelPass child is reaped within roughly 500 ms after the remote + stream ends; +- leaving the call clears the share and leaves no PeerSpeak-owned PixelPass, + player, GStreamer, capture, or echo-cancellation residue. + +If any row fails, stop release preparation. Save the exact visible text and +relevant logs, fix the defect, run the focused regression gates, commit the +fix, rebuild, and repeat the matrix. + +### 3. Prepare the 0.6.7 source + +After the current build passes: + +- Change `[package].version` in `Cargo.toml` to `0.6.7`. +- Refresh the root PeerSpeak package entry in `Cargo.lock`; inspect the diff and + make sure it changes only as intended. +- Change `MyAppVersion` in `packaging/windows/peerspeak.iss` to `0.6.7`, even + though tomorrow's planned public asset is AppImage-only. This prevents the + next Windows installer from silently retaining `0.6.6`. +- Move the relevant `[Unreleased]` material into a dated `0.6.7` section in + `CHANGELOG.md` and add the `v0.6.7` comparison/release link. +- State that the release is wire-compatible with `0.6.6`; do not claim a + protocol bump. +- Summarize user-visible behavior, especially: + - **All system audio** now shares desktop sound without feeding PeerSpeak's + own call audio back to listeners; + - the safe path is the single normal desktop-audio choice; + - unsafe or incomplete audio-routing states fail closed and surface a useful + warning; + - viewer/share cleanup is prompt when a stream stops or a peer leaves; + - the Linux AppImage bundles the matching PixelPass helper. +- Record the completed two-machine evidence in + `docs/screenshare-audio-exclusion-impl-plan.md`. + +Commit the scoped version/changelog/evidence work. Keep unrelated user changes +out of the commit. + +### 4. Run source gates on the final commit + +Use the pinned Rust toolchain and one build job if disk or linker pressure is +tight: + +```sh +cargo fmt --all -- --check +CARGO_BUILD_JOBS=1 cargo clippy --locked --all-targets -- -D warnings +CARGO_BUILD_JOBS=1 cargo test --locked --all-targets +CARGO_BUILD_JOBS=1 cargo test --locked --doc +cargo deny --locked check +cargo audit +git diff --check +git status --short --branch +``` + +The commands mirror the repository CI, with `--locked` added to compilation +and test gates after the intentional lockfile refresh. A gate that cannot run +must be recorded as unverified; do not silently treat it as passed. + +Also verify the bundled PixelPass source is still exactly the intended clean +commit and run its release diagnostics before packaging: + +```sh +git -C ../pixelpass status --short --branch +git -C ../pixelpass rev-parse --short=8 HEAD +cargo run --manifest-path ../pixelpass/Cargo.toml --locked -- --doctor +``` + +### 5. Build the final AppImage + +Build from the clean, committed PeerSpeak release source and clean PixelPass +source in the Ubuntu 24.04 distrobox described in `packaging/appimage/README.md`. +Keep build caches on `/mnt/superjar` and use one build job if space remains +tight. A representative invocation is: + +```sh +distrobox enter peerspeak-appimage -- env \ + PATH="$HOME/.rustup/toolchains/1.97.1-x86_64-unknown-linux-gnu/bin:$PATH" \ + SYSTEM_DEPS_LIBSPA_INCLUDE=/run/host/usr/include/spa-0.2 \ + SYSTEM_DEPS_LIBPIPEWIRE_INCLUDE=/run/host/usr/include/pipewire-0.3:/run/host/usr/include/spa-0.2 \ + CARGO_BUILD_JOBS=1 \ + PEERSPEAK_APPIMAGE_CACHE=/mnt/superjar/peerspeak-appimage-cache \ + ./packaging/appimage/build-appimage.sh +``` + +The official output should be +`packaging/appimage/peerspeak-0.6.7-x86_64.AppImage`. Do not overwrite the +stamped 0.6.6 field-test artifact until the release is complete and verified. + +### 6. Validate the exact final artifact + +At minimum: + +- record `sha256sum` and create a matching `.sha256` sidecar; +- run `--appimage-extract` into an isolated scratch directory; +- inspect `ldd` for both bundled `usr/bin/peerspeak` and `usr/bin/pixelpass` and + require no `not found` entries; +- inspect RUNPATH/RPATH and confirm the bundle has not captured the host's + graphics, PulseAudio, or GStreamer stack contrary to the thin-AppImage policy; +- run the bundled `pixelpass --capabilities` and confirm desktop-audio exclusion + support is advertised; +- run the bundled `pixelpass --doctor` with a fresh temporary GStreamer registry; +- launch the AppImage with an isolated config/data directory for a GUI smoke; +- verify the first/home screen reads + `PeerSpeak v0.6.7 ()`; +- verify the same version/hash appears in Settings; +- confirm the bundled PixelPass binary corresponds to `ce909afc` (or the exact + newer commit deliberately selected tomorrow). + +Because the final version/evidence commit changes the embedded hash relative to +the current field-test artifact, do one short two-machine confirmation using +the final AppImage: connect, share **All system audio**, confirm desktop sound +and no voice echo/warning, stop the share, and leave cleanly. + +### 7. Publication gate + +Before any external write, present the final facts to the user: + +- final PeerSpeak full and short commit; +- bundled PixelPass full and short commit; +- `v0.6.7` proposed tag target; +- AppImage filename, size, and SHA-256; +- title-screen version/hash observed; +- source, artifact, and two-machine gate results; +- exact release notes/assets to publish. + +Then wait for explicit approval to publish. + +After approval only: + +1. Push `main` without force. +2. Confirm remote `main` resolves to the tested final commit. +3. Create an annotated `v0.6.7` tag on that exact commit and push it. +4. Create the `v0.6.7` GitButter release page from the finalized changelog text. +5. Upload `peerspeak-0.6.7-x86_64.AppImage` and its `.sha256` sidecar. +6. Do not paste or store a GitButter token in the repository, documentation, + shell history, or release artifacts. + +The planned release scope is the Linux x86_64 AppImage only. Do not imply that +a Windows installer, Debian package, or separate PixelPass release exists +unless those artifacts are deliberately added and independently verified. + +### 8. Verify the public release + +Publication is not complete until it is independently read back: + +- confirm GitButter shows the correct release title, tag, notes, and both assets; +- confirm the remote tag and remote `main` point to the expected commit; +- download the public AppImage to a fresh temporary path; +- verify its SHA-256 against the published sidecar and the local final hash; +- extract or run the downloaded copy and repeat the version/hash and bundled + PixelPass diagnostic checks; +- save the final release URL and verification result in the implementation plan + or handoff. + +## Failure and recovery rules + +- A failed gate means no tag and no release—not a waiver. +- Never force-push or move a published tag as an automatic recovery step. +- If the tag is pushed but release creation/upload fails, stop and report the + exact remote state before changing anything. +- Keep failed or candidate artifacts clearly stamped so they cannot be mistaken + for the final asset. +- Remove only exact, rebuildable scratch/extraction directories when reclaiming + disk space; preserve source, user changes, final artifacts, hashes, and field + evidence.