git-enforce.py backstop coverage gaps: H-02 force-push and H-14/H-10b fail-closed branches are untested
Two coverage findings share one file and one remediation direction: the #161 git-level enforcement backstop (git-enforce.py) has several block/fail-closed branches with zero test coverage.
coverage-001 (anchor): H-02 force-push block in git-enforce.py has zero test coverage
Severity: high | Confidence: 0.8 | Effort: S
Where:
plugins/ca/hooks/git-enforce.py:186-195
plugins/ca/hooks/tests/test_git_hooks.py:150-167
Evidence: git-enforce.py pre_push() implements two independent gates: H-01 (push to protected branch) and H-02 (force/non-fast-forward update, lines 187-195). test_git_hooks.py's TestPrePushEnforce class has exactly two tests: test_push_to_protected_branch_is_blocked (H-01) and test_feature_fast_forward_push_is_allowed (a create ref, which short-circuits H-02 via the zero() check). No test stages a real non-fast-forward update (both shas non-zero, remote not an ancestor of local) on a non-protected branch, so H-02's block path, its "unresolvable check treated as force" fail-closed branch, and the ancestor-check success path (an actual fast-forward on a feature branch, not a create) are all unexercised.
Impact: H-02 is one of two enforcement gates in the spelling-proof git-level backstop (#161) explicitly designed to close a bypass in pre-bash.py. A regression that silently disables the force-push block (e.g. an inverted condition, a broken merge-base invocation, or a future refactor) would ship undetected — CI's green build offers no evidence H-02 still fires.
Recommendation: Add TestPrePushEnforce cases: (1) a real non-fast-forward push on a feature branch asserts returncode==1 and 'H-02' in stderr; (2) a genuine fast-forward update asserts allow; (3) an unresolvable merge-base asserts fail-closed block.
Acceptance criteria:
- A test stages/simulates a non-fast-forward push (both refs non-zero, no ancestor relationship) and asserts H-02 blocks it
- A test exercises the ancestor-check-unresolvable fail-closed branch and asserts it blocks
- A genuine (non-create) fast-forward push is asserted to be allowed
coverage-002 (member): H-14 migration block, H-10b secret block, and both fail-closed git-read branches are untested
Severity: medium | Confidence: 0.8 | Effort: S
Where:
plugins/ca/hooks/git-enforce.py:126-164
plugins/ca/hooks/tests/test_git_hooks.py:106-148
Evidence: pre_commit() has four distinct block paths beyond H-01: the H-09b/H-10b fail-closed branch when cached_added_lines returns None (lines 126-129), the H-10b secret-only block (lines 133-140), the H-14 fail-closed branch when cached_names returns None (lines 149-152), and the H-14 uncovered-migration block (lines 153-164). The TestPreCommitEnforce class has five tests (direct-commit-to-main, variable-indirection commit, feature-branch-allow, crypto-commit-without-marker, dormant-repo-noop); none stages a secret-only line, none stages a migration path without a migration-gate marker, and none simulates a git diff --cached failure to exercise either fail-closed branch.
Impact: H-14 (migration-review backstop) and H-10b (secret-handling backstop) are two of four distinct gate outcomes in the #161 git-level enforcement layer; a defect isolated to the secret or migration branch would not be caught by the current suite. The fail-closed branches are the ambiguity-resolves-CLOSED security posture called out in the module's own docstring — untested fail-closed logic is a common site for accidental fail-open regressions. Ties into wave-1's fail-closed group (reliability-001/002), which touches these same paths; the tests should land with or before that fix.
Recommendation: Extend TestPreCommitEnforce with: a secret-only staged line asserting H-10b block; a staged migration-path file with no migration-gate-passed marker asserting H-14 block; and two tests that monkeypatch/force a git-diff failure to assert both H-09b/H-10b and H-14 fail closed.
Acceptance criteria:
- A secret-only (non-crypto) staged line triggers H-10b, not H-09b
- A staged migration file lacking a fresh content-bound marker triggers H-14
- Both fail-closed branches (added-lines read failure, staged-names read failure) are exercised and assert block
git-enforce.py backstop coverage gaps: H-02 force-push and H-14/H-10b fail-closed branches are untested
Two coverage findings share one file and one remediation direction: the #161 git-level enforcement backstop (git-enforce.py) has several block/fail-closed branches with zero test coverage.
coverage-001 (anchor): H-02 force-push block in git-enforce.py has zero test coverage
Severity: high | Confidence: 0.8 | Effort: S
Where:
plugins/ca/hooks/git-enforce.py:186-195
plugins/ca/hooks/tests/test_git_hooks.py:150-167
Evidence: git-enforce.py pre_push() implements two independent gates: H-01 (push to protected branch) and H-02 (force/non-fast-forward update, lines 187-195). test_git_hooks.py's TestPrePushEnforce class has exactly two tests: test_push_to_protected_branch_is_blocked (H-01) and test_feature_fast_forward_push_is_allowed (a create ref, which short-circuits H-02 via the zero() check). No test stages a real non-fast-forward update (both shas non-zero, remote not an ancestor of local) on a non-protected branch, so H-02's block path, its "unresolvable check treated as force" fail-closed branch, and the ancestor-check success path (an actual fast-forward on a feature branch, not a create) are all unexercised.
Impact: H-02 is one of two enforcement gates in the spelling-proof git-level backstop (#161) explicitly designed to close a bypass in pre-bash.py. A regression that silently disables the force-push block (e.g. an inverted condition, a broken merge-base invocation, or a future refactor) would ship undetected — CI's green build offers no evidence H-02 still fires.
Recommendation: Add TestPrePushEnforce cases: (1) a real non-fast-forward push on a feature branch asserts returncode==1 and 'H-02' in stderr; (2) a genuine fast-forward update asserts allow; (3) an unresolvable merge-base asserts fail-closed block.
Acceptance criteria:
coverage-002 (member): H-14 migration block, H-10b secret block, and both fail-closed git-read branches are untested
Severity: medium | Confidence: 0.8 | Effort: S
Where:
plugins/ca/hooks/git-enforce.py:126-164
plugins/ca/hooks/tests/test_git_hooks.py:106-148
Evidence: pre_commit() has four distinct block paths beyond H-01: the H-09b/H-10b fail-closed branch when
cached_added_linesreturns None (lines 126-129), the H-10b secret-only block (lines 133-140), the H-14 fail-closed branch whencached_namesreturns None (lines 149-152), and the H-14 uncovered-migration block (lines 153-164). The TestPreCommitEnforce class has five tests (direct-commit-to-main, variable-indirection commit, feature-branch-allow, crypto-commit-without-marker, dormant-repo-noop); none stages a secret-only line, none stages a migration path without a migration-gate marker, and none simulates agit diff --cachedfailure to exercise either fail-closed branch.Impact: H-14 (migration-review backstop) and H-10b (secret-handling backstop) are two of four distinct gate outcomes in the #161 git-level enforcement layer; a defect isolated to the secret or migration branch would not be caught by the current suite. The fail-closed branches are the ambiguity-resolves-CLOSED security posture called out in the module's own docstring — untested fail-closed logic is a common site for accidental fail-open regressions. Ties into wave-1's fail-closed group (reliability-001/002), which touches these same paths; the tests should land with or before that fix.
Recommendation: Extend TestPreCommitEnforce with: a secret-only staged line asserting H-10b block; a staged migration-path file with no migration-gate-passed marker asserting H-14 block; and two tests that monkeypatch/force a git-diff failure to assert both H-09b/H-10b and H-14 fail closed.
Acceptance criteria: