openai / openai/codex-security
Bulk-scan wizard drops cancellation while waiting on interactive prompts
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 10.8k
- Forks
- 801
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 257
Description
Summary
runBulkScanWizard() accepts an AbortSignal and propagates it through GitHub authentication/discovery requests, but then stops forwarding it to several blocking interactive prompts.
Once discovery reaches account/repository selection, output-directory entry, or the final confirmation, cancellation can no longer interrupt the prompt even though BulkScanPrompt already exposes a signal parameter for every prompt method.
Reproduction / evidence
The prompt contract is signal-aware:
confirm(question, defaultValue?, signal?): Promise<boolean>;
input(question, defaultValue?, signal?): Promise<string>;
select(question, options, presentation?, signal?): Promise<Value>;
Current main at 37bf87a692fc72d41f7312cc48808d699d204fba correctly forwards the signal to createGitHub() and discoverGitHubRepositories(), but omits it at these call sites:
selectGitHubOwner(...)
-> prompt.select(...); // no signal
selectGitHubRepositories(...)
-> prompt.select(...); // no signal
prompt.input(
"Where should scan results be saved?",
"./security-scans",
); // no signal
prompt.confirm("Start scanning?"); // no signal
Minimal deterministic reproduction with an injected BulkScanPrompt:
- let GitHub discovery return one active repository;
- pass an
AbortSignaltorunBulkScanWizard(); - instrument
select,input, andconfirmto record the signal they receive; - current
mainrecordsundefinedat those interactive boundaries despite the wizard having the caller's signal.
With a real terminal prompt, cancellation during one of those waits cannot reach Inquirer until the user supplies input or the process is otherwise terminated.
Expected behavior
Every blocking prompt in a signal-aware wizard should receive the same caller AbortSignal that is already used for GitHub requests, so cancellation remains effective throughout the workflow.
Root cause
The signal is threaded through the network/discovery helpers but was omitted from the prompt call sites. selectGitHubRepositories() does not currently accept a signal at all, and selectGitHubOwner() accepts one but does not pass it to prompt.select().
Suggested fix
- pass
signalto account selection; - add
signaltoselectGitHubRepositories()and pass it to repository selection; - pass
signalto output-directory input and final confirmation; - add focused prompt-boundary regression coverage proving all blocking prompts receive the caller signal.
Impact
This is a cancellation/reliability bug rather than data corruption. A user or automation can request cancellation successfully during GitHub discovery, then have the same cancellation become ineffective once the wizard is waiting for terminal input.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the runBulkScanWizard() entry point and trace selectGitHubOwner(), selectGitHubRepositories(), the output-directory prompt.input(), and the final prompt.confirm(). Use an injected BulkScanPrompt to record signals, then add focused regression coverage showing that each blocking prompt receives the caller's AbortSignal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100