Skip to content

Tighten the CLI Usage Gate, Share Its Status Parser, and Fix the Windows Decode Probe - #2956

Merged
ptr727 merged 3 commits into
developfrom
feature/cli-gate-followups
Oct 13, 2026
Merged

ptr727 merged 3 commits into
developfrom
feature/cli-gate-followups

Conversation

@ptr727

@ptr727 ptr727 commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Summary

Four follow-ups to the CLI usage gate, for #2946, #2947, #2948, and #2949.

  • Decode Child Output as UTF-8 in the Test That Fails on Windows' Code Page #2946. The Windows reader-thread UnicodeDecodeError comes from locale_patch_bites() in tests/test_prose_lint.py, the probe whose call deliberately names no encoding, so adding encoding= was not the fix. On Windows communicate() decodes in a reader thread, so the error never reached the probe's except. The probe returned False, and every TestGitOutputDecodesAsUtf8 case skipped on the one platform the class exists for. The probe now records the reader thread's exception through threading.excepthook, which also stops the unhandled traceback. Every other text-mode call under tests/ already names an encoding, which tests/test_tooling_encoding.py enforces.
  • Share One Porcelain Status Parser Between carry.py and the CLI Usage Gate #2947. scripts/carry.py gains git_status_records(root, *, ignored=False), which returns (status, path) pairs and refuses malformed or incomplete records as before. git_status_paths() is now a projection of it, and the CLI gate's tree_state() calls it. tests/test_carry.py covers status pairing, the ignored option, rename order, and each refusal.
  • Hold an Unlisted CLI That Needs an Argument to Refusing the Unknown Flag Itself #2948. tests/test_cli_usage.py declares NO_REQUIRED_ARGUMENT. Each member was checked by reading its parser. The gate fails an entry point declared nowhere, and also a stale or duplicate declaration. catalog/snippets/hub-fetch-run.py takes a required hub path but refuses a leading flag before reading it, so it fits neither set. It is declared in a one-entry REFUSES_A_LEADING_FLAG with that reason. The module docstring now describes the declarations.
  • State the CLI Usage Gate's Stricter Reading in CODESTYLE's Argument Rule #2949. CODESTYLE.md "Command-Line Arguments" states the gate's requirements: the same help text for -h and --help on stdout, opening on a usage line that names the script, and a refusal that names the argument as an unknown or unrecognized option, argument, flag, or parameter. PowerShell's own binder refusal also counts. The gate's REFUSED_AS_OPTION now accepts exactly that set. Before this change it accepted only "unrecognized argument/option". The python-codestyle and shell-codestyle Skills are regenerated.

Verification

  • Ran the full local gate set from OPERATIONS.md "Local Verification", including the unit suite (2720 tests OK), spec/validate.py, build_dist.py --check, repo_gate.py --check eol and --check eol-coverage, both prose invocations, a --diff run with and without sentence-length, and docker_lint.py. All passed.
  • Ran two local-strict-review passes. The first raised five findings, all fixed in 1a8640c. The second raised none.
  • The Windows probe path was exercised on Linux by simulating the reader-thread exception. The Windows CI leg is the real check.

🤖 Generated with Claude Code

ptr727 and others added 2 commits October 13, 2026 13:42
Declare every entry point the gate runs without arguments in
NO_REQUIRED_ARGUMENT, so an entry point declared nowhere fails instead of
passing on a warning followed by a missing-argument stop. hub-fetch-run.py
takes a required hub path but reads a leading flag first, so it is declared
in REFUSES_A_LEADING_FLAG.

Move the porcelain status parsing tree_state() carried into carry.py as
git_status_records(), with an ignored option and (status, path) pairs, and
keep git_status_paths() as a projection of it.

State the gate's three stricter requirements in CODESTYLE.md's argument rule
and regenerate the Skills that include it.

Let the cp1252 probe in test_prose_lint.py see a decode error raised in
subprocess's Windows reader thread, which it missed, skipping the whole
UTF-8 decode class on Windows and printing an unhandled thread traceback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings October 13, 2026 21:05
@ptr727

ptr727 commented Oct 13, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 1a8640c3b9496512dc100679f6dc8ca10052a5b6, the content this pull request carries at that commit against develop, and it recorded 0 findings.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9335caa3-e081-4430-b077-cd79b7255963
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.02%. Comparing base (ac78916) to head (4851b53).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2956      +/-   ##
===========================================
+ Coverage    59.96%   60.02%   +0.06%     
===========================================
  Files           17       17              
  Lines         8778     8784       +6     
===========================================
+ Hits          5264     5273       +9     
+ Misses        3514     3511       -3     
Flag Coverage Δ
python-3.13 60.02% <100.00%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The CLI gate can accept a refusal that names a different flag instead of the one it passed.

1 open finding
What changed in this PR

This PR tightens the CLI usage gate and its documented contract, shares Git status parsing with the gate, and fixes the Windows decode probe.

Changes:

  • Declare how each CLI entry point handles an unknown flag.
  • Share status parsing between carry.py and the gate, with parser tests.
  • Update the decode probe and regenerate the CLI rules in the distributed Skills.
File Description
tests/​test_prose_lint.py Captures reader-thread decode errors.
tests/​test_cli_usage.py Adds entry-point declarations and uses the shared parser.
tests/​test_carry.py Tests status records and parser failures.
scripts/​carry.py Exposes status records alongside paths.
CODESTYLE.md Clarifies CLI help and refusal requirements.
.github/​skills/​shell-codestyle/​SKILL.md Updates generated shell guidance.
.github/​skills/​python-codestyle/​SKILL.md Updates generated Python guidance.
.claude-plugin/​fleet-skills/​skills/​shell-codestyle/​SKILL.md Updates distributed shell guidance.
.claude-plugin/​fleet-skills/​skills/​python-codestyle/​SKILL.md Updates distributed Python guidance.
.claude-plugin/​fleet-skills/​.source-digests/​shell-codestyle Refreshes the shell source digest.
.claude-plugin/​fleet-skills/​.source-digests/​python-codestyle Refreshes the Python source digest.
.agents/​skills/​shell-codestyle/​SKILL.md Updates source shell guidance.
.agents/​skills/​python-codestyle/​SKILL.md Updates source Python guidance.

🧠 Review effort: Lite


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/test_cli_usage.py Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ptr727

ptr727 commented Oct 13, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 4851b53815b98940555bb2cf2096343b7ac9cfda, the content this pull request carries at that commit against develop, and it recorded 0 findings.

@ptr727
ptr727 merged commit ee8531c into develop Oct 13, 2026
13 checks passed
ptr727 added a commit that referenced this pull request Oct 14, 2026
…ps, and the Refusal Field Wording to Main (#2965)

- #2963 makes `gh-write-guard` read each push refspec's own operation,
so a `+src` forces and a `:dst` deletes only its own branch while
`--force` and `--delete` reach every refspec, and every operation, force
and delete included, is checked against `pull_request`. A git command
under an `include.path` or `includeIf.<condition>.path` override whose
subcommand is not a known git command now denies, since the included
file may alias it to a push. A separator fused with a redirection (`;<`,
`&&<`, `|<` and similar) is read both ways, so the next command's words
no longer read as the push's refspecs. A differential against the
previous guard found every allow flip in the intended per-refspec class
and none under a rule set holding `pull_request`. The known new
over-denials are listed in that pull request, and the fixed-prefix
branch pattern case is #2964
- #2956 tightens the CLI usage gate: `tests/test_cli_usage.py` declares
the entry points that need no argument and fails one declared nowhere,
`CODESTYLE.md` "Command-Line Arguments" states the gate's stricter
reading of help and unknown-argument refusals, `scripts/carry.py` shares
one porcelain status parser with the gate, and the Windows UTF-8 decode
probe in `tests/test_prose_lint.py` now sees the reader thread's
exception
- #2955 records the attached `-c<name>=<value>` / `-C<dir>` git option
disproof in the Disproved Claims ledger and states in
`scripts/README.md` when the digest's `refusal=` field and `wait`'s exit
code differ

Closes #2941
Closes #2946
Closes #2947
Closes #2948
Closes #2949
Closes #2951

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@ptr727
ptr727 deleted the feature/cli-gate-followups branch October 14, 2026 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants