Skip to content

feat(cli): phase-aware scan progress and clearer verbosity flags#122

Closed
eFAILution wants to merge 2 commits intofeat/containers-build-vs-image-and-schema-headerfrom
feat/scan-progress-and-flag-reshape
Closed

feat(cli): phase-aware scan progress and clearer verbosity flags#122
eFAILution wants to merge 2 commits intofeat/containers-build-vs-image-and-schema-headerfrom
feat/scan-progress-and-flag-reshape

Conversation

@eFAILution
Copy link
Copy Markdown
Collaborator

Description

Stacked on #121. Closes the "I don't know what argus is stuck on" gap surfaced during the option-A schema review — replaces the static "Running container scan" spinner with phase-aware progress, and re-shapes the verbosity flags into orthogonal, named flags.

Changes Made

  • Added new scanner/workflow
  • Modified existing scanner/workflow
  • Updated documentation
  • Fixed bug
  • Other (please specify)

Details

1. Phase-aware container scan progress

ContainerEngine accepts an optional progress_callback that's invoked at each phase transition per image: pull/build on start, scan after build completes, done on success or failure. The CLI installs a callback that routes phase events to the right surface based on the user's flag mix:

Mode Phase events go to
Default (TTY) The spinner's status text — updates in place ([2/4] scanner-opengrep — scan (12s))
--no-spinner OR non-TTY [idx/total] name — phase (Ns) lines on stderr — useful for CI logs and step-away terminals
--quiet No-op (phase progress suppressed)
--verbose / --debug No-op (logger streams full output; emitter would duplicate)

2. Verbosity flag re-shape — three orthogonal flags

The old -v / --verbose / -vv ladder was confusing — --verbose and -v looked like the same thing, then -vv was a syntactically-similar third option meaning something different. Replaced with named flags whose names announce their purpose:

Flag Concern Behavior
(no flag) Default Phase-aware spinner with INFO-level engine logging
--quiet / -q Log verbosity Suppress per-phase INFO lines + bump engine logger to WARNING. Spinner still draws unless --no-spinner is also passed
--debug Full firehose Subprocess output, vulnerability-DB updates, every engine log line
--verbose Backward-compatible alias for --debug Existing CI scripts keep working unchanged
--no-spinner (existing) UI rendering Don't draw the animation

--quiet and --no-spinner target different concerns and compose orthogonally — same convention as git -q, pip -q, pytest -q (suppress info, don't touch UI rendering).

Four discrete UX modes through three orthogonal flags:

Invocation Spinner INFO lines Debug noise
argus scan ✅ updates per phase ✅ engine INFO logging
argus scan --quiet ✅ static ❌ (WARNING+ only)
argus scan --no-spinner ✅ persistent scrollback
argus scan --quiet --no-spinner ❌ (WARNING+ only)
argus scan --debug (or --verbose) ❌ auto-disabled

3. Documentation

docs/cli-reference.md gets a new "Output and verbosity" section between Global Options and Commands, walking through the four most useful modes as a table and noting how compose patterns produce additional modes. Added via the doc generator (scripts/ci/gen_cli_docs.py) so it survives every regeneration.

_configure_logger(args) is the new central helper that maps the flag combination to a stream-handler level (DEBUG / INFO / WARNING). _cmd_container_scan now uses it instead of calling get_logger directly with a verbose bool.

Verification

End-to-end tested locally with all four modes:

  • argus scan container --no-spinner emits [1/1] scanner-bandit — pull (0s) then [1/1] scanner-bandit — scan (0s) as scrollback
  • argus scan container --quiet --no-spinner runs silent except ERROR lines and the final summary
  • argus scan container --debug and --verbose both stream the full firehose unchanged from today
  • Default-mode TTY scan: spinner updates per phase per image

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Tested with different scanner combinations

Test Results

  • New test file argus/tests/test_progress_emitter.py13 unit tests covering each combination of --quiet, --verbose, --debug, --no-spinner, plus TTY-vs-non-TTY routing. Validates that:
    • --quiet returns a no-op emitter
    • --verbose/--debug return no-ops (logger handles output)
    • --no-spinner non-quiet non-verbose: phase events print as scrollback
    • Spinner-disabled flag: still falls back to print
    • Spinner-enabled: routes to update_message
    • --quiet overrides spinner-update path
  • Full SDK suite: 1580 passed, 8 skipped (was 1567 before; +13 from this PR)
  • docs/cli-reference.md regenerated; pre-commit Check CLI docs are up to date passes

Security Considerations

  • No security impact

AI Context Updates (.ai/)

  • N/A - No .ai/ updates needed (CLI flag changes don't affect architecture or workflows)

Checklist

  • Code follows project style guidelines
  • Documentation updated (cli-reference.md "Output and verbosity" section + CLI flag help text)
  • Changelog updated (if applicable)
  • All tests pass
  • Reviewed by at least one maintainer
  • Reviewed CONTRIBUTING.md guidelines

For New Scanners/Actions (if applicable)

  • N/A — modifying CLI surface only, no scanner changes

Follow-ups (not in this PR)

  • Apply the same progress-callback pattern to source scans (_cmd_source_scan). Today the source-scan path also has a static "Running scanners" spinner that doesn't update per scanner. Same engine-level callback shape would work; one short follow-up PR.
  • Per-tool granularity inside scan_image (trivy / grype / syft phases). Today's --debug already shows them as logger lines; the spinner could surface them too. Worth doing if user feedback suggests image-level granularity isn't enough.

eFAILution added 2 commits May 6, 2026 10:11
Two coupled UX improvements that close the "I don't know what argus
is stuck on" gap surfaced during the option-A schema review.

1. Phase-aware container scan progress.

   ContainerEngine accepts an optional ``progress_callback`` that's
   invoked at each phase transition per image: ``pull``/``build`` on
   start, ``scan`` after build completes, ``done`` on success or
   failure. The CLI installs a callback that routes phase events to
   the right surface based on the user's flag mix:

   * Default (TTY): the spinner's status text updates in place
     (``[2/4] scanner-opengrep — scan (12s)`` instead of the static
     "Running container scan").
   * --no-spinner OR non-TTY: phase events print as persistent
     ``[idx/total] name — phase (Ns)`` lines on stderr — useful for
     CI logs and step-away terminals where the rolling spinner is
     useless.
   * --quiet: no-op (phase progress suppressed).
   * --verbose / --debug: no-op (the logger already streams full
     INFO/DEBUG output; the progress emitter would just duplicate it).

2. Verbosity flag re-shape — three orthogonal flags, one mental
   model per flag.

   The ``-v`` / ``--verbose`` / ``-vv`` ladder was confusing.
   Replace with named flags whose names announce their purpose:

   * (no flag) — phase-aware spinner with INFO-level engine logging.
     The user sees enough to know the scan is making progress.
   * --quiet / -q — suppress per-phase INFO lines and bump the
     engine logger to WARNING. The spinner still draws unless
     --no-spinner is also passed; final summary still prints.
   * --debug — full firehose: subprocess output, DB updates, every
     engine log line. ``--verbose`` is preserved as a backward-
     compatible alias so existing CI scripts keep working.

   The ``--quiet`` and ``--no-spinner`` flags target different
   concerns and compose orthogonally:
     * --quiet (log verbosity): suppress info messages
     * --no-spinner (UI rendering): don't draw the animation
   This matches *nix convention — git -q, pip -q, pytest -q all
   suppress info but don't touch UI rendering.

   New helper _configure_logger(args) maps the flag combination to
   a stream-handler level: --verbose/--debug to DEBUG, --quiet to
   WARNING, default to INFO. _cmd_container_scan now uses it.

Tests: 1580 passing (was 1567; ten more progress-emitter tests
covering each combination of --quiet, --verbose, --debug,
--no-spinner, and TTY-vs-non-TTY routing).

CLI reference regenerated for the new flags.
The four output-control flags (--quiet, --no-spinner, --debug,
--verbose) each get individual help text in the auto-generated per-
command tables, but the *compose pattern* — the orthogonality of log-
verbosity (--quiet) vs UI rendering (--no-spinner) and the four UX
modes that fall out — wasn't anywhere in the docs. The cli-reference
header warns "Do not edit manually", so the new section is added via
``scripts/ci/gen_cli_docs.py`` so it survives every regeneration.

Section sits between Global Options and Commands, displaying a four-
row table with When-to-use and What-you-see columns plus a one-line
note on the additional modes that fall out from composing flags.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 88.70968% with 14 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
argus/cli.py 66.66% 13 Missing ⚠️
argus/container/engine.py 94.11% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@eFAILution
Copy link
Copy Markdown
Collaborator Author

Folded into #121 — same diff. Merging through #121 once CI confirms.

@eFAILution eFAILution closed this May 6, 2026
@eFAILution eFAILution deleted the feat/scan-progress-and-flag-reshape branch May 6, 2026 14:26
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔒 Argus Container Security Scan

Branch: feat/scan-progress-and-flag-reshape
Commit: f525552

📊 Combined Findings Summary

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low 📦 Total 🔢 Unique
1 22 67 64 154 154

Scanned: 4 containers | Build Failures: 0

📦 Container Breakdown

Container Image 🚨 Crit ⚠️ High 🟡 Med 🔵 Low Total Unique Status
cli ghcr.io/huntridge-labs/argus/cli:f5255525ef441d22932fa57272f2be0123b81d57 1 11 16 1 29 29
scanner-bandit ghcr.io/huntridge-labs/argus/scanner-bandit:f5255525ef441d22932fa57272f2be0123b81d57 0 0 2 0 2 2
scanner-opengrep ghcr.io/huntridge-labs/argus/scanner-opengrep:f5255525ef441d22932fa57272f2be0123b81d57 0 7 44 63 114 114
scanner-supply-chain ghcr.io/huntridge-labs/argus/scanner-supply-chain:f5255525ef441d22932fa57272f2be0123b81d57 0 4 5 0 9 9

🔍 Detailed Findings by Container

🚨 cli - 29 vulnerabilities (23 unique)

Image: ghcr.io/huntridge-labs/argus/cli:f5255525ef441d22932fa57272f2be0123b81d57

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
1 11 16 1 29 23
🔷 Trivy Scanner (29 findings, 23 unique)
CVE Severity Package Version Fixed
CVE-2025-68121 🚨 CRITICAL stdlib v1.24.11 1.24.13, 1.25.7, 1.26.0-rc.3
CVE-2026-32280 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32281 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32283 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-33810 ⚠️ HIGH stdlib v1.26.1 1.26.2
CVE-2025-61726 ⚠️ HIGH stdlib v1.24.11 1.24.12, 1.25.6
CVE-2025-61728 ⚠️ HIGH stdlib v1.24.11 1.24.12, 1.25.6
CVE-2026-25679 ⚠️ HIGH stdlib v1.24.11 1.25.8, 1.26.1
CVE-2026-32280 ⚠️ HIGH stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32281 ⚠️ HIGH stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32283 ⚠️ HIGH stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-34040 ⚠️ HIGH github.com/docker/docker v28.5.2+incompatible 29.3.1
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A
CVE-2026-6357 🟡 MEDIUM pip 26.0.1 26.1
CVE-2026-32282 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32288 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32289 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2025-11579 🟡 MEDIUM github.com/nwaples/rardecode/v2 v2.1.0 2.2.0
CVE-2025-58058 🟡 MEDIUM github.com/ulikunitz/xz v0.5.12 0.5.15
CVE-2025-47914 🟡 MEDIUM golang.org/x/crypto v0.35.0 0.45.0
CVE-2025-58181 🟡 MEDIUM golang.org/x/crypto v0.35.0 0.45.0
CVE-2025-61730 🟡 MEDIUM stdlib v1.24.11 1.24.12, 1.25.6
CVE-2026-27142 🟡 MEDIUM stdlib v1.24.11 1.25.8, 1.26.1
CVE-2026-32282 🟡 MEDIUM stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32288 🟡 MEDIUM stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32289 🟡 MEDIUM stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-33997 🟡 MEDIUM github.com/docker/docker v28.5.2+incompatible 29.3.1
CVE-2026-41506 🟡 MEDIUM github.com/go-git/go-git/v5 v5.17.2 5.18.0
CVE-2026-27139 🔵 LOW stdlib v1.24.11 1.25.8, 1.26.1
⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype

🟡 scanner-bandit - 2 vulnerabilities (2 unique)

Image: ghcr.io/huntridge-labs/argus/scanner-bandit:f5255525ef441d22932fa57272f2be0123b81d57

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
0 0 2 0 2 2
🔷 Trivy Scanner (2 findings, 2 unique)
CVE Severity Package Version Fixed
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A
CVE-2026-6357 🟡 MEDIUM pip 26.0.1 26.1
⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype

⚠️ scanner-opengrep - 114 vulnerabilities (50 unique)

Image: ghcr.io/huntridge-labs/argus/scanner-opengrep:f5255525ef441d22932fa57272f2be0123b81d57

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
0 7 44 63 114 50
🔷 Trivy Scanner (114 findings, 49 unique)
CVE Severity Package Version Fixed
CVE-2026-4878 ⚠️ HIGH libcap2 1:2.75-10+b8 N/A
CVE-2025-69720 ⚠️ HIGH libncursesw6 6.5+20250216-2 N/A
CVE-2026-29111 ⚠️ HIGH libsystemd0 257.9-1~deb13u1 N/A
CVE-2025-69720 ⚠️ HIGH libtinfo6 6.5+20250216-2 N/A
CVE-2026-29111 ⚠️ HIGH libudev1 257.9-1~deb13u1 N/A
CVE-2025-69720 ⚠️ HIGH ncurses-base 6.5+20250216-2 N/A
CVE-2025-69720 ⚠️ HIGH ncurses-bin 6.5+20250216-2 N/A
CVE-2026-27456 🟡 MEDIUM bsdutils 1:2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM bsdutils 1:2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM libblkid1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libblkid1 2.41-5 N/A
CVE-2026-4046 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-4437 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-4438 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-5435 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-5450 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-5928 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-6238 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-4046 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-4437 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-4438 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-5435 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-5450 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-5928 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-6238 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-27456 🟡 MEDIUM liblastlog2-2 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM liblastlog2-2 2.41-5 N/A
CVE-2026-34743 🟡 MEDIUM liblzma5 5.8.1-1 N/A
CVE-2026-27456 🟡 MEDIUM libmount1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libmount1 2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM libsmartcols1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libsmartcols1 2.41-5 N/A
CVE-2026-40225 🟡 MEDIUM libsystemd0 257.9-1~deb13u1 N/A
CVE-2026-40226 🟡 MEDIUM libsystemd0 257.9-1~deb13u1 N/A
CVE-2026-4105 🟡 MEDIUM libsystemd0 257.9-1~deb13u1 N/A
CVE-2026-40225 🟡 MEDIUM libudev1 257.9-1~deb13u1 N/A
CVE-2026-40226 🟡 MEDIUM libudev1 257.9-1~deb13u1 N/A
CVE-2026-4105 🟡 MEDIUM libudev1 257.9-1~deb13u1 N/A
CVE-2026-27456 🟡 MEDIUM libuuid1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libuuid1 2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM login 1:4.16.0-2+really2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM login 1:4.16.0-2+really2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM mount 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM mount 2.41-5 N/A
CVE-2026-5958 🟡 MEDIUM sed 4.9-2 N/A
CVE-2026-5704 🟡 MEDIUM tar 1.35+dfsg-3.1 N/A
CVE-2026-27456 🟡 MEDIUM util-linux 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM util-linux 2.41-5 N/A
CVE-2026-27171 🟡 MEDIUM zlib1g 1:1.3.dfsg+really1.3.1-1+b1 N/A
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A

...and 64 more

⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype

⚠️ scanner-supply-chain - 9 vulnerabilities (9 unique)

Image: ghcr.io/huntridge-labs/argus/scanner-supply-chain:f5255525ef441d22932fa57272f2be0123b81d57

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
0 4 5 0 9 9
🔷 Trivy Scanner (9 findings, 9 unique)
CVE Severity Package Version Fixed
CVE-2026-32280 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32281 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32283 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-33810 ⚠️ HIGH stdlib v1.26.1 1.26.2
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A
CVE-2026-6357 🟡 MEDIUM pip 26.0.1 26.1
CVE-2026-32282 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32288 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32289 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype


Generated by Argus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant