openai / openai/codex-security

bulk-scan discards run warnings, so a drifted repository is recorded as completed with no signal

Open
#248 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:bulk-scan area:reports bug priority:p1
Dominant language
TypeScript
Stars
10.8k
Forks
801
Avg merge
1d 8h
Merged PRs (30d)
257

Description

Summary

bulk-scan never observes a repository's run warnings. runMultiscan calls security.run() without an onWarning observer, and the JSONL ledger receipt records status, attempt, outputDir, cost and error but no warnings. A repository whose target drifted mid-run is therefore recorded as status: "completed" with the warning nowhere in the campaign output.

This is the multiscan counterpart of #195. That issue is about a single scan exiting 0 and reporting nothing in --json; the same information is simply absent from bulk-scan, which is the mode where a human is least likely to be watching individual repositories.

Environment

  • @openai/codex-security 0.1.5, current main at ea19f24
  • macOS 15 (Darwin 25.5.0), Node.js 24.11.1, Bun 1.3.14

Where it is

sdk/typescript/src/multiscan.ts — the security.run() call passes no onWarning, and the receipt written for each attempt has no warnings field. Nothing else on the multiscan path carries them: the ledger receipt is the only per-repository record, and the campaign summary aggregates completed/failed/skipped counts only.

Impact

A drifted target is the motivating case, because coverage.completeness stays complete and the attempt genuinely succeeds — so there is no failure, no non-zero status, and no ledger field that would let a campaign consumer notice the results describe a stale tree. The same applies to the other warning producers (a cost limit that could not be verified, and cleanup failures).

Suggested direction

Two parts, both small:

  1. Pass an onWarning observer through to security.run() so multiscan sees them, and record them on the attempt receipt alongside error.
  2. Surface them in the campaign summary the way failures already are, so a resumed or scripted campaign can act on them.

On the receipt field's shape: scans show and scans list already emit their stored warnings key only when non-empty, so matching that — and matching how the receipt's own error and cost fields are omitted when absent — keeps the ledger predictable and keeps an older ledger readable.

For the record, ScanResult carries no warnings field on main today, so the observer is the only available channel; #195 and PR #220 concern surfacing warnings for a single scan, and this issue is about the multiscan ledger regardless of how that lands.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in sdk/typescript/src/multiscan.ts, tracing the security.run() call, per-attempt ledger receipt, and campaign summary. Done means warnings are observed, stored on receipts only when present, and surfaced in campaign summaries while older ledgers remain readable.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.