Skip to content
gwmgwmgwmv1.10.0

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.

  • Dropped the unsound, unmaintained serde_yml dependency (#340, RUSTSEC-2025-0068). The issue-form front-matter parser now uses the maintained serde_yaml_ng fork; bumped anyhow to 1.0.103 to clear RUSTSEC-2026-0190. The CI cargo audit job is now blocking (--deny warnings, continue-on-error removed) so warning-class advisories - unmaintained / unsound / yanked - fail the build instead of being silently ignored.

  • Hardened the gwm daemon unix socket (#341). The socket is now chmod’d owner-only (0600), and on the world-writable /tmp last-resort fallback it is nested in a per-user owner-only gwm-<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 for connect(2). The common $XDG_RUNTIME_DIR / $TMPDIR paths (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 on ServeOptions). Also fixed a bug where a transient run_list git error pushed a phantom-empty worktrees.changed to subscribe clients (they flickered “everything vanished”, then self-healed next poll) - transient errors are now swallowed instead of streamed as an empty snapshot.

  • 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 inside terminal.draw() on every selection / mode change, stalling j / k on a large repo or a slow filesystem; workspace-mode auto-refresh re-listed every repo synchronously too. Both now ride the TaskRunner (#231): the render path only reads the last-known payload - showing a muted loading… 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 held j coalesces 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 --bootstrap now goes through the TOFU trust gate (#338). Re-running a repo’s [[bootstrap.command]] shell on undo previously bypassed trust_or_prompt entirely - cmd_undo called bootstrap::run directly with no trust check, so an untrusted .gwm.toml could run shell commands unprompted. Undo now mediates the bootstrap re-run through the same gate as create / review --bootstrap / bootstrap, honouring --allow-bootstrap / GWM_ALLOW_BOOTSTRAP / --deny-bootstrap.

  • gwm clean --workspace no longer panics on the empty-workspace invariant (#344). When nothing participated and no repo validated the --profile (nor reported an error), the workspace-clean handler expect-panicked on an invariant open_workspace_repos already enforces; it now returns a GwmError defensively instead of unwinding.

  • 1.0.x hardening backlog (#344). Froze the gwm exec / gwm clean flag surface (--profile / --jobs / --yes / the global --workspace) with a contract_tests canary - the subcommand-name canary (help_prints_subcommands) does not see flags. Reconciled the MSRV enforcement story between Cargo.toml and the stability doc: CI’s clippy job catches an accidental std-API use above the 1.86 floor (clippy::incompatible_msrv under -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 ungated clean::scan_worktree / delete_reclaim convention (feed them only a scan_worktree_safe reclaim) 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 (the v1.0.0 tag predated the gwm → gwm-cli rename, so crates.io gwm-cli@1.0.0 isn’t reachable from the tag).

  • Scoped the published library API as an internal test seam (#342). The gwm-cli crate ships a [lib] target only so the binary and the tests/ suite can share one module tree - cargo treats that pub surface (~460 items) as a de-facto SemVer contract. Rather than gate it with cargo-semver-checks (which would force a major bump on every routine internal refactor), the lib is now #![doc(hidden)] (nothing is advertised on docs.rs) and explicitly disclaimed: the crate-level docs and docs/6.development/3.stability.md state it is not a public API and carries no SemVer guarantee. issue_templates - the one module no integration test imports - is now pub(crate).

  • Finished the 1.0.0 documentation sync (#339). The in-repo docs/ tree and skills/SKILL.md still described the v0.10.0 line: fixed the install command (cargo binstall gwm → cargo binstall gwm-cli; the bare gwm crate on crates.io is an unrelated project), added a cargo install gwm-cli crates.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 (75 tests/*.rs files, 1902 #[test] markers). EN/FR parity preserved.