Add wall-clock timeout and SSH hardening to authorship note fetch#1184
Closed
jwiegley wants to merge 3 commits into
Closed
Add wall-clock timeout and SSH hardening to authorship note fetch#1184jwiegley wants to merge 3 commits into
jwiegley wants to merge 3 commits into
Conversation
This was referenced Apr 23, 2026
Contributor
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Member
|
This PR has a lot of changes... I think the patch for the one affected test (from what I can tell) is a ~1 liner to just use |
`fetch_authorship_notes` previously shelled out to `git fetch` via `exec_git`, which uses `Command::output()` and blocks the calling thread indefinitely. In practice this meant a stalled SSH handshake to the remote -- credential prompt with no TTY, dead TCP connection, or BatchMode-less keepalive loss -- would freeze the caller forever with no way to recover. We observed a ~5 hour hang in a test run where `ssh git@github.com` never completed. Introduce `exec_git_with_env_and_timeout` in repository.rs: it spawns the child with piped stdout/stderr drained by background threads (to avoid pipe-buffer deadlock), polls `try_wait` with a short interval, and on timeout kills the child and returns a `GitCliError` marked with `code: None` and a descriptive stderr. Route `fetch_authorship_notes` through it with a 60s deadline -- authorship notes are tiny, anything longer is a hung remote -- plus two env vars that prevent hangs at the SSH layer: - `GIT_TERMINAL_PROMPT=0` disables interactive credential prompts. - `GIT_SSH_COMMAND` forces `BatchMode=yes`, `ConnectTimeout=10`, and short keepalives so a dead connection fails fast. Only applied when the user has not set `GIT_SSH_COMMAND` themselves. Either guard alone would have killed the observed hang within seconds; together they provide defense in depth. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`test_load_ai_touched_files_for_specific_commits` performs a real `git fetch origin refs/notes/ai` against the developer's CWD remote and requires the remote to have at least 3 authorship notes. It is a smoke test, not a unit test: in CI or on a machine without SSH credentials to the configured origin it will either fail or (before the preceding fetch-timeout hardening) hang indefinitely. Mark it `#[ignore]` with a comment spelling out the preconditions and what a proper hermetic rewrite would look like (a TestRepo with a local file:// remote seeded with synthetic notes). Re-enable once ported. The other four tests in the module remain environment- dependent on CWD but do not touch the network, so are left alone here. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pure rustfmt output -- indentation and macro-call wrapping only. No behavior change. These were produced by `task fmt` during an unrelated session and are bundled here separately to keep them out of the hang-fix commits. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8b08c91 to
fd5f46f
Compare
fd7b5db to
9822853
Compare
Member
|
Closing re #1184 (comment) |
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.

Add wall-clock timeout and SSH hardening to authorship note fetch
fetch_authorship_notespreviously shelled out togit fetchviaexec_git, which usesCommand::output()and blocks the callingthread indefinitely. In practice this meant a stalled SSH handshake
to the remote -- credential prompt with no TTY, dead TCP connection,
or BatchMode-less keepalive loss -- would freeze the caller forever
with no way to recover. We observed a ~5 hour hang in a test run
where
ssh git@github.comnever completed.Introduce
exec_git_with_env_and_timeoutin repository.rs: it spawnsthe child with piped stdout/stderr drained by background threads
(to avoid pipe-buffer deadlock), polls
try_waitwith a shortinterval, and on timeout kills the child and returns a
GitCliErrormarked with
code: Noneand a descriptive stderr.Route
fetch_authorship_notesthrough it with a 60s deadline --authorship notes are tiny, anything longer is a hung remote -- plus
two env vars that prevent hangs at the SSH layer:
GIT_TERMINAL_PROMPT=0disables interactive credential prompts.GIT_SSH_COMMANDforcesBatchMode=yes,ConnectTimeout=10, andshort keepalives so a dead connection fails fast. Only applied
when the user has not set
GIT_SSH_COMMANDthemselves.Either guard alone would have killed the observed hang within
seconds; together they provide defense in depth.
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com
Disable env-dependent authorship traversal smoke test
test_load_ai_touched_files_for_specific_commitsperforms a realgit fetch origin refs/notes/aiagainst the developer's CWD remoteand requires the remote to have at least 3 authorship notes. It is
a smoke test, not a unit test: in CI or on a machine without SSH
credentials to the configured origin it will either fail or (before
the preceding fetch-timeout hardening) hang indefinitely.
Mark it
#[ignore]with a comment spelling out the preconditionsand what a proper hermetic rewrite would look like (a TestRepo with
a local file:// remote seeded with synthetic notes). Re-enable once
ported. The other four tests in the module remain environment-
dependent on CWD but do not touch the network, so are left alone
here.
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com
Apply pending cargo fmt to hooks and test_repo
Pure rustfmt output -- indentation and macro-call wrapping only.
No behavior change. These were produced by
task fmtduring anunrelated session and are bundled here separately to keep them
out of the hang-fix commits.
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com