Repository navigation
Conversation
A full run on Windows 11 failed 31 tests, almost all because a fixture assumed POSIX behaviour or read the developer's own Git configuration rather than because Strix misbehaved. That noise hides real regressions. - Resolve git with `shutil.which` instead of `/usr/bin/env git`, and skip the module when no git is present. This single line accounted for 19 of the 31 failures. - Isolate every git subprocess from `GIT_CONFIG_GLOBAL`/`GIT_CONFIG_SYSTEM` and supply a commit identity, so a global `core.excludesFile`, `commit.gpgSign`, or `core.hooksPath` cannot change what a test sees. - Create control-character filenames through a fixture that skips where the filesystem rejects them, instead of failing to build the fixture. - Choose the protected system directory for the platform in the mount policy test. `check_mountable_dir` already handles both families, so on Windows this now exercises the real policy instead of failing early. - Assert secret-file permissions through a fixture that keeps the POSIX 0o600 check exact and, on Windows, skips with the reason stated rather than weakening the assertion. The device-identity test is split so its identity contract still runs everywhere. - Pin mypy to `platform = "linux"` so type checking resolves the same APIs as CI and the container target. This removes the six `fcntl.flock`/`os.getuid`/`os.getgid` attribute errors reported on Windows without adding ignores that `warn_unused_ignores` would then flag on Linux. Windows now reports 12 failures, all owned elsewhere: usestrix#1258 (7-8, intermittent), usestrix#648/usestrix#652, usestrix#1288, and usestrix#1285. Refs usestrix#1259 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
| except OSError as exc: # pragma: no cover - platform dependent | ||
| pytest.skip(f"this filesystem rejects control characters in filenames: {exc}") |
There was a problem hiding this comment.
This catches every OSError, not only the invalid-filename error expected on Windows. If writing fails because the temporary directory is unwritable, storage is exhausted, or another filesystem problem occurs, these security-focused tests will be reported as skipped instead of exposing the failure. Restrict the skip to the expected invalid-name error or explicitly to Windows.
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/conftest.py
Line: 105-106
Comment:
**Unrelated errors become skips**
This catches every `OSError`, not only the invalid-filename error expected on Windows. If writing fails because the temporary directory is unwritable, storage is exhausted, or another filesystem problem occurs, these security-focused tests will be reported as skipped instead of exposing the failure. Restrict the skip to the expected invalid-name error or explicitly to Windows.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
|
||
| [tool.mypy] | ||
| python_version = "3.12" | ||
| platform = "linux" |
There was a problem hiding this comment.
Platform branches lose type coverage
Forcing mypy to analyze only Linux prevents it from checking supported Windows and macOS branches under their actual platforms. Platform-specific code such as Windows event-loop setup, Windows TUI launching, and non-Windows restart behavior can therefore accumulate type errors without mypy detecting them. Preserve a platform-specific check or run mypy for each supported target.
Prompt To Fix With AI
This is a comment left during a code review.
Path: pyproject.toml
Line: 107
Comment:
**Platform branches lose type coverage**
Forcing mypy to analyze only Linux prevents it from checking supported Windows and macOS branches under their actual platforms. Platform-specific code such as Windows event-loop setup, Windows TUI launching, and non-Windows restart behavior can therefore accumulate type errors without mypy detecting them. Preserve a platform-specific check or run mypy for each supported target.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| # and `_FORBIDDEN_WINDOWS_TREE_NAMES`); only the fixture was Unix-only. | ||
| candidates = ( | ||
| [Path(Path.cwd().anchor) / "Windows"] if os.name == "nt" else [Path("/etc"), Path("/usr")] | ||
| ) |
There was a problem hiding this comment.
Alternate drives skip coverage
If the checkout is on a different drive from the Windows installation, deriving the protected directory from Path.cwd().anchor looks for paths such as D:\Windows instead of the actual C:\Windows. When that directory is absent, the test skips rather than exercising the Windows mount-policy branch. Use the actual Windows system root while retaining the existence check.
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/test_local_sources.py
Line: 184-187
Comment:
**Alternate drives skip coverage**
If the checkout is on a different drive from the Windows installation, deriving the protected directory from `Path.cwd().anchor` looks for paths such as `D:\Windows` instead of the actual `C:\Windows`. When that directory is absent, the test skips rather than exercising the Windows mount-policy branch. Use the actual Windows system root while retaining the existence check.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Review feedback, both valid. The control-character fixture caught every OSError, so an unwritable temp directory or a full disk would have reported these security tests as skipped instead of failing. It now skips only for errors that mean the name itself is unrepresentable (EINVAL, EILSEQ, ENAMETOOLONG) and re-raises everything else. The mount-policy test derived the protected directory from the checkout's drive, so a repo cloned to D: would look for D:\Windows, miss, and skip the branch the test exists to cover. Ask Windows where it is installed via SYSTEMROOT instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Two of the three were valid and are fixed in 1. Unrelated errors become skips — valid, fixedGood catch, and the failure mode is exactly the bad one: a security test silently reporting "skipped" because the disk filled up. It now skips only for errors meaning the name is unrepresentable and re-raises everything else: I used the errno set rather than 2. Alternate drives skip coverage — valid, fixedCorrect, and it would have silently reduced coverage rather than erroring. Now reads 3. Platform branches lose type coverage — I don't think this holdsThe premise is that Without this setting, mypy uses the platform it is running on. CI runs Linux, so Concretely, Where you're right is that no configuration checks the Windows branches. The fix for that is your second suggestion, "run mypy for each supported target": a CI matrix over I already flagged this tradeoff for a maintainer in the PR description and I'm happy to go whichever way they prefer. Leaving as-is for now. Full suite on Windows after these changes: 9 failures, down from 31 on |
`platform = "linux"` was a workaround for six Windows-only attribute errors on `fcntl` and `os.getuid`. Review pushed back, correctly: it makes local runs deterministic but checks no platform-specific branch under its own platform. usestrix#1301 fixes those six at the source and adds a workflow running mypy under --platform linux, darwin and win32, so the pin is no longer needed. Removing it here leaves this PR scoped to test assumptions and lets the two merge in either order. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Correcting something I said in my previous reply, because it was wrong in a way that matters for this decision. I wrote that "CI runs Linux, so The conclusion survives (nothing gates a merge on type checking, so nothing was checking Windows branches), but the reason I gave was not the real one, and "there is no type-check CI" is a more useful fact for a maintainer than "CI runs Linux". That also makes the reviewer's underlying point stronger than I credited, so I've fixed it properly in #1301: a
With those fixed at the source, @greptile-apps your second suggestion — "run mypy for each supported target" — was the right call. The first one ("preserve a platform-specific check") is still not viable here: |
|
Thanks for checking and correcting the earlier explanation. You're right: the absence of mypy from CI is the key coverage gap, and the multi-platform workflow in #1301 addresses the underlying concern properly. Dropping Tip: You can customize Greptile's behavior for this repo with |
Refs #1259
Before / after
Full suite on Windows 11, Python 3.12,
main@95e085e:Every one of the remaining 12 is owned by another issue, so none of them is a Unix assumption:
test_cloud_source_upload/test_cloud_cli_runtimearchive repacktest_config_loader::test_persist_current_sets_0600_modetest_pricing::test_resolves_common_bare_model_namestest_workspace_filesdrive lettersChanges
/usr/bin/env git→shutil.which("git")— one line intests/test_threat_model_tool.pyaccounted for 19 of the 31 failures.shutil.which("git")was already the idiom intests/test_cloud_source_upload.py:46, so this aligns with the suite rather than introducing a pattern. The module skips if git is absent.Git config isolation — a new autouse fixture points
GIT_CONFIG_GLOBAL/GIT_CONFIG_SYSTEMat a non-existent path and supplies a commit identity. Tests that build a throwaway repo were reading the developer's own config underneath, so a globalcore.excludesFilesilently drops files from source selection, andcommit.gpgSignorcore.hooksPathcan fail the commit outright. This is machine-independence, not just Windows.Control-character filenames — two tests prove Strix never echoes an escape sequence back to the terminal, and needed a hostile filename on disk to do it. Windows rejects those characters outright, so the fixture could not even be built and the test failed in setup. A
write_control_character_filefixture now skips with the realOSErrorwhen the filesystem refuses the name. The POSIX contract keeps being exercised; Windows stops reporting a product failure it does not have.Mount policy —
test_infer_target_type_applies_the_mount_policyhardcoded/etc, which does not exist on Windows, so it failed at target validation before reaching the policy.check_mountable_diralready handles both families (_FORBIDDEN_MOUNT_TREESand_FORBIDDEN_WINDOWS_TREE_NAMES) — only the fixture was Unix-only. It now picks the platform's protected directory, following the existing idiom intest_check_mountable_dir_rejects_system_subdirsa few lines above. This one now genuinely passes on Windows rather than skipping, exercising the Windows branch of the policy for the first time.Secret-file permissions — Windows does not implement POSIX mode bits:
os.opencollapses the mode to a single read-only flag, sostat()reports0o666regardless and confidentiality comes from the user-profile ACL. Anassert_secret_file_permissionsfixture keeps the POSIX assertion exact and, on Windows, skips with that reason spelled out — deliberately not weakened into something that passes everywhere while checking nothing.test_cli_device_identity_is_stable_and_privacy_safebundled a permission check with its identity assertions, so the permission part is split into its own test and the identity contract keeps running on every platform.mypy
platform = "linux"— removes the sixfcntl.flock/os.getuid/os.getgidattribute errors seen when type checking on Windows. The alternative,# type: ignore[attr-defined], would be flagged as unused on Linux underwarn_unused_ignores = true. Pinning the platform makes local type checking resolve the same APIs as CI and the Linux container target, instead of varying per developer machine.Verification
All numbers above are from real runs on Windows 11, not inferred.
ruff checkandruff format --checkclean on every touched file. (ruff checkreports 26 errors across the repo both with and without this branch — pre-existing, from a newer local ruff than the pin.)mypy strixon Windows: 8 errors before, 2 after. Both remaining aretypes-requestsarg-typecomplaints that appear because that stub package is not installed in my venv — unrelated to this change and not platform-specific.Not included
The
test_cloud_source_uploadfailures are not a test assumption, so I left them to #1258 rather than papering over them with a skip. I instrumented the guard to confirm the mechanism — the diff is almost alwaysst_ctime_nsalone, drifting 1–30 ms between the selectionos.stat(path)and the lateros.fstat(fd)with no write in between. I've posted the evidence on #1258.🤖 Generated with Claude Code