Summary
The pre-push hook script appended by prov install is chained with any existing user hook. Pre-push stdin is one-shot — if the user's chained hook reads from stdin (very common), prov sees empty stdin and falls through the "skip on malformed input" defensive branch, which returns Allow. The unit test pre_push_with_malformed_stdin_exits_zero_defensively confirms the empty-stdin → success path.
The plan flagged this concern explicitly for U5/U8 install ("the chained wrapper captures stdin to a temp file once and replays it to each chained sub-hook"). Implementation does not yet do this.
Severity
P1 — silent privacy bypass any time a user has another pre-push handler. Confidence 75.
Evidence
crates/prov-cli/src/commands/install.rs — chained-wrapper construction.
crates/prov-cli/src/commands/hook.rs (handle_pre_push) — empty-stdin defensive branch.
crates/prov-cli/tests/cli_pre_push.rs::pre_push_with_malformed_stdin_exits_zero_defensively.
Suggested fix
Per plan: in the wrapper, capture stdin once to a temp file, then replay to each chained sub-hook. Then revisit whether the empty-stdin defensive branch in handle_pre_push should fail-closed (exit 1) when the gate is supposed to be active.
Acceptance criteria
Reference
/tmp/compound-engineering/ce-code-review/20260502-075634-3af3d047/security.json (sec-004); plan U5 §612.
Summary
The pre-push hook script appended by
prov installis chained with any existing user hook. Pre-push stdin is one-shot — if the user's chained hook reads from stdin (very common), prov sees empty stdin and falls through the "skip on malformed input" defensive branch, which returnsAllow. The unit testpre_push_with_malformed_stdin_exits_zero_defensivelyconfirms the empty-stdin → success path.The plan flagged this concern explicitly for U5/U8 install ("the chained wrapper captures stdin to a temp file once and replays it to each chained sub-hook"). Implementation does not yet do this.
Severity
P1 — silent privacy bypass any time a user has another pre-push handler. Confidence 75.
Evidence
crates/prov-cli/src/commands/install.rs— chained-wrapper construction.crates/prov-cli/src/commands/hook.rs(handle_pre_push) — empty-stdin defensive branch.crates/prov-cli/tests/cli_pre_push.rs::pre_push_with_malformed_stdin_exits_zero_defensively.Suggested fix
Per plan: in the wrapper, capture stdin once to a temp file, then replay to each chained sub-hook. Then revisit whether the empty-stdin defensive branch in
handle_pre_pushshould fail-closed (exit 1) when the gate is supposed to be active.Acceptance criteria
Reference
/tmp/compound-engineering/ce-code-review/20260502-075634-3af3d047/security.json(sec-004); plan U5 §612.