Skip to content

v0.1.23 — Windows now first-class on CI

Choose a tag to compare

@memtomem memtomem released this 06 May 15:00
2fa84e7

This release lights up Windows as a gating CI platform. Issue #302 ran a multi-week ladder (#303#319, #321) shaking out Windows-specific bugs across the cli, the file-IO utilities, the surfacing feedback store, and ~10 test sites that assumed POSIX-shaped HOME / file-mode / monotonic-clock semantics. With every rung green, #320 PATCHed main's required-status-checks to require lint (windows-latest) + test (windows-latest) — Windows is now first-class supported, not an informational matrix axis. There are no new features; v0.1.23 is the first wheel published with Windows officially under CI gate.

User-visible fixes

  • #303_run_claude_mcp subprocess now pins UTF-8 on Windows. subprocess.run was inheriting the system codepage (cp949 on Korean locale, cp1252 on Western European), so any MCP discovery output containing non-ASCII bytes (server names, descriptions, tool docstrings) decoded as mojibake and mms add --from-clients / mms import either raised UnicodeDecodeError or silently round-tripped garbled strings into the registry. Now pins encoding=\"utf-8\" + errors=\"replace\" explicitly. POSIX behavior unchanged.

  • #307utils/fileio retries os.replace on Windows transient WinError 5. os.replace(tmp, dest) is the atomic-write substrate under every TOML write in mms (registry.toml, import_state.toml, stm_proxy.json, surfacing feedback store, pending store) and the proxy metrics DB rotation. On Windows it intermittently raises PermissionError: [WinError 5] when an antivirus or indexer briefly holds the destination open. The replace path now retries up to 5 times with 10ms exponential backoff (~310ms cap) before re-raising. POSIX hits the success path on the first attempt — zero behavior change.

  • #314mms add --args tokenizer is now backslash-safe on Windows. shlex.split on POSIX consumes \ as escape, which destroys path separators in --args \"C:\\path\\to\\server.exe --port 1234\" (you get C:pathtoserver.exe). The cli now branches on sys.platform == \"win32\" and passes posix=False, matching cmd.exe / PowerShell semantics.

  • #316 — surfacing feedback store recent ordering is deterministic on tied created_at. feedback_store.recent(limit=N) previously relied on insertion order until two rows shared the same created_at Unix timestamp, at which point SQLite's ORDER BY created_at DESC became implementation-defined. POSIX time.time() provides nanosecond resolution; Windows ticks at ~15.6ms, so two writes inside one operation routinely tied. Query now sorts by (created_at DESC, rowid DESC). Surfaced via Windows but is platform-agnostic correctness.

CI / test infra (no behavior change)

  • #304 + #320windows-latest matrix axis added to lint + test workflows, then promoted from informational to required on main.
  • #305, #310set_home test helper that round-trips USERPROFILE (the env var Windows actually consults).
  • #306 — NTFS mode-bit assertions skipif'd on Windows (NTFS doesn't track POSIX mode bits).
  • #309, #312, #313 — unified test platform-detection on sys.platform == \"win32\".
  • #315 — UTF-8 read_text in test_qa_round3 (was using system codepage default).
  • #317, #319 — sleep above Windows monotonic tick floor in pending_store.touch and compression-key TTL tests.
  • #318, #321 — reader thread tolerates PermissionError from #307's retry window + 1ms yield per iteration so the reader doesn't starve the writer's retry budget under Windows' coarser scheduler.

PyPI: https://pypi.org/project/memtomem-stm/0.1.23/
Full diff: v0.1.22...v0.1.23