Skip to content

learjet5/VultureFlock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VultureFlock

A flock of "vulture" agents that turn idle Claude / Codex subscription quota into continuous C/C++ vulnerability auditing.

VultureFlock is a multi-agent system that drives Claude Code / Codex CLI agents to read and reason about C/C++ codebases the way a human researcher would, and emits evidence-backed Markdown bug reports. Scheduling is quota-aware: it spends only the subscription capacity you are not using, ramping each backend up to a configurable utilization target and then backing off until the usage window resets.

It is built for recall, not precision — it surfaces many plausible candidates with a self-checked evidence chain, and leaves serious verification / PoC generation to downstream systems.

Status: alpha, but functional end-to-end. The full pipeline runs as a persistent, quota-gated service (Repo Analyzer → Auditor → optional Build/PoC) and writes bucketed Markdown bug reports. It has produced evidence-backed candidate reports on real targets (libpng, php-src). Layout and APIs may still change.

What it does (and does not)

  • Does: continuously enumerate unaudited scopes in target C/C++ repos, dispatch auditor agents under a token budget, and write Markdown bug reports.
  • Does not: run fuzzing campaigns, ship a SAST rule engine, auto-fix code, or seriously validate bugs. PoC attempts (when a sanitizer build is available) are opportunistic and never gate report retention.

Architecture (high level)

Vulture brain (LLM director)   ── the SOLE work generator: reads a digest and decides
  │                               what to analyze / build / audit / PoC, balancing repos
  │                               and chasing productive areas (no deterministic work-gen)
  ▼
Controller (deterministic kernel)
  ├─ Job queue (SQLite)        ── single source of truth for *work*
  ├─ Expander                  ── turns the brain's intents into deduplicated job rows
  ├─ Memory (Markdown tree)    ── audit-coverage map; agents consult it before working
  ├─ Reports (Markdown tree)   ── deliverable + source of truth for *findings*,
  │                               bucketed per repo: high / medium / low / abandoned
  ├─ Quota-aware scheduler     ── per-backend, per-window (5h / 7d) usage caps
  └─ Backends                  ── Claude Agent SDK / Codex CLI (per-backend model/effort/sandbox)

Agent roles == job types:
  Repo Analyzer → (Build Agent) → Auditor → (PoC Attempter)

The brain is the only source of work; the controller below it makes no mining decisions — it just enforces safety (quota caps, concurrency, dependencies, budget) and dispatches each job to whichever backend sits furthest below its cap. The Auditor writes its report directly, so there is no separate reporter step. Disable the brain and the loop simply runs whatever is already queued.

Requirements

  • Python 3.12+
  • uv (recommended) or pip
  • At least one agent backend installed and logged in:
    • Claude: the claude CLI (Claude Code) + a logged-in subscription
    • Codex (optional): the codex CLI, logged in
  • For the optional Build/PoC stages only (do_build / do_poc): a C/C++ toolchain with Clang/LLVM + AddressSanitizer/UBSan. Tested with Clang 14; any reasonably modern Clang works. On an old Clang 11 runtime whose ASan aborts at startup (SetAlternateSignalStack mmap failure), set asan_options = "use_sigaltstack=0" in your config. If your runtime sandboxes build/PoC commands with ptrace (e.g. Codex's sandbox) so LeakSanitizer can't run, set asan_options = "detect_leaks=0" and/or run Codex unsandboxed with [backends.codex] sandbox = "danger-full-access". Auditing and reporting do not need a compiler — only the sanitizer build + PoC attempts do.

Install

# from a checkout
uv tool install .

# or, for development
uv venv
uv pip install -e ".[dev]"

Quickstart

vultureflock init                      # write vultureflock.toml
$EDITOR vultureflock.toml              # enable backends, set usage caps, add targets
vultureflock target add <repo-url>     # (or edit the [[targets]] blocks directly)
vultureflock doctor                    # smoke-test each enabled backend
vultureflock run                       # start the persistent auditing loop (quota-gated)
vultureflock status                    # job queue + per-backend quota (5h/7d used vs cap)
vultureflock report list|index|show <id>   # browse reports / rebuild the index
vultureflock audit <repo> <scope>      # inject a high-priority audit into a running loop

Configuration

All settings live in vultureflock.toml — run vultureflock init to write a fully-commented starter (also browsable at config.example.toml). It covers per-window usage caps (global or per backend), concurrency, per-backend model / effort / sandbox, per-job budgets and timeouts, the [brain] director, the optional do_build / do_poc stages, and target projects. PoC attempts run in throwaway scratch/<repo>__<id>/ dirs bounded by a size-based GC; only a confirmed PoC has its whole attempt dir moved intact to poc/<repo>/<id>/ — the reproducible first-scene, kept out of the GC's reach. Mutable fields hot-reload while the loop runs; credentials come from each CLI's own login.

OOM protection

PoC/build agents compile and run arbitrary harnesses, and a malformed or oversized input can make one allocate without bound and OOM the whole machine (which usually has no swap, so the kernel kills processes abruptly). Three layers guard against this:

  1. ASan RSS self-limitasan_options = "hard_rss_limit_mb=N …" makes a sanitizer harness abort itself once its resident memory passes N, before it can exhaust the box. Inherited by both backends' harnesses.
  2. Per-agent cgroup cappoc_memory_max_mb runs each PoC/build agent's whole process tree in a transient systemd-run --scope with a hard MemoryMax (OOMPolicy=kill), so a runaway harness OOM-kills only its own scope. Applies to Codex (Claude spawns inside its SDK and leans on layers 1 and 3).
  3. Memory watchdog — if system MemAvailable falls below mem_watchdog_min_mb, a background thread kills the heaviest agent subtree to keep the box alive.

A PoC that is killed for OOM (or whose harness is Killed/exits 137) is treated as inconclusive, never a trigger, and the finding is abandoned, not retried — a memory bomb only repeats. Set poc_memory_max_mb / mem_watchdog_min_mb to 0 to disable a layer.

Per-project policy

Every triggerable crash is not a reportable bug. A policies/<project>.md file (under the work dir, operator-authored) lets you impose a project's real reporting bar — e.g. a VRP's in-scope rules — on mining and trigger-evaluation. Two optional sections:

  • ## Harness — pins which harness to build/use (it still decides how to compile it), with an optional **Build options:** line. E.g. force the project's own CLI rather than a fuzz target. The pin also governs trigger evaluation: the PoC stage may only establish a trigger through the pinned harness, so a crash reachable solely by some other entry point comes back triggered=false. (Clear the project's sanitizer build to re-build onto a newly-pinned harness.)
  • ## Reporting constraints — free-text rules for what counts as reportable (e.g. "memory-safety only; assertion failures / API-misuse / OOM are out of scope"). The auditor avoids out-of-scope classes, and the PoC stage demotes a triggered bug that violates them to the low bucket — kept as a record (with poc_reportable: false and a reason) but neither promoted nor reported. This keeps reportable output to bugs that actually clear the bar. No policy file ⇒ no constraints (default behaviour).

Roadmap

The pipeline above is built and runs end-to-end. Not yet done:

  • Multi-account quota pooling — rotate across several Claude / Codex logins to widen the idle-capacity envelope. Today VultureFlock uses whichever account each CLI is logged into; vultureflock account only reports current usage.
  • Async brain + richer steering — the director plans in one blocking step every interval; making it non-blocking, with finer control over the fleet, would let it react and steer faster.

License

MIT

About

Multi-agent system for bug discovery.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages