Source: https://github.com/argusappsec/argus (Go daemon, Apache-2.0, pre-1.0, 24 ADRs + design docs). Analyzed 2026-09-01. Companion analysis: docs/cloudflare-security-audit-skill-analysis.md (5 items from that report already implemented in commit 61e2c80 — not repeated here).
Different category from the Cloudflare skill: argus is an interactive
application-security agent platform, not a scanner pipeline. A Go daemon
(argusd) wrapping semgrep/gitleaks/osv-scanner as structured tools, driving
an open-ended LLM review loop humans converse with over TUI, GitHub PR
webhooks, and MCP. Differentiating ideas: (a) validated skill content — a
6-pass BOLA/IDOR/BFLA hunting methodology benchmarked against a labeled target
(VAmPI, 100% recall / 100% precision on that corpus) before shipping, with the
ground-truth oracle shipped as a regression check; (b) content-derived stable
finding IDs; (c) org-context (SOUL) prompt calibration; (d) strict lane
discipline ("pattern → tool, semantic → skill"); (e) prompt-injection
hardening of the untrusted-code review path. The daemon/channel/RBAC machinery
is product architecture baco ignores.
- Evidence:
pkg/skill/builtin/authz-audit/self-test-vampi.md— expected findings table (recall set, exact sink + rule_id + severity), expected-NOT findings (precision set, deliberately labeled near-misses), pass/fail criteria; loaded only for validation, never during real audits. - baco gap: nothing measures the LLM discovery/verification phases — every prompt change lands unmeasured.
- Mapping:
eval/harness: labeled fixture targets with vulnerable/secure aligned pairs + oracle JSON; scoring module reports recall (on vulnerable set) and precision (zero flags on secure twins); e2e run gated behind an env flag (needs real LLM), oracle/fixture validation always in CI.
- Evidence:
pkg/skill/builtin/authz-audit/SKILL.md— PASS 0 builds the ground model before judging (router style, canonical principal accessor, ownership/tenancy model, actual guard vocabulary); "'I can't find a guard in this file' is not a finding — it is an instruction to go read the call chain"; PASS 6 skeptical self-refutation gate before every emit ("the correctly-scoped sibling branch is SAFE — flagging it is the canonical false positive"; "default to NOT reporting if any guard chain is unresolved"). Naive LLM IDOR passes measure 78–88% FP. - Mapping: new ground-model authz hunt module + self-refutation gate section in the verification prompt.
- Evidence:
pkg/report/report.goComputeFindingID=sha256(rule_id + "\x00" + normalizeSnippet(snippet))[:12]; rule_id from a closed taxonomy; IDs survive refactors; a fix changes the snippet and auto-resolves the finding. - baco state: the key mechanism landed with the prior-runs store
(
src/run_store.rs::stable_finding_key, snippet-based). Remaining delta: a closed rule taxonomy (domain/CWE-sourced rule_id) stamped on findings.
- Evidence: "if a deterministic tool catches it reliably, the skill's only
job is to triage/confirm the tool's output"; adjacent classes emitted as
infounder a deterministic handoff rule_id for a future sibling module — "If you see an f-string SQL query while tracing a sink, that is not your finding." - Mapping: every hunt module declares a "Scope — stay in your lane" section: closed class ownership + out-of-scope list + info-severity handoff rule for adjacent observations.
- Evidence:
pkg/soul/soul.go— narrow structured profile (stack, infra, data sensitivity, where secrets live in production, risk tolerance) where every label renders as an instruction with meaning attached ("without this the model reads 'high' as 'only flag criticals'");secret_storageis a massive FP reducer; per-repo exception store curated via explicit writes. - Mapping:
[org_context]config section → rendered prompt block with meaning-attached text injected into discovery/verification.
- Evidence: ADR-0018 — untrusted reviews run read-only on the knowledge base and in ephemeral sessions ("an injection in reviewed code could poison MEMORY.md; a public-repo attacker could silently steer reviews of private code"); ADR-0019 — symlink resolution for path containment.
- Mapping: code-as-data framing in the phase prompts (instructions inside analyzed code are injection attempts, never obeyed); cross-run store already ingests only verified/gated outcomes; symlink containment in the indexer.
| Item | Reason |
|---|---|
| Daemon/platform architecture (TUI/MCP/Slack, webhooks, RBAC, audit log) | conversational product; baco is a batch pipeline |
pr-quick-check diff-scoped review |
PR-comment product mode |
| Webhook dedup + repo gating | GitHub App plumbing |
| Persona/identity layer | chat cosmetics |
| Memory-curator subagent | overlaps the cross-run store |
secret-rotation-plan skill |
analyst work-product, not a finding |
| Agent-loop safety nets | baco phases emit structured verdicts |
| Markdown+YAML report format | SARIF/JSON/HTML already cover it |
- "100%/100% on VAmPI" is a single tiny purpose-built target — the transferable asset is the oracle+blind-validation method, not the number.
- argus's LLM loop is open-ended tool-use; mappings target baco's structured phases, not a re-architecture.
- Repo is pre-1.0, schema-unstable; ADRs/design docs are the stable knowledge.