Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 43 additions & 50 deletions docs/reviews/2026-10-30-v0.4.1-release-review.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,40 @@
# v0.4.1 release review

Desktop v0.4.1 is a patch release. It fixes the three observations from the CF-7 close-out's live
runs (#280):
Desktop v0.4.1 is a patch release. It addresses observations from the CF-7 close-out's live runs (#280):

- a turn's files list no longer looks complete when a shell command may have changed files no CLI
named;
- a turn's files list no longer looks complete when a shell command may have changed files no CLI named;
- a thread named after its opening message is cut at a word break with "…", not mid-word.

Val asked on 2026-10-30 for the CF-7 work to land and the next patch release to ship. The iPhone
Companion stays at 0.4.0 (9); nothing in this release changes it.
Val asked on 2026-10-30 for the CF-7 work to land and the next patch release to ship. The iPhone Companion stays at 0.4.0 (9); nothing in this release changes it.

This preparation starts from protected `main` at `9f85d61` (#455), which includes #450 as
`108b814`. It changes only the desktop version and the release records. The tag source is this
PR's squash merge on protected `main`.
The current validation combines protected `main` at `f51ef7e8caa17e79c9029be0d696f5bb40b3dcf2` with #452 head `a76cd3d76ca422d042f6c7b15a8845ce730ac154`. The signed validation commit is `04a5f7d78f9de348b5f9e894697b363cf340ddfa`, tree `bacef42528019ba9179117ab34861b7293dbea30`. PR #452 merged through the protected queue as `6a97d23aaea315b29008890f25dde2d7ea07f1d0`, with that exact tree. Its queue run `41159310757` passed 479 desktop tests (4 skipped) and 7 website tests, with a transcript median of 353.6 ms against the 500 ms limit. The final release tag must name a protected main commit and its artifacts require independent verification.

## Scope since v0.4.0

| Area | Pull requests |
| --- | --- |
| Commands that may have changed unlisted files are named in the context map, footer, Task view and note; opening-message titles cut at a word break (CF-7 follow-ups) | #450 |
| Failed possible-writer commands retain uncertainty; denied commands remain excluded | #453 |
| CI: qualified Ubuntu 24.04 KWallet baseline, desktop runner memory diagnostics; worktree stacked-merge proof | #456, #458, #457 |
| Local child admission refuses enabled or missing subagent settings. Local coding execution stays unadmitted in production | #448 |
| Tests: native Canvas readiness before Escape (the flake in #443's first queue run), secure answer field focus, local auxiliary dispatch boundaries | #446, #455, #447 |
| Records: v0.4.0 publication and site fallback, CF-7 close-out receipt, CF-4 deferral and full-suite record | #445, #443, #444, #449, #454 |

Any other pull request that reaches `main` before this one merges is listed in the publication
section with its merge SHA.
Any other pull request that reaches `main` before this one merges is listed in the publication section with its merge SHA.

## Candidate behavior and compatibility

- **Updates.** v0.4.0 reaches v0.4.1 through the background update: a check downloads and verifies
it without a click, and it installs on **Restart to update** or the next time Modex quits. v0.2.0
and older still need one **Download update** click. Windows and Linux still install by hand.
[Download and restart](../update-recovery.md#download-and-restart).
- **Files touched.** A finished turn that ran a command which may have written files, and is
neither a check nor known to be read-only, now shows that command under the files list. The label
reads "N, maybe more", or "not listed" when no file was named. A turn that only reads, or only
edits through patch tools, looks as before.
[Context map](../task-context.md#context-map).
- **Saved notes.** Notes and task records saved by v0.4.0 reopen unchanged, without the command
list. Nothing is backfilled or inferred. A new save of the same turn writes the list.
- **Thread titles.** Only new threads change. An existing thread keeps its title, and a Retry of a
first turn that carries the old 60-character cut is still renamed once the turn completes.
- **Not changed.** The release workflow, signing scripts, release verifier, native updater verifier
and desktop build hooks are unchanged from v0.4.0, so no rc rehearsal is needed.
- **Updates.** v0.4.0 reaches v0.4.1 through the background update: a check downloads and verifies it without a click, and it installs on **Restart to update** or the next time Modex quits. v0.2.0 and older still need one **Download update** click. Windows and Linux still install by hand. [Download and restart](../update-recovery.md#download-and-restart).
- **Files touched.** A finished turn that ran a command which may have written files, and is neither a check nor known to be read-only, now shows that command under the files list. The label reads "N, maybe more", or "not listed" when no file was named. A turn that only reads, or only edits through patch tools, looks as before. [Context map](../task-context.md#context-map).
- **Saved notes.** Notes and task records saved by v0.4.0 reopen unchanged, without the command list. Nothing is backfilled or inferred. A new save of the same turn writes the list.
- **Thread titles.** Only new threads change. An existing thread keeps its title, and a Retry of a first turn that carries the old 60-character cut is still renamed once the turn completes.
- **Signed rehearsal.** `v0.4.1-rc.1` runs the existing protected Release workflow on the combined validation source to investigate packaged acceptance with a consistent Developer ID signature. Its draft must never be published.

## Local preparation — 2026-10-30

This Mac has only an Apple Development identity, and the 1Password CLI is signed out, so
`scripts/release-mac.sh` cannot sign or notarize here. The local rehearsal is the ad-hoc package
(`pnpm --filter @modex/desktop dist`) with the packaged e2e. Its artifacts must not be published.
Developer ID signing, notarization, packaged acceptance, native updater scenarios and native platform
checks run in the protected `Release` workflow.
This Mac has only an Apple Development identity, and the 1Password CLI is signed out, so `scripts/release-mac.sh` cannot sign or notarize here. The local rehearsal is the ad-hoc package (`pnpm --filter @modex/desktop dist`) with the packaged e2e. Its artifacts must not be published. Developer ID signing, notarization, packaged acceptance, native updater scenarios and native platform checks run in the protected `Release` workflow.

Machine: Apple M5 Max, 18 cores, macOS 27.0.1, Node 24.22.0, pnpm 10.34.5.
Historical preparation machine: Apple M5 Max, 18 cores, macOS 27.0.1, Node 24.22.0, pnpm 10.34.5.

| Check | Source | Result |
| --- | --- | --- |
Expand All @@ -62,28 +44,39 @@ Machine: Apple M5 Max, 18 cores, macOS 27.0.1, Node 24.22.0, pnpm 10.34.5.
| Packaged e2e, `MODEX_PACKAGED_APP=… pnpm test:e2e` | `2ccb808` | exit 1. Desktop 475 passed, 7 skipped, **1 failed**; the site stage did not run. Transcript median 243.5 ms against the approved 500 ms |
| The failed case alone, `--repeat-each 10`, same packaged app | `2ccb808` | 10 passed |

`2ccb808` is this branch before its rebase onto `9f85d61`. The rebase added #447, #448, #454 and
#455 from `main`; their own PR and queue runs cover them, and the protected `Release` workflow runs
the full packaged suite on the exact tag source.
`2ccb808` is the historical #452 preparation before its rebase onto `9f85d61`. The rebase added #447, #448, #454 and #455 from `main`; their own PR and queue runs cover them, and the protected `Release` workflow runs the full packaged suite on the exact tag source.

**The first packaged failure stays on record.** `e2e/attachment-lifecycle.spec.ts:305`, "failed
creation restores files while keeping newer text and other drafts usable", expected the relaunched
composer to read `another draft` and found `yanother draft` at line 362. The extra leading `y` was
never typed by the test, and its source is not explained. The same case passed in the development
Electron run above and in ten unchanged packaged repetitions. This release changes neither the
composer nor drafts, so it is recorded as an unexplained flake, not cleared. The trace and error
context are kept outside the tree under
`~/.claude/task-evidence/release-041-2026-10-30/first-failure/`, with the full logs beside it.
**The first packaged failure stays on record.** `e2e/attachment-lifecycle.spec.ts:305`, "failed creation restores files while keeping newer text and other drafts usable", expected the relaunched composer to read `another draft` and found `yanother draft` at line 362. The extra leading `y` was never typed by the test, and its source is not explained. The same case passed in the development Electron run above and in ten unchanged packaged repetitions. This release changes neither the composer nor drafts, so it is recorded as an unexplained flake, not cleared. The trace and error context are kept outside the tree under `~/.claude/task-evidence/release-041-2026-10-30/first-failure/`, with the full logs beside it.

Packaged selection covers the shared desktop launcher, window lifecycle and Code Review launchers.
Store, standalone desktop-host and fixture launchers keep their development or fixture paths, as
[release-signing.md](../release-signing.md#cutting-a-release) describes. The protected `Release`
workflow runs the full packaged suite again on the Developer ID signed bundle.
Packaged selection covers the shared desktop launcher, window lifecycle and Code Review launchers. Store, standalone desktop-host and fixture launchers keep their development or fixture paths, as [release-signing.md](../release-signing.md#cutting-a-release) describes. The protected `Release` workflow runs the full packaged suite again on the Developer ID signed bundle.

## Combined candidate validation

This section records the combined candidate rehearsal. The final publication source must still be the protected merge, and final-tag artifacts require their own verification.

| Check | Exact source | Result |
| --- | --- | --- |
| Build and unit checks | `04a5f7d` | Exit 0; 2,272 passed, 26 skipped, 0 failed |
| Ad-hoc package | `04a5f7d` | Version 0.4.1; ASAR SHA-256 `422d1056366c508413de4aa6143549312483451580f6bf6a4820b0ee309e8089` |
| Full packaged desktop E2E | `04a5f7d` | Exit 1; 474 passed, 7 skipped, 2 failed, plus 2 worker-teardown errors, in 25.4 minutes. Jev and OpenCoven Settings-click/teardown timeouts preserved |
| Website E2E, run separately | `04a5f7d` | 7 passed in 9.4 seconds |
| Signed CI rehearsal | `04a5f7d` | [Run 41102241411](https://github.com/TypeSafeAI/modex/actions/runs/41102241411): all seven jobs passed, including signed macOS packaged E2E (479 passed, 4 skipped; site 7 passed), three native updater scenarios, Windows and Linux checks, and artifact attachment |

A native sample during the OpenCoven failure showed the main thread waiting in `SecItemCopyMatching` and `SecurityServer::ClientSession::decrypt`. The failure occurred before contrast measurements. Settings invokes routing status, which synchronously checks encryption availability; that is a plausible call path, not a captured JavaScript stack. Whether a permission dialog was visible remains unconfirmed. The source and first failure remain unchanged; subsequent cases progressed in a replacement worker. Neither a later passing case nor the signed rehearsal erases these failures.

Windows and Linux installed-candidate receipts both bind source `04a5f7d78f9de348b5f9e894697b363cf340ddfa`, run `41102241411`, and version `0.4.1`, and report `nativeChecksPassed: true`. Windows verifies NSIS replacement/restart and DPAPI persistence. Linux verifies Debian/AppImage paths, libsecret persistence and basic-text refusal; a separate KWallet5 receipt verifies write, app restart and automatic daemon restart. Both retain `installerAcceptance: pending`: complete CLI/account acceptance remains, and Linux also retains KWallet6 and full graphical login-session acceptance. The private same-source `0.0.0` baseline does not prove historical migration.

The five downloaded RC installers match both `SHA256SUMS.txt` and the manifest. The manifest binds version `0.4.1`, source `04a5f7d78f9de348b5f9e894697b363cf340ddfa` and run `41102241411`. The extracted macOS app passes deep strict signature verification; the app and DMG are accepted by Gatekeeper as Notarized Developer ID and pass stapler validation. The signing team is Soul Protocol LLC (`9LR8Z8UQ9X`). The signed hosted transcript median is 450.5 ms against the 500 ms limit. RC draft `429478340` must never be published.

The exact downloaded signed RC also passes all five local Code Review accessibility cases in 24.3 seconds, including the two themes that stalled with the ad-hoc bundle. This supports a signing-related Keychain explanation but does not establish a definitive root cause; both original traces remain preserved.

The historical attachment-draft failure above remains unexplained. Its case passed in the current full run; this does not establish a root cause or clear the historical failure.

## Release steps still to run

1. CI and the merge queue for this PR (#450 merged as `108b814`).
2. Signed tag `v0.4.1` at this PR's squash SHA with the approved key
(`SHA256:Apqee2EOZLXmfVUUy/QX1QLBn9g10SuzHbK5ARks19E`).
1. Current-head CI and the protected merge queue for the evidence follow-up in #459. Release preparation #452 has merged; it is not superseded or awaiting closure.
2. Signed tag `v0.4.1` at this PR's squash SHA with the approved key (`SHA256:Apqee2EOZLXmfVUUy/QX1QLBn9g10SuzHbK5ARks19E`).
3. The `Release` workflow behind the `release-signing` reviewer.
4. Independent checks of the downloaded draft assets, then publication.

The combined rehearsal evidence is archived outside the repository at `/Users/buns/Documents/Codex/artifacts/modex-land-and-prune/`: `release041-combined-packaged-final.json`, `release041-combined-packaged-results.tar.gz`, `release041-rc1-native-receipts-verified.json`, and `release041-rc1-independent-verification.json`. The original failure traces and log hashes remain in that archive.
3 changes: 1 addition & 2 deletions docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ PR #422's CR-6 review found two blockers: unconfirmed child exit was reported as

The published application source is `2eda138` (v0.4.0). Later source deliveries belong here; the release inventory and its incomplete acceptance gates are recorded separately below.

- **v0.4.1 candidate (2026-10-30).** A patch release of the follow-ups below. See the
[v0.4.1 review](reviews/2026-10-30-v0.4.1-release-review.md).
- **v0.4.1 candidate (2026-10-30).** The combined candidate passed the signed RC workflow (packaged desktop 479 passed, 4 skipped; website 7 passed; native updater, Windows and Linux jobs passed) and independent downloaded-asset verification. The local ad-hoc failures remain recorded. Release preparation #452 merged as `6a97d23`; evidence follow-up #459, the final signed tag workflow and final artifact verification/publication remain pending. See the [v0.4.1 review](reviews/2026-10-30-v0.4.1-release-review.md).
- **CF-7 close-out follow-ups (#280, #450, 2026-10-30).** The three observations from the live close-out
runs are fixed. A turn's files list now names any command that may have changed files no CLI
reported, such as a shell redirect or `perl -pi`, and says "maybe more" or "not listed" instead of
Expand Down
Loading