Repository navigation
Fix the two pre-existing test failures on develop (stack 6/6) - #47
Closed
martient wants to merge 2 commits into
Conversation
test_tag_respects_repo_git_overrides_and_cli_can_override_them asserts that a repo-configured gpg.program is consulted, by pointing it at a script that always fails and expecting the tag creation to fail with it. That only holds when gpg.format is openpgp. On a machine whose global config sets gpg.format=ssh, git routes signing to gpg.ssh.program, the stub never runs, the tag is signed successfully by the ssh signer, and the assertion evaporates -- the test fails claiming Committy ignored the override when Committy had passed it through correctly. Verified: the tag git produced in that environment carried a valid SSH signature. The test now pins gpg.format=openpgp alongside the other overrides, so it exercises the path it means to exercise regardless of the host. Separately, the three config::hierarchy tests call MergedConfig::load, which reads the user config from $HOME. The tests in config.rs mutate HOME and are marked #[serial]; these were not, so they could read a half-written or relocated user config while one of those held it, and MergedConfig::load(...).unwrap() would panic. They are now serial too. Caveat on that second change: it closes a real race but is unproven. The failure was observed once, and did not recur in thirteen subsequent runs (eight lib-only, five full) even with the fix reverted, so causality is reasoned rather than demonstrated. It is cheap and correct regardless -- a test reading global state that other tests mutate belongs in the same serial group.
…t caught The rewritten guardrail shipped unvalidated: nothing executed it, so its deny rules were assumed rather than checked. That matters more than for ordinary code, because a guardrail that silently stops refusing looks exactly like one that works. Twelve tests feed the hook the same JSON the harness does and assert the exit code. Writing them found three defects in the hook, all now fixed: - `git push -f origin main` was not refused. The force check was one ordered regex whose `-f` alternative required a preceding space, which the `push ` match had already consumed. Force detection is now two independent conditions -- a push, and a force flag anywhere -- so flag order and adjacency stop mattering. - A heredoc feeding an interpreter was dropped along with every other heredoc body, so `bash <<EOF` / `git reset --hard` / `EOF` sailed through. Heredoc bodies are still discarded when the opener writes to a file, but scanned when it names a shell or interpreter. - Quoted prose naming a dangerous command is still refused. This one is deliberate and now recorded as a decision: stripping quoted segments would fix it and would also let `bash -c "git reset --hard"` through, and for a guardrail a false refusal costs far less than a false pass. Coverage includes the variants the previous substring hook missed entirely -- doubled spaces, a leading env assignment, `git -C .`, and a git call after `&&`.
martient
force-pushed
the
claude/ai-agents-capabilities-report-fgpp3p-test-fixes
branch
from
September 20, 2026 18:03
f36d733 to
fbb1144
Compare
Owner
Author
|
Superseded by #49, which carries these commits unchanged. Closing — see #42 for why the stack was collapsed. Generated by Claude Code |
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.
Stacked on #46. Fixes the two failures flagged throughout this series as pre-existing, and adds the behaviour matrix for the guardrail introduced in #46.
Result: 421 passed, 0 failed — parallel and
--test-threads=1.1.
tag_tests::test_tag_respects_repo_git_overrides_and_cli_can_override_them— root-caused and fixedThe test points
gpg.programat a script that always fails and expects tag creation to fail with it, proving Committy passes repo git config through.It was not a Committy bug. Committy passed the overrides correctly. The test depends on ambient host config:
gpg.programis only consulted whengpg.formatis openpgp./root/.gitconfigsetsgpg.format=sshandgpg.ssh.program.git tag -asucceeded.Confirmed directly — the tag git produced carried a valid
-----END SSH SIGNATURE-----, andcommitty config showproved both overrides were loaded and forwarded. The test then reported "Committy ignored the override" when Committy had done exactly the right thing.The test now pins
gpg.format=openpgpalongside the other overrides, so it exercises the path it means to exercise regardless of host.This one is demonstrated: failure reproduced, cause identified, fix verified.
2.
config::hierarchy::tests::test_repository_config_overrides_user— hardened, but causality unprovenAll three
config::hierarchytests callMergedConfig::load, which reads the user config from$HOME. The tests insrc/config.rsmutateHOMEand are#[serial]; these three were not.serial_testonly serialises tests that opt in, so a hierarchy test could read a relocated or half-written user config while one of those held it — andMergedConfig::load(...).unwrap()panics on the resultingErr. That matches the observed symptom.They are now
#[serial]too.I'm keeping the change because it's correct and costs nothing: a test reading global state that other tests mutate belongs in the same serial group. But it should be read as hardening against a plausible race, not as a verified fix. If it ever recurs, the
.unwrap()athierarchy.rs:230is where to look.3. Behaviour matrix for the guardrail — and three defects it caught
.claude/hooks/block-dangerous-git.sh(rewritten in #46) shipped unvalidated: nothing executed it, so its deny rules were assumed. That matters more than for ordinary code, because a guardrail that silently stops refusing looks exactly like one that works.tests/guardrail_hook_tests.rsfeeds the hook the same JSON the harness does and asserts the exit code, across 12 cases. Writing it found three defects, all fixed here:git push -f origin mainwas not refused. The force check was one ordered regex whose-falternative required a preceding space that thepushmatch had already consumed. Force detection is now two independent conditions — a push, and a force flag anywhere — so flag order and adjacency stop mattering.bash <<EOF/git reset --hard/EOFsailed through. Bodies are still discarded when the opener writes to a file, but scanned when it names a shell or interpreter.bash -c "git reset --hard"through. For a guardrail a false refusal costs far less than a false pass.Coverage includes the variants the previous substring hook missed entirely — doubled spaces, a leading env assignment,
git -C ., and a git call after&&.4. CI was not running on this stack at all
lint.ymlfilteredpull_request: branches: ["*"], and in Actions branch filters*does not match/. Every stacked PR targets aclaude/…base, so #43–#47 had zero check runs — silently, since a workflow that does not trigger looks identical to one with nothing to report. Only #42 (basedevelop) ever ran.Fixed to
["**"], which is what the filter meant. It would equally have hidden CI on anything under afeat/orfix/prefix. The fix is merged down the stack so every PR in the series now gets checks.