Release v0.69.2 - #3590
Merged
Merged
Conversation
…ds it SignPath names its download after the GitHub artifact, which `archive: false` already makes `worktrunk-x86_64-pc-windows-msvc.zip` — so writing it into `target/distrib` landed it at `…zip.zip` beside the untouched unsigned build. The checksum step and the release upload both kept reading the original, and v0.69.1 shipped an unsigned binary under a green run and a Completed signing request. The download now goes to a scratch directory and whatever single file lands there replaces the built zip, so SignPath's naming doesn't matter. The replacement is verified before it overwrites: an unsigned release is tolerable while the certificate is a self-signed test one, a corrupt one never is. A final step then reads the shipped zip and reports any executable without a certificate table — the failure this fixes was invisible from the logs, and signing stays continue-on-error, so nothing else would catch it. Rehearsed against the published v0.69.1 zip on a Windows runner before landing: sign, verify, replace, checksum, report — `wt.exe` and `git-wt.exe` both signed, checksum matching the shipped bytes.
max-sixty
force-pushed
the
signpath-code-signing
branch
from
July 25, 2026 01:43
c439e18 to
f741496
Compare
max-sixty
force-pushed
the
signpath-code-signing
branch
from
July 25, 2026 01:44
f741496 to
7369a75
Compare
worktrunk-bot
approved these changes
Jul 25, 2026
max-sixty
added a commit
that referenced
this pull request
Jul 25, 2026
Eleven commits landed on `main` while #3590 sat in CI, so they ship in v0.69.2 with no changelog entry. Most are user-facing, and three are data-loss fixes — exactly the drift the release skill's step-12 check exists to catch. The tag is held until this lands. Entries added, most-impactful first: - **#3589** — two ways shell integration deleted user data on a substring guess: an rc line that only *quotes* the init command, and a user's own `conf.d/wt.fish` deleted outright by `install`'s legacy cleanup. Plus forge detection moving from `host.contains("github")` to label-wise matching. - **#3585 + #3591** — truncate-in-place rc writes replaced by write-temp-then-rename, then generalized to every user-file write. - **#3578** — despite its `docs(step):` subject this carries three behavior fixes, including `wt step push` succeeding mid-rebase and moving the target branch onto a half-replayed history. - **#3588 + #3587** — conflict markers can no longer reach a commit via `wt step relocate --commit`, and `wt merge` refuses in its own name. - **#3554** — OpenCode marker writes could land in another session's worktree (thanks @4i3n6, who both reported and fixed it). Not documented, per convention: #3574 (doc comments only, no runtime or docs-site surface) and the three dependency bumps. Also corrects `.github/CLAUDE.md`, which lists three required status checks; there are four — `fast-checks` is required too, confirmed against the branch-protection API. Entries verified against the diffs by subagent. Two corrections came back and are folded in: the #3589 entry originally promised "two of them deleted" and described only one, and the #3578 entry mis-quoted the success line as `✓ Pushed to main` when it carries a commit count. > _This was written by Claude Code on behalf of max_
max-sixty
added a commit
that referenced
this pull request
Jul 25, 2026
…3593) Follow-up to #3590, now that v0.69.2 has shipped a signed Windows binary — verified against the published asset rather than the logs: ``` git-wt.exe: certificate table 8480 bytes wt.exe: certificate table 8472 bytes c4343fb5…1a43 *worktrunk-x86_64-pc-windows-msvc.zip (published .sha256 matches) ``` Comments only; no behavior change. The signing comments were written while the mechanism was still being guessed at, so they carried the failed attempts — a ten-line account of the zip-of-a-zip failure, a six-line account of the `…zip.zip` collision. The path is proven and the workflow now verifies itself, so what a reader needs is the current mechanism. Trimmed to that. One thing added rather than removed. `Recompute checksum` sits between two `continue-on-error` steps and looks like it should fold into the replace step above it. It must not: the signing steps are tolerant because publishing can't depend on a self-signed test certificate, while a checksum that doesn't match the shipped zip has to fail the release. That asymmetry is invisible in the YAML, so it's now stated — the next person to simplify this shouldn't have to rediscover it. > _This was written by Claude Code on behalf of max_
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cuts v0.69.2, and fixes the Windows code-signing path it depends on.
The signing fix
v0.69.1 shipped an unsigned
wt.exeunder a green run and a Completed SignPath signing request.archive: false(#3566) had already made the GitHub artifact nameworktrunk-x86_64-pc-windows-msvc.zip, and SignPath names its download after the artifact — so withoutput-artifact-directory: target/distribthe signed zip landed atworktrunk-x86_64-pc-windows-msvc.zip.zip, beside the untouched unsigned build. The checksum step and the release upload both kept reading the original. Confirmed by parsing the published asset's PE certificate table:size=0.The download now goes to a scratch directory and whatever single file lands there replaces the built zip, so SignPath's naming isn't load-bearing.
Verification, because this failure is invisible
Signing is
continue-on-errorby design (self-signed test certificate pending SignPath's OSS review), so nothing in the logs distinguishes "signed" from "silently unsigned" — which is how it slipped through twice, two different ways..github/verify-windows-signature.pyreads the zip's PE certificate tables directly, and runs at two points with distinct jobs:Rehearsed before landing
The signing path only runs on a tag, so each question about it used to cost a release. This chain was instead run on a Windows runner against the already-published v0.69.1 zip (identical bytes, no build):
That also settled the open question behind #3556: SignPath returns the signed zip itself, not a wrapper, so
skip-decompress: trueis correct — the extract mode does explode it into loose files.Release contents
wt remove's fsmonitor sweep (#3581), the troubleshooting doc trim, and this fix. The two refactors in range (#3582, #3584) are behavior-preserving and omitted per convention.Local gate green (4547 passed). Changelog entries verified against the diffs by subagent; two claims corrected (the doc entry's rationale, and an overclaim attributing v0.69.0's unsigned binary to this bug rather than the separate upload failure #3566 fixed). Data-loss surface reviewed across the cumulative diff.