ci(security): retry incomplete npm audits#7575
Conversation
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
📝 WalkthroughWalkthroughThe npm audit helper now retries incomplete or timed-out executions, classifies failures, sanitizes retry warnings, and returns parsed reports or terminal errors. Reviewed audit execution uses the final result, while unit and workflow tests cover the new behavior. ChangesNPM audit retry handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
PR Review Advisor — No blocking findings reportedAdvisor assessment: No blocking advisor findings reported Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: None 1 warning · 0 suggestionsWarningsWarnings do not block.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
test/reviewed-npm-audit-workflow.test.ts (1)
132-147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSource-text assertions on the helper file, not observable behavior.
This reads
reviewed-npm-audit.mtsas text and asserts on literal substrings ("const NPM_AUDIT_ATTEMPT_TIMEOUT_MS = 45_000","timeout: NPM_AUDIT_ATTEMPT_TIMEOUT_MS"). This locks the test to source formatting/wording rather than proving the configured timeout is actually wired into thespawnSynccall — a harmless rename, reformat, or refactor (e.g. extracting the constant into a shared config module) would fail this test without any behavior change, while a genuine bug (e.g. passing a different constant totimeout) that happens to preserve these substrings would pass it.Consider asserting behavior instead, e.g. mocking
spawnSync/child_processand asserting thetimeoutoption value actually passed byrunReviewedNpmAudit, or invokingrunNpmAuditWithRetrywith a fakerunand confirming the configured constant governs retry timing.Based on path instructions for
**/*.test.{ts,js,mts,mjs,cts,cjs}: "Prefer observable outcomes through the public boundary over source-text, private-shape, or mock-call assertions."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/reviewed-npm-audit-workflow.test.ts` around lines 132 - 147, Replace the source-text assertions for NPM audit timeout wiring in the reviewed-npm-audit test with an observable behavior test. Exercise runReviewedNpmAudit or runNpmAuditWithRetry using a controlled fake spawnSync/run implementation, then verify the timeout option passed to the audit attempt is 45_000 and retry behavior remains correct. Remove the helper file substring checks while preserving the existing action and configuration assertions.Source: Path instructions
test/reviewed-npm-audit.test.ts (1)
315-338: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winThis test's fixture never exercises the redaction gap in the terminal failure path.
Using empty
summary/detailhere means the assertion onaudit.failure?.messagenever proves that sensitive stderr/report.errorcontent is redacted once the retry budget is exhausted — unlike the "bounded backoff" test, which does inject secrets but only into retry warnings (a different, already-sanitized path). See the related comment onscripts/lib/reviewed-npm-audit.mts(Lines 337-344) for the underlying gap this test doesn't catch.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/reviewed-npm-audit.test.ts` around lines 315 - 338, Update the “fails closed after the scan-incomplete retry budget is exhausted” test fixture to include representative sensitive values in stderr and the report error summary/detail, then assert that audit.failure?.message contains the structural failure context while excluding every injected secret. Preserve the existing three-attempt and backoff assertions, and target the terminal failure message produced by runNpmAuditWithRetry rather than retry warnings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/lib/reviewed-npm-audit.mts`:
- Around line 337-344: Update the terminal failure construction in
runNpmAuditWithRetry so it uses the same sanitized stable reason code as the
per-attempt warn() calls instead of embedding lastFailure?.message. Preserve the
retry count and fail-closed behavior, and ensure the resulting failure message
used for both throwing and provenance cannot expose raw stderr or report error
contents.
---
Nitpick comments:
In `@test/reviewed-npm-audit-workflow.test.ts`:
- Around line 132-147: Replace the source-text assertions for NPM audit timeout
wiring in the reviewed-npm-audit test with an observable behavior test. Exercise
runReviewedNpmAudit or runNpmAuditWithRetry using a controlled fake
spawnSync/run implementation, then verify the timeout option passed to the audit
attempt is 45_000 and retry behavior remains correct. Remove the helper file
substring checks while preserving the existing action and configuration
assertions.
In `@test/reviewed-npm-audit.test.ts`:
- Around line 315-338: Update the “fails closed after the scan-incomplete retry
budget is exhausted” test fixture to include representative sensitive values in
stderr and the report error summary/detail, then assert that
audit.failure?.message contains the structural failure context while excluding
every injected secret. Preserve the existing three-attempt and backoff
assertions, and target the terminal failure message produced by
runNpmAuditWithRetry rather than retry warnings.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: b2789591-f867-4870-a2a9-ee3ec52674cc
📒 Files selected for processing (3)
scripts/lib/reviewed-npm-audit.mtstest/reviewed-npm-audit-workflow.test.tstest/reviewed-npm-audit.test.ts
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
cv
left a comment
There was a problem hiding this comment.
The new head fixes the test-body growth guard, and the exact focused suite passes 39/39. One security blocker remains before this trusted CI change can be approved:
runNpmAuditWithRetry constructs the terminal failure with lastFailure?.message. That message can contain raw final-attempt stderr or report.error text (including authenticated registry URLs, newlines, and ANSI/control sequences), and is then emitted by the CLI and stored in provenance. The per-attempt warnings are sanitized, but retry exhaustion reopens the same diagnostic leak. Build the terminal failure from a stable sanitized reason code (plus attempt count), never raw scanner text, and add a final-attempt fixture with injected credentials/control text that proves both the returned failure/provenance-facing message and console path exclude them.
The timeout source-shape assertion and the advisor note about documenting the upstream/removal boundary are nonblocking maintainability follow-ups. After the security fix, refresh the exact-head sensitive/docs receipts and rerun normal gates. The current reviewed-npm-audit failure is still the old trusted base helper receiving an incomplete registry response; wait for registry recovery rather than waiving that required gate.
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Addressed the requested terminal redaction in signed commit |
<!-- markdownlint-disable MD041 --> ## Summary Add the canonical `docs/changelog/2026-07-25.mdx` release entry with the exact `## v0.0.96` heading. The entry reconciles all 90 first-parent commits since v0.0.95 with all 92 merged PRs in the live `v0.0.96` label ledger and groups the user-visible changes by operator journey. ## Changes - Add the parser-safe dated MDX changelog entry for v0.0.96 with root-absolute links to the focused user guides. - Source summary: - [#7194](#7194) -> `docs/changelog/2026-07-25.mdx`: Document persistent baseline network policy exclusions and their inspection, rebuild, and snapshot behavior. - [#7188](#7188), [#7427](#7427), and [#7546](#7546) -> `docs/changelog/2026-07-25.mdx`: Document DNS-backed HTTPS inference routing, keyless loopback endpoints, and provider-marker isolation. - [#7238](#7238) -> `docs/changelog/2026-07-25.mdx`: Document blueprint sandbox and provider identifier validation before state writes or OpenShell calls, with bounded terminal-safe rejection previews. - [#7319](#7319), [#7274](#7274), [#7528](#7528), [#7353](#7353), and [#7560](#7560) -> `docs/changelog/2026-07-25.mdx`: Document the managed default gateway service, onboarding readiness, and container-runtime identity safeguards. - [#7349](#7349), [#7498](#7498), [#7406](#7406), [#7196](#7196), [#7559](#7559), [#7421](#7421), [#7510](#7510), [#7295](#7295), and [#7565](#7565) -> `docs/changelog/2026-07-25.mdx`: Document gateway-scoped status, lifecycle diagnostics, managed MCP recovery, delete-edge safeguards, and fail-closed CLI prompt and command output. - [#7591](#7591) -> `docs/changelog/2026-07-25.mdx`: Document opt-in authenticated MCP tool-name discovery, its bounded and names-only contract, probe interaction, and rebuild requirement. - [#7305](#7305), [#7480](#7480), [#7471](#7471), [#7365](#7365), and [#7541](#7541) -> `docs/changelog/2026-07-25.mdx`: Document installer version checks, version-tag reporting, license guidance, WSL Ollama selection, and DGX Station vLLM detection. - [#7482](#7482), [#7466](#7466), [#7208](#7208), [#7434](#7434), and [#7586](#7586) -> `docs/changelog/2026-07-25.mdx`: Document Ollama resource details, reasoning precedence, Hermes onboarding behavior, and preserved managed Hermes BuildKit failures. - [#6830](#6830), [#7492](#7492), [#7563](#7563), and [#7582](#7582) -> `docs/changelog/2026-07-25.mdx`: Document the authoritative OpenClaw production lock, fixed managed-image dependencies, immutable Hermes base adoption, and Hermes image-size reduction. - [#7505](#7505), [#7530](#7530), [#7547](#7547), [#7508](#7508), [#7548](#7548), [#7549](#7549), [#7537](#7537), [#7534](#7534), [#7515](#7515), [#7511](#7511), [#7551](#7551), [#7562](#7562), [#7575](#7575), [#7496](#7496), [#7594](#7594), [#7595](#7595), and [#7599](#7599) -> `docs/changelog/2026-07-25.mdx`: Summarize release validation, transient and bounded dispatch reconciliation, exact pre-tag qualification, identity revalidation, npm-audit retry, sharding, image reuse, timeout, telemetry, and workflow-hardening changes. - Reconciled without separate changelog prose: - [#7539](#7539), [#7526](#7526), [#7507](#7507), [#7506](#7506), [#7519](#7519), [#7516](#7516), [#7396](#7396), [#7254](#7254), [#7583](#7583), [#7596](#7596), and [#7598](#7598): Test-harness or fixture-only changes. - [#7403](#7403), [#7161](#7161), [#6877](#6877), [#7531](#7531), [#7525](#7525), [#7522](#7522), [#7536](#7536), [#7552](#7552), [#7566](#7566), [#7553](#7553), [#7561](#7561), [#7577](#7577), [#7569](#7569), [#7585](#7585), [#7584](#7584), [#7592](#7592), [#7580](#7580), [#7571](#7571), [#7517](#7517), [#7589](#7589), [#7402](#7402), [#7558](#7558), [#7544](#7544), and [#7601](#7601): Dependency, internal recovery, validation, contributor-workflow, E2E optimization, telemetry, or CI trust changes with no separate user-facing release claim. - [#7556](#7556), [#7573](#7573), [#7576](#7576), and [#7578](#7578): Experimental repository-maintainer conflict automation with no canonical user documentation surface. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [x] Existing tests cover changed behavior — justification: `test/changelog-docs.test.ts` validates dated changelog structure, version headings, and published links. - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: Reviewed `docs/changelog/2026-07-25.mdx` at exact head `0f5dedb47` against 90 first-parent release commits and 92 merged PRs labeled `v0.0.96`. Verified parser-safe MDX SPDX, the exact version heading, literal CLI names, writing style, skip terms, all 20 root-absolute published links, and the accepted #7591 opt-in authenticated discovery bounds. #7544, #7599, and #7601 remain internal or CI-only release-ledger entries. Changelog tests passed 6/6, the docs build passed with 0 errors and two pre-existing Fern warnings, and `npm run check:diff` plus the final diff check passed. - Agent: Codex Desktop documentation-writer subagent <!-- docs-review-head-sha: 0f5dedb --> <!-- docs-review-agents-blob-sha: be20a09 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: - Station profile/scenario: - Result: - Supporting evidence: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `npx vitest run test/changelog-docs.test.ts`: 6/6 passed. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: Not applicable to this prose-only changelog entry. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — the build passed with 0 errors and 2 existing Fern warnings; the published-route check passed. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) — native changelog files use the required parser-safe MDX SPDX comment and no frontmatter. --- Signed-off-by: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Persistent network policy exclusions with consistent restore/exclusion reporting across rebuilds/snapshots. * Opt-in MCP tool discovery via `mcp status --tools` with bounded, redacted authenticated traffic. * Improved HTTPS inference switching for custom endpoints and refreshed onboarding/model menu details. * Refined OpenShell gateway defaults for port `8080`, including more reliable readiness checks. * **Bug Fixes** * Prevent incorrect provider/model restoration after compatible-provider update failures. * Preserve managed MCP state after exec loss and tighten gateway/doctor status scoping. * **Tests** * Stronger, fail-closed release validation with hardened evidence/artifact handoff and bounded timeouts/retries. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Summary
The reviewed npm audit gate currently fails immediately when the registry returns an incomplete JSON response. This change retries only incomplete or timed-out scans within a fixed 138-second budget, continues to evaluate complete vulnerability reports immediately, and still fails closed when the retry budget is exhausted.
Changes
npm audit --omit=dev --jsonattempt to 45 seconds and retry incomplete scans after fixed 1-second and 2-second delays.Type of Change
Quality Gates
293ed408a. The final refresh adds only byte-identical upstream changes from merged PRs fix(security): update sandbox dependency fixes #7563 and fix(ci): build conflict trees from main #7578; the three PR-authored audit files are unchanged. Complete vulnerability reports still evaluate immediately, retry exhaustion remains fail-closed, and both transient and terminal diagnostics are redacted with negative regression coverage.Documentation Writer Review
no-docs-needed293ed408achanges only the internal reviewed-npm-audit helper and its tests relative to current main. The merge-only changes from fix(security): update sandbox dependency fixes #7563 and fix(ci): build conflict trees from main #7578 match main byte-for-byte. No user-facing CLI, configuration, API, or supported workflow contract changes. No comments were added; the new test titles precisely describe retry/backoff, timeout, non-timeout error, complete-report, and exhausted-budget behavior. No documentation or Fern build input changed.DGX Station Hardware Evidence
Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpx vitest run --project integration test/reviewed-npm-audit.test.ts test/reviewed-npm-audit-workflow.test.ts: 39 passed; the normal pre-push CLI TypeScript and package/tag version checks passed.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docsbuilds without warnings (doc changes only)Signed-off-by: Apurv Kumaria akumaria@nvidia.com