v1.0.1
First patch on the 1.0 line - a hardening and housekeeping pass, no new
features and no breaking changes. Two security fixes lead it: the unsound,
unmaintained serde_yml dependency is dropped (RUSTSEC-2025-0068) and the
cargo audit CI job is now blocking, and the gwm daemon unix socket is
locked down (owner-only perms, an isolated /tmp fallback, and request-path
DoS guards). The rest is a perf win (the last synchronous git subprocesses
move off the TUI render path), two correctness fixes (gwm undo --bootstrap
now honours the TOFU trust gate; gwm clean --workspace fails loud instead of
panicking), and internal / documentation hardening from the 1.0.0 ultra-audit.
The machine contracts frozen in 1.0.0 are unchanged.
Security
Section titled “Security”-
Dropped the unsound, unmaintained
serde_ymldependency (#340, RUSTSEC-2025-0068). The issue-form front-matter parser now uses the maintainedserde_yaml_ngfork; bumpedanyhowto 1.0.103 to clear RUSTSEC-2026-0190. The CIcargo auditjob is now blocking (--deny warnings,continue-on-errorremoved) so warning-class advisories - unmaintained / unsound / yanked - fail the build instead of being silently ignored. -
Hardened the
gwm daemonunix socket (#341). The socket is now chmod’d owner-only (0600), and on the world-writable/tmplast-resort fallback it is nested in a per-user owner-onlygwm-<uid>/directory - so another local user can no longer connect and read the worktree list even on platforms that don’t enforce socket-file perms forconnect(2). The common$XDG_RUNTIME_DIR/$TMPDIRpaths (already private) are unchanged. Added DoS guards on the request/response path: a per-line length cap, an idle read timeout, and a concurrent-connection cap (all configurable onServeOptions). Also fixed a bug where a transientrun_listgit error pushed a phantom-emptyworktrees.changedtosubscribeclients (they flickered “everything vanished”, then self-healed next poll) - transient errors are now swallowed instead of streamed as an empty snapshot.
Performance
Section titled “Performance”- Moved the last synchronous git subprocesses off the TUI render path
(#343). The details sidebar rebuilt its git-backed sections
(
git_diff_stat_vs_base,git status --porcelain -z,git log,git stash list) synchronously insideterminal.draw()on every selection / mode change, stallingj/kon a large repo or a slow filesystem; workspace-mode auto-refresh re-listed every repo synchronously too. Both now ride theTaskRunner(#231): the render path only reads the last-known payload - showing a mutedloading…placeholder while a rebuild is in flight (the identity card still renders instantly) - and a coalesced worker rebuilds it off-thread, keyed to the current selection. A heldjcoalesces onto the single in-flight worker instead of spawning a thread per row, and the poll cadence tightens to 50 ms while a task is loading so the preview lands fast.
-
gwm undo --bootstrapnow goes through the TOFU trust gate (#338). Re-running a repo’s[[bootstrap.command]]shell on undo previously bypassedtrust_or_promptentirely -cmd_undocalledbootstrap::rundirectly with no trust check, so an untrusted.gwm.tomlcould run shell commands unprompted. Undo now mediates the bootstrap re-run through the same gate ascreate/review --bootstrap/bootstrap, honouring--allow-bootstrap/GWM_ALLOW_BOOTSTRAP/--deny-bootstrap. -
gwm clean --workspaceno longer panics on the empty-workspace invariant (#344). When nothing participated and no repo validated the--profile(nor reported an error), the workspace-clean handlerexpect-panicked on an invariantopen_workspace_reposalready enforces; it now returns aGwmErrordefensively instead of unwinding.
Changed
Section titled “Changed”-
1.0.x hardening backlog (#344). Froze the
gwm exec/gwm cleanflag surface (--profile/--jobs/--yes/ the global--workspace) with acontract_testscanary - the subcommand-name canary (help_prints_subcommands) does not see flags. Reconciled the MSRV enforcement story betweenCargo.tomland the stability doc: CI’s clippy job catches an accidental std-API use above the 1.86 floor (clippy::incompatible_msrvunder-D warnings), but not language/edition features or a dependency raising its own floor - those stay a local pre-bump check (cargo msrv verify). Documented the ungatedclean::scan_worktree/delete_reclaimconvention (feed them only ascan_worktree_safereclaim) and their narrow TOCTOU window; justified the remaining#[allow(clippy::too_many_arguments)]; and added a release-process note to finalise the crate identity before tagging (thev1.0.0tag predated thegwm→gwm-clirename, so crates.iogwm-cli@1.0.0isn’t reachable from the tag). -
Scoped the published library API as an internal test seam (#342). The
gwm-clicrate ships a[lib]target only so the binary and thetests/suite can share one module tree - cargo treats thatpubsurface (~460 items) as a de-facto SemVer contract. Rather than gate it withcargo-semver-checks(which would force a major bump on every routine internal refactor), the lib is now# and explicitly disclaimed: the crate-level docs anddocs/6.development/3.stability.mdstate it is not a public API and carries no SemVer guarantee.issue_templates- the one module no integration test imports - is nowpub(crate).
Documentation
Section titled “Documentation”- Finished the 1.0.0 documentation sync (#339). The in-repo
docs/tree andskills/SKILL.mdstill described the v0.10.0 line: fixed the install command (cargo binstall gwm→cargo binstall gwm-cli; the baregwmcrate on crates.io is an unrelated project), added acargo install gwm-clicrates.io channel to the install page, ported the site roadmap to v1.0.0 (with the 1.0 lot #317–#334), and refreshed the test counters to the real 1.0.0 figures (75tests/*.rsfiles, 1902#[test]markers). EN/FR parity preserved.