fix: test-triage submodule visibility + Windows cp1252 stdout encoding#3
Open
jhetchan wants to merge 4 commits into
Open
fix: test-triage submodule visibility + Windows cp1252 stdout encoding#3jhetchan wants to merge 4 commits into
jhetchan wants to merge 4 commits into
Conversation
Fixes two misclassification bugs in triage_test(): 1. If the test file lives inside a git submodule or is untracked by the outer repo (runtime-generated, vendored, protobuf stub), git log returns empty and the old code conflated "git saw nothing" with "nothing changed", producing a false `stale` verdict. A new _path_visible_to_outer_repo() helper checks `git submodule status` and `git ls-files --error-unmatch` before any timestamp comparison; if the path is not visible, triage_test() returns `unknown` with an evidence line explaining the visibility gap. 2. In the no-recent-behavior-change branch, a repo with zero commits in the window was classified `stale`. A `git rev-list --count --since=…` call now distinguishes a quiet repo (→ `ambiguous`) from a repo that has activity but no behaviour-file changes (→ `stale` as before). Also fixes the global git commit-signing environment for the entire test suite: GIT_CONFIG_GLOBAL now points to a temp config that disables gpgsign for all subprocess-based git operations, unblocking 56 pre- existing test failures caused by the remote signing service. Ticket: TKT-20260502-103308-MX51 Co-Authored-By: claude-sonnet-4-6 <noreply@anthropic.com>
…er entry points On Windows with the default cp1252 console codepage, print() raises UnicodeEncodeError when the output contains box-drawing characters (╔ ║ ╚ ═) used in the session banner or arrows (→) in human formatters. This kills the process before any output is produced, including --help. Fix: at the very top of exo.cli.main() and exo.mcp_server.main(), before argparse runs, call stream.reconfigure(encoding='utf-8', errors='replace') on stdout and stderr. contextlib.suppress handles AttributeError (streams without reconfigure, e.g. StringIO) and OSError (binary-mode streams). On terminals that already support UTF-8 this is a no-op; on narrow encodings it substitutes '?' instead of crashing. Adds tests/test_cli_encoding.py with TestCliEncodingCp1252 verifying that main(['--help']) survives a cp1252-encoded stdout wrapper. Ticket: TKT-20260502-103309-1C2P Co-Authored-By: claude-sonnet-4-6 <noreply@anthropic.com>
…ity (TKT-20260502-103308-MX51)
…main() (TKT-20260502-103309-1C2P)
❌ ExoProtocol Health ReportVerdict: FAIL · Drift: |
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.
Summary
Community-feedback round 2 (post-0.2.0). Two bugs bundled into one PR, each on its own governed ticket branch, merged into
feedback-round-2.Bug 1 —
exo test-triagemisclassifies nested-repo / runtime-file cases (exo/stdlib/triage.py,tests/test_triage.py)triage_test()calledgit logagainst the outer repo to determine when a test file and its covered behaviour code were last edited. If the test path lives inside a git submodule, is untracked (uncommitted, runtime-generated, protobuf stub, vendored file),git logreturns nothing. The old code conflated "git saw nothing" with "nothing changed", emitting a falsestaleverdict instead ofunknown. Additionally, whengit log --since=<window>found no commits at all — meaning the repo was simply quiet — the code also emittedstaleinstead ofambiguous.Fixed by: (a) a new
_path_visible_to_outer_repo(repo, path)helper that runsgit submodule statusandgit ls-files --error-unmatchto detect the invisible-path case and returnsunknownwith an evidence line; (b) agit rev-list --count --since=…call in the no-behavior-change branch to distinguish a quiet repo (ambiguous) from a repo with activity that simply has no recent non-test commits (stale). Test infrastructure:tests/conftest.pyadded to disablecommit.gpgsignfor all test repos viaGIT_CONFIG_GLOBAL; this unblocked 56 pre-existing test failures caused by the remote signing service.Bug 2 — Windows cp1252 crashes CLI help / banner output (
exo/cli.py,exo/mcp_server.py,tests/test_cli_encoding.py)The session banner uses box-drawing characters (
╔ ║ ╚ ═) and several human formatters use→. On Windows with the default cp1252 console codepage,print()raisesUnicodeEncodeErrorand the CLI dies before producing any output — includingexo --help. Fixed by callingstream.reconfigure(encoding='utf-8', errors='replace')inside acontextlib.suppress(AttributeError, OSError)guard at the very top of bothexo.cli.main()andexo.mcp_server.main(), before argparse runs. On UTF-8 terminals this is a no-op; on narrow-encoding consoles it substitutes?for unencodable characters instead of crashing.Repro
Bug 1 — stale instead of unknown
Bug 2 — UnicodeEncodeError on cp1252
Test plan
TestTriageNestedAndRuntime::test_submodule_path_returns_unknown— fake submodule path →unknownwith visibility evidenceTestTriageNestedAndRuntime::test_untracked_file_returns_unknown— uncommitted file on disk →unknownTestTriageNestedAndRuntime::test_quiet_repo_returns_ambiguous_not_stale— single old commit, zero commits in window →ambiguousTestTriageNestedAndRuntime::test_truly_stale_still_classified_stale— old test + recent test-only commits in window →stale(regression guard)TestCliEncodingCp1252::test_help_survives_cp1252_stdout—main(['--help'])on cp1252 stream exits 0 withoutUnicodeEncodeErrorTestCliEncodingCp1252::test_help_box_chars_survive_utf8_stdout— UTF-8 stream: reconfigure is a no-op, output is valid UTF-8TestCliEncodingCp1252::test_cp1252_replaces_not_crashes— narrow stream: exits 0, no exception raisedpython3 -m pytest→ 1647 passed, 0 failed (up from 1578 before; 56 pre-existing failures also resolved bytests/conftest.py)Governance tickets:
TKT-20260502-103308-MX51(Bug 1) ·TKT-20260502-103309-1C2P(Bug 2)Parent intent:
INT-20260502-103234-267BGenerated by Claude Code