Changelog

What changed, and why.

The recent history below is a copy of CHANGELOG.md — see that file for the complete record back to v0.1.0.

1.2.34

2026-09-12

Fixed

  • Cloud LLM providers were broken by a decommissioned default model. Groq retired llama-3.1-70b-versatile, but Argus hardcoded it as the Groq model — so selecting Groq (with a perfectly valid API key) produced a misleading "provider: groq — reachable" in argus status while every actual scan call failed with an HTTP 400. Found live: a valid key returned 200 from the API, but the hardcoded model was no longer served. Three fixes: - Updated the stale defaults to currently-served models (Groq → openai/gpt-oss-20b, verified working with JSON mode; Gemini → gemini-2.0-flash, since gemini-1.5-flash is being retired). - The cloud model is now config-overridable ([cloud].<provider>_model in ~/.argus/config.toml), so the next time a provider rotates a model name it can be corrected without waiting for a release — the model was previously hardcoded with no override. - available() for OpenAI-compatible providers (Groq/OpenRouter) now verifies the model is actually in the provider's served list instead of only checking that a key is set, so argus status stops reporting a dead model as reachable. Falls back to the key check when offline.

1.2.33

2026-09-12

Fixed

  • The bundled CLI reported a stale version after an in-place desktop upgrade — and so did every SBOM/VEX export's tool-version field. The CLI ships as a PyInstaller onedir whose *.dist-info directory is named with the release version, and the NSIS installer upgrades by overlaying files without removing ones the new version no longer has. So an upgrade left the previous version's argus_panoptes-<old>.dist-info orphaned beside the new one, and importlib.metadata resolved whichever it saw first — observed live: a 1.2.30→1.2.32 in-place upgrade reported argus 1.2.30. Two fixes: version resolution now takes the highest version when more than one dist-info is present (self-healing, and correct for a security tool that stamps its own version into audit artifacts), and the Windows installer now wipes the argus-cli bundle before reinstalling so only one dist-info ever exists. User data in ~/.argus is untouched. Found while reinstalling and testing the app end-to-end on a repo, a website, and a local folder — all three target types verified working against real targets.

1.2.32

2026-09-10

Fixed

  • The desktop app went completely silent during LLM reasoning, for as long as tens of minutes. Enrichment is one sequential LLM call per finding, so on a local model a scan sits in that step for a very long time — and the only progress reporting was a Rich progress bar, which exists for a human at a terminal. The desktop app reads the sentinel event stream instead, so it showed "LLM reasoning over N finding(s)" and then nothing at all, which is indistinguishable from a hang and was reported as one. All three reasoning passes (enrichment, --deep review, --taint tracing) now stream real per-item progress to the live feed. Regression-tested.
  • A finished agent's DONE tag could disappear mid-run, and the "N done" counter count down. Live Attack derived per-agent completion by scanning the retained feed, but the feed is capped at 200 lines and a real audit emits far more than that — so once an agent's "sweep complete" line aged out, that agent silently reverted to looking like it was still running. Completion is now recorded as the event arrives, which is the only point the information exists. The same header could also report more agents done than were running, because the engine emits "Static scan complete…" under a pseudo-agent named system that was tallied as if it were one of the roster; the count is now taken over the agents actually in the run.

Changed

  • The public surfaces that restate the release version or the changelog — the README's pre-commit rev and version range, the download page's version, and the site's changelog page and RSS feed — are now generated from CHANGELOG.md and pyproject.toml by scripts/sync_release_docs.py, and CI fails when they drift. They had gone stale twice: the site once sat eighteen releases behind, then fell behind again on the very next tag.
  • ROADMAP.md is closed out. The last two open items are resolved with reasons recorded: D4 (GitHub App) — the outcome already ships via the Action and argus pr-comment; what remained needed a hosted webhook receiver, which contradicts the local-first promise. D5 (VS Code extension) — superseded by the MCP server, which puts scan/attack/fix inside every MCP-speaking editor today rather than one.

1.2.31

2026-08-14

Fixed

  • Desktop app showed a blind "the scan failed" / "the attack failed" on every CLI failure, discarding the real reason. out.error() (used by every intentional CLI failure — policy gates, --fail-on, caught exceptions) prints through Rich to stdout, not stderr; the desktop shell only forwarded sentinel-prefixed stdout lines to the live feed and silently dropped everything else, so a failure with nothing on stderr fell back to a hardcoded generic message. The Rust side now keeps a rolling tail of raw stdout and uses it as the real error message when stderr comes back empty.
  • "Strike the app" against a bare repo path (no running URL) always failed in the desktop app — the bundled CLI never included the docker Python package (a pure-Python client for a locally-running Docker daemon, excluded to keep the installer lean), so every auto-sandboxed Phase 2 attack hit "The 'docker' Python package isn't installed" regardless of Docker Desktop being available. Now bundled (packaging/argus.spec, desktop-release.yml builds with the sandbox extra) — verified end to end against a real cloned repo, past the point that used to fail and into an actual Docker sandbox build.
  • CI: pinned ruff's lint rule set (select = ["E4","E7","E9","F"]) — ruff's own "no select configured" default had silently grown across versions and broke the lint step with no code change.
  • CI: capped the mcp extra below 2.0 (mcp>=1.28.1,<2) — mcp 2.0.0 dropped/relocated mcp.server.fastmcp, which argus/mcp_server.py imports directly, breaking every MCP server test.
  • Website: the "attack swarm" (19 agents) and "meets you where you work" (6 cards) grids used CSS Grid with auto-fit/auto-fill; since neither count divides evenly into the columns that fit at typical widths, the leftover grid cells exposed the container's own background as flat, unlabeled boxes. Switched both to flexbox so the last row's items stretch to fill the width instead of leaving empty cells.

1.2.30

2026-08-13

Changed

  • New app icon and logo mark (the eye-covered figure inside a compass ring) across every platform (Windows .ico, macOS .icns, all PNG sizes) and the in-app mark on the Live Attack idle screen.

1.2.29

2026-08-13

Changed

  • GUI: removed the "estimated watch" duration on Set the Watch — it was computed from placeholder multipliers with no real timing data behind them (a Deep sweep of the full roster showed 6.7h, which read as absurd).
  • GUI: Live Attack now shows real per-agent completion. Every attack agent already emits its own "sweep complete" event when it finishes; that was streaming into the feed unused. Agent tiles now show a DONE tag and stop their running animation once that real event lands.
  • GUI: Dashboard's posture panel now reads "of 19" (the real attack-agent roster size) instead of "of 51" (the vulnerability-class catalogue the eye field itself binds to) — those are two different real counts, and showing 51 next to "19 agents" elsewhere in the app read as inconsistent.

1.2.28

2026-08-13

Changed

  • GUI: redesigned all three screens (The Watch, Set the Watch, The Register) to the pinned "keeper's watch-ledger" visual world — dotted-leader rows, Bodoni Moda/IBM Plex Mono typography, a single gold accent with grave-red reserved for critical findings, no cards/gradients/glow.
  • GUI: the hundred-eyes field on The Watch is a real rotating Fibonacci-sphere canvas (ported from the pinned design reference), sized and positioned correctly regardless of window size; every screen now fits the app window with no page-level scrolling, with only genuinely long lists (agent roster, findings) scrolling in their own bounded lane.
  • GUI: raised the desktop window's minimum size (960×640 → 1180×760) to match what the redesigned layout actually needs.

1.2.27

2026-07-22

Fixed

Found via a rigorous audit (parallel deep-code review + live end-to-end Docker/LLM testing) of everything shipped in 1.2.25/1.2.26:

  • A sandboxed target's port was published to every network interface (0.0.0.0), not just the scanning machine's loopback, for the whole duration of any sandboxed attack.
  • A generated sandbox container could leak a real repo's .git/.env — the static-site/PHP auto-sandbox cases serve any copied file verbatim. Now excluded from the build context, restored to the exact prior repo state afterward either way.
  • The LLM Dockerfile fallback broke on a markdown-fence-wrapped response (common even with strict JSON mode), silently discarding an otherwise-correct answer.
  • The DB-connection-string secret fix from 1.2.25 had its own real bug: either side of a credential pair merely looking like a common word (e.g. a username literally being "token") suppressed the entire finding — hiding a genuinely random, real password next to it. Also extended placeholder recognition to ${VAR}/{{var}}/%VAR% conventions, and fixed a long-line skip that was discarding the secret scanner's high-confidence regex pass (not just the entropy pass) on minified/bundled files.
  • Secrets committed then reverted in git history were never caught for the generic-secret pattern class — the single most common "oops" shape — due to an unexplained exclusion.
  • Several smaller robustness fixes: attack-provider resolution no longer adds a real network delay to plain --url attacks that never need it; capped an unbounded directory walk and file reads in the new stack- detection code against adversarial/oversized repos.

1.2.26

2026-07-22

Added

  • Phase 2 can now sandbox almost any repo, not just a fixed stack list. When no deterministic stack probe recognizes a repo (Go, Rust, Java, .NET, unusual layouts, ...) and an LLM provider is configured, Argus asks it to identify the stack and write a Dockerfile — verified before it's ever trusted (the sandbox actually checks the container becomes reachable, so a wrong guess fails cleanly instead of silently reporting "0 findings, clean"). Includes one corrective retry for the common multi-stage glibc/musl mismatch mistake. Verified end-to-end against a real Go repo with no Dockerfile. Raw-scan-only mode (no provider configured) is unaffected.

1.2.25

2026-07-22

Fixed

  • False-positive "hardcoded DB connection string" secret. A .env.example-style placeholder like postgresql://USER:PASSWORD@HOST was flagged as a real secret (in the working tree and git history) because the placeholder filter was never applied to that detector at all. Now checks the actual matched username/password against common placeholder field-names — a real credential in the same shape is still caught.
  • Phase 2 (attack) now works for two very common no-Dockerfile cases: plain static sites and basic PHP apps. Previously only Django, Flask, FastAPI, Rails, and Node were auto-sandboxed, so a large share of real-world GitHub repos with no Dockerfile never got attacked at all, even with Docker running. Verified end-to-end (built and ran both generated Dockerfiles for real).

1.2.24

2026-07-22

Changed

  • Smoother, crisper desktop UI. Every interactive element now eases its hover/active state over a uniform 140ms instead of snapping, action buttons give a subtle press-down on click, and navigating between screens glides with a quick fade-and-rise instead of a hard cut. Purely interaction polish — the theme is unchanged, and reduced-motion is respected.

1.2.23

2026-07-22

Added

  • Argus now clearly reports when a scan is blocked by bot protection. Scanning a Vercel/Cloudflare/WAF-protected site used to produce a thin, low-risk result that looked like a clean bill of health when really the scan never got past the challenge page. ReconBot now detects the common anti-automation providers (Vercel, Cloudflare, Imperva, Sucuri, AWS WAF, generic CAPTCHA walls) and reports a plain-language notice that the real app wasn't reached and the results don't reflect its actual security.
  • Two clear scan modes in the desktop app: Code vs Website. New Scan now starts with a single choice — scan a repo/local folder (reads the source, with an optional Docker-sandboxed attack), or scan a live website URL (attacks it directly) — instead of two overlapping fields and toggles. The Dashboard gains matching "Scan code" / "Scan a website" quick-start buttons.

1.2.22

2026-07-22

Fixed

  • Reports no longer show a misleading "closed since" diff across different targets. A live-URL attack could display a previous local code scan's findings (SQL injection, YAML deserialisation, etc. — things a URL attack can't produce) as if they'd been fixed on the current target. The since-last-scan diff now renders only when the previous scan was the same target.

1.2.21

2026-07-22

Added

  • A fresh desktop install now starts with an empty Recent Scans list. Scan history lives in ~/.argus (which survives an uninstall/reinstall), so a reinstalled app used to show the previous install's scans. The app now records each install's moment and shows only scans run after it; a reinstall resets the list, and new scans accumulate from there. The CLI's argus history still shows everything.

1.2.20

2026-07-22

Fixed

  • argus mcp-server crashed with a raw traceback on a base install missing the optional [mcp] extra, instead of the clean install-hint message every other optional integration (semgrep, pip-audit, trivy, docker) already gives. Now prints pip install 'argus-panoptes[mcp]' and exits cleanly.

1.2.19

2026-07-21

Fixed

  • Blind SSRF/SQLi/XSS callback detection silently failed against Argus's own Docker-sandboxed targets. Found via rigorous testing with a real vulnerable sample app: attacking an already-running URL correctly confirmed a blind SSRF, but attacking the exact same app through argus attack <repo-path> (Phase 2's own Docker-sandbox flow) always reported 0 confirmed, with no error anywhere — the callback URL handed to a sandboxed target said 127.0.0.1, which inside that container means its own loopback, not the host running the callback listener. Now advertises host.docker.internal to targets Argus sandboxed itself, verified end-to-end.

1.2.18

2026-07-16

Fixed

  • Phase 2 was attacking github.com itself when given a .git repo URL. Pointing Argus at https://github.com/user/repo.git for "Strike the app" sent real HTTP requests straight at GitHub's own server and reported its ordinary responses (redirects, 404s) as confirmed vulnerabilities in the target repo — entirely fabricated findings. A git clone URL is now refused as an attack target from every entry point (CLI positional target, --url, and the desktop app's URL field) with a clear explanation, instead of silently attacking the wrong host.

1.2.17

2026-07-16

Fixed

  • Desktop app window going fully "Not Responding" mid-scan under heavy local-LLM/CPU load — every command that shells out to the CLI now runs strictly off the window's own thread, and the CLI child runs at a lower OS priority so it can't starve the GUI.
  • Glitchy double-tooltip on the vulnerability-check "eyes" (a native browser tooltip and the custom hover panel firing at once).
  • Risk-score number/"100" baseline misalignment on the Reports screen, and inconsistent digit spacing in Dashboard's recent-scans risk column.

1.2.16

2026-07-16

Fixed

  • A systematic full-codebase audit (GUI, backend pipeline, attack agents) found and fixed: the provider-display bug from 1.2.15 recurring in New Scan and the sidebar badge; argus attack never applying suppressions (an ignored finding kept resurfacing); three more attack agents (PromptInjectionAgent, RaceCondition, IDORHunter) missing the fallback-baseline false-positive guard shipped for BusinessLogicAgent in 1.2.14; synthesized attack-chain findings always reporting flat "high" confidence regardless of a weak constituent finding; two unguarded concurrent-write races in local state files; and three config options that were silently no-ops. Full detail in the commit message.

1.2.15

2026-07-16

Fixed

  • Settings — switching to a cloud LLM provider (Groq/Gemini/Claude/OpenRouter) appeared to silently fail. The status refresh right after a click was overwriting the selection with whatever the backend resolved to (which falls back to Local GPU whenever no API key is saved yet) instead of what was actually clicked. The picker now shows your real selection and a "selected — add an API key below to activate it" hint when a key is needed.
  • "Strike the app" alone didn't skip "Read the code." Deselecting "Read the code" and leaving only "Strike the app" on still ran full static analysis first, which tries to git clone the target — fatal (and instant, with a useless "the attack failed") against a live URL that isn't a repo. The desktop app now has a real Phase-2-only ("attack") mode that goes straight at the target, matching what argus attack already did from the CLI.
  • New Scan now has a separate field for a running app's URL, instead of one box overloaded for both "read this repo" and "attack this URL."
  • Live Attack's Cancel button did nothing during "Read the code"-only scans — the backend never recorded a killable process handle for that path, so Cancel was silently a no-op and the scan ran to completion regardless.
  • "Read the code"-only scans showed zero progress for their entire duration, stuck on a static "this is usually quick" message even after several minutes on a large codebase — indistinguishable from a freeze. Static analysis now streams the same kind of live per-step feed Phase 2 already had.

Full history back to v0.1.0 on GitHub →