Skip to content

Read a Push Option Attached to -o as Its Value in the Write Guard - #3784

Merged
ptr727 merged 3 commits into
developfrom
feature/burn-3720
Nov 1, 2026
Merged

ptr727 merged 3 commits into
developfrom
feature/burn-3720

Conversation

@ptr727

@ptr727 ptr727 commented Nov 1, 2026

Copy link
Copy Markdown
Owner

Summary

_push_targets in the write guard read an all-letter short-option word as a cluster of flags anywhere in it, so a push option attached to -o was read as more flags. When the word ended in o, the next word was also consumed as the option's value. So git push -ofoo origin develop read f as --force, consumed origin, and judged the push as a bare push of the current branch. It was allowed while git pushed develop.

The walk now stops at the first o, as git does. The rest of the word is the push option's value, and the next word is consumed only when nothing follows the o. A cluster carrying a digit, such as -4f (-4 is git push's IPv4 option), is walked too, where before it was skipped and its f missed. A word whose flag part carries a run-time character, such as -$o, consumes no next word, as before.

Changes

  • host-setup/agent-safety/claude/gh-write-guard.py: the short-cluster branch of _push_targets, plus self-test rows for -ofoo, -o foo, -fofoo, -ofoo to a main whose rules allow an update, -4f, and -uo ci.skip, a cluster ending in o that takes the next word as its value.
  • host-setup/agent-safety/README.md: requirement 4 states how a short-option cluster and its push option are read.

Verification

  • gh-write-guard.py --selftest passes. The same rows run against the guard from origin/develop fail on -ofoo origin develop, -fofoo origin main, and -4f origin main, each allowed there. A mutant that never consumes the next word fails the -uo ci.skip row.
  • tests/test_guard_size.py and host-setup/agent-safety/claude/test_install.py pass. The guard is 2208 lines against its 2500 ceiling.

Pre-existing findings, filed

Closes on promotion: #3720

🤖 Generated with Claude Code

ptr727 and others added 3 commits November 1, 2026 14:59
The push reading walked an all-letter short-option word as flags anywhere
in it, so a push option attached to -o was read as more flags and the next
word was consumed as its value. Stop the walk at the first o, take the rest
of the word as the value, and consume the next word only when nothing
follows the o. Non-letter clusters such as -4f are walked too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 November 1, 2026 23:08
@ptr727

ptr727 commented Nov 1, 2026

Copy link
Copy Markdown
Owner Author

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

@coderabbitai

coderabbitai Bot commented Nov 1, 2026

Copy link
Copy Markdown

Important

  • Trigger review

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

Run configuration
  • 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

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.

🟢 Approval recommended

No active review issues remain, and the change includes targeted parsing updates with accompanying documentation and regression coverage.

No open issues 🎉

What changed in this PR

This pull request fixes short-option parsing in the write guard so attached git push -o values are treated as values rather than additional flags. It also documents the behavior and adds regression coverage.

Changes:

  • Stops parsing short-option clusters at the first o.
  • Consumes the following word as the push-option value only when no attached value exists.
  • Preserves flag detection in digit-bearing clusters such as -4f.
  • Adds self-tests and updates the agent-safety requirements.
File Description
host-setup/​agent-safety/​README.md Documents how push short-option clusters and -o values are interpreted.
host-setup/​agent-safety/​claude/​gh-write-guard.py Fixes push-option parsing and adds regression self-tests.

Review effort: Lite

@codecov

codecov Bot commented Nov 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.34%. Comparing base (27d1ca4) to head (b6767ad).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #3784   +/-   ##
========================================
  Coverage    82.34%   82.34%           
========================================
  Files           28       28           
  Lines         9454     9454           
========================================
  Hits          7785     7785           
  Misses        1669     1669           
Flag Coverage Δ
python-3.13 82.34% <ø> (ø)

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.

@ptr727
ptr727 merged commit ea3e2b6 into develop Nov 1, 2026
14 checks passed
@ptr727
ptr727 deleted the feature/burn-3720 branch November 1, 2026 23:22
ptr727 added a commit that referenced this pull request Nov 2, 2026
…ings With an Acknowledgment Record, and Mark Direct-Push Closures (#3797)

Promotes the changes merged into `develop` since promotion #3778 to
`main`, the second round of a backlog burndown.

- [#3784](#3784) has the
write guard read a push option attached to `-o` as that option's value,
as git does, rather than as more short flags. It also walks a
short-option cluster carrying a digit, such as `-4f`.
- [#3796](#3796) fixes
five pull-request-gate and release-task defects:
- Each aggregator's `name:` gives the ruleset-bound required check name
only on a `pull_request` run, so a dispatch run cannot mask it.
`spec/audit.py` `check_interface` reads that expression.
- The stubs drop the `pull_request` base-branch filter, and "Adopting
the Gates" states the task's preconditions.
- A re-run release takes the Latest flag only where its version sorts at
or above the current Latest release.
- The `lint` job runs its Python steps under the first `python-versions`
entry.
- `dotnet format` and `dotnet test` run per tracked workspace where the
root holds no solution or project.
- [#3793](#3793) has
`pr_review.py merge` read an acknowledgment record, posted with `comment
--ack KEY=OUTCOME`, for findings no thread carries and for a verdict
naming no counted finding. Every `merge` run ends on one `next=` line
the skills follow, and the digest reads the excluded-files refusal as
`refusal=EXCLUDED`.
- [#3792](#3792) has a
direct push to `develop` on an operational-model repository name the
issues it fixes in its commit message's on-promotion line.
`backlog-burndown` assembles the promotion body from the pull request
that merged each commit, falling back to a direct push's own message.
Its claim lookup matches only claim comments, and
`git-commit-conventions` names the abandon-discard exception.
- [#3798](#3798) has
`has_prose` read an inline token's text children outside code, so an
inline-code span alone no longer counts as prose. It answers this
promotion's first review round.
- [#3799](#3799) has
`check_interface` read each job by its key on a workflow a non-PR event
triggers. A job whose off-PR name is the required check gets its own
DRIFT. It answers this promotion's first review round.

## Downstream effect

From #3796: once this reaches `main`, every downstream
`test-pull-request.yml` whose aggregator carries a literal `name:` shows
`check_interface` DRIFT. It shows that until its next resync. A resync
clears it by replacing the aggregator's `name:` line with the
expression. No ruleset changes, since the `context:` a pull request run
posts is unchanged.

Fixes #3720
Fixes #3334
Fixes #1516
Fixes #3487
Fixes #1485
Fixes #1938
Fixes #3718
Fixes #3724
Fixes #3777
Fixes #3773
Fixes #1276
Fixes #1307
Fixes #3780

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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