Quickstart Β· Architecture Β· Roadmap Β· Contributing
Status: Pre-alpha, but real. Every command below actually runs β
ward scanexecutes a real multi-scanner + agent pipeline today, not a roadmap promise. The core verification loop is closed:ward scan --llm-provider ollama --sandboxdetects a finding, generates a proof-of-concept, runs it in an isolated Docker sandbox, and β only if the exploit actually fires β climbs to theDYNAMIC_POCrung andVERIFIED, then generates a patch and puts it through four validation gates. See Β§ Roadmap for the exact phase-by-phase state, and ROADMAP.md for the full breakdown with evidence for every line.π Single source of truth: the Master Project Specification v1.0 is approved and frozen. Architecture changes only via ADRs.
AI writes a large and growing share of the world's code, and studies repeatedly find that 30β40% of AI-generated code ships with security flaws. Existing tools each see only part of the picture:
| Tool class | What it does well | Where it falls short |
|---|---|---|
| Static analyzers (Semgrep, CodeQL, Bandit) | Fast, broad pattern matching | Can't tell if a match is reachable or exploitable β drowns teams in false positives |
| LLM reviewers | Reason about intent and context | Hallucinate, and can't prove anything |
| Almost every tool | Detects | Rarely closes the loop with a fix it can demonstrate actually works |
CortexWard is not another LLM wrapper. It's an autonomous security engineer: it builds a real understanding of a codebase, gathers evidence about each potential vulnerability, and only escalates or fixes what it can substantiate.
Instead of a binary "did an exploit run?", CortexWard assigns each finding the strongest feasible evidence and calibrates its confidence accordingly β climbing higher only when the evidence earns it:
| Rung | Evidence | Meaning |
|---|---|---|
| 0 | NONE β pattern match |
a detector fired |
| 1 | STATIC_REACHABILITY β reachability proof |
the sink is reachable |
| 2 | TAINT_CONFIRMED β data-flow trace |
attacker-controlled data reaches the sink |
| 3 | DYNAMIC_POC β sandboxed exploit |
a proof-of-concept actually worked |
| 4 | DIFFERENTIAL_TEST β discriminating test |
behaves differently on vulnerable vs. fixed code |
Two safety rules are structural, not aspirational:
- π« An LLM is never sufficient on its own β model judgement is bounded and cannot climb the ladder; only concrete analysis can.
- β
Refutation is first-class β evidence that a finding isn't exploitable is captured and
drives it toward a
NOT_AFFECTEDverdict, not silently ignored.
Results are exported as SARIF (findings), VEX (exploitability, CycloneDX-VEX), and CycloneDX SBOM β standards-aligned answers to "is this actually a problem, in context?"
CortexWard uses a hexagonal (ports-and-adapters) design with an in-process, inspectable agent orchestrator. Everything that touches the outside world is a pluggable adapter.
ββ Interfaces ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLI (ward) Β· REST API Β· GitHub Action Β· VS Code extension β
ββ Application ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Orchestrator β Planner Β· Scanner Β· Verifier Β· Repair Β· Reviewer Β· Memory β
ββ Domain core (pure, no I/O) ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Finding Β· Evidence Β· Verification Ladder Β· Patch Β· Provenance β
ββ Ports (typing.Protocol) βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β CodeGraph Β· LanguageProvider Β· Scanner Β· LLM Β· Sandbox Β· VCS Β· Storage Β· Reporter β
ββ Plugins ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β entry-point discovery β a new adapter needs zero core changes β
ββ Adapters βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β tree-sitter CPG Β· Bandit/detect-secrets/OSV.dev/Semgrep Β· Ollama/Anthropic/OpenAI/ β
β Gemini Β· SARIF/JSON/CycloneDX-VEX Β· GitHubVCSAdapter Β· Docker sandbox Β· SQLite β
β storage Β· sequential + agent + LangGraph orchestrators β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Package map β click to expand
| Package | Ships |
|---|---|
cortexward-core |
Domain model, full port catalog, plugin registry |
cortexward-cpg |
Code Property Graph engine β AST/CFG/DFG/call-graph over tree-sitter, dependency-manifest parsing, reachability/taint/slice queries |
cortexward-scanners |
BanditScanner, SecretsScanner (detect-secrets), OsvScanner (OSV.dev), SemgrepScanner (self-authored, offline rule pack), cross-tool correlation |
cortexward-reporters |
SARIF 2.1.0, CortexWard-native JSON, and CycloneDX-VEX ReporterPort adapters |
cortexward-eval |
RunManifest, detection metrics, statistical protocol (bootstrap CIs, McNemar's test), the versioned golden dataset, and the ward bench harness |
cortexward-llm |
LLMPort adapters β Ollama, Anthropic, OpenAI-compatible, Gemini β plus a cost-aware ModelRouter |
cortexward-agents |
The seven-agent pipeline (Planner, Scanner, Verifier, Repair, Reviewer, Coordinator, Memory), CPG-grounded reachability evidence, STRIDE threat modeling, patch-gate verification |
cortexward-vcs |
GitHubVCSAdapter, the first VCSPort implementation |
cortexward-storage |
SqliteStoragePort, the event-sourced finding log (ADR-0008) |
cortexward-sandbox |
DockerSandboxAdapter, isolated dynamic execution (ADR-0004) |
cortexward-orchestrator |
SequentialOrchestrator, AgentOrchestrator, LangGraphOrchestrator, and build_pipeline() to pick between them |
cortexward-cli |
The ward CLI β scan / baseline / threat-model / bench / serve |
cortexward-server |
A REST API slice (FastAPI) |
integrations/vscode |
A VS Code extension |
Every package is independently versioned under packages/, added as its phase
lands β see ARCHITECTURE.md and
ADR-0005.
uv run ward scan . # scan the current directory, SARIF to stdout
uv run ward scan . -o results.sarif # write SARIF to a file instead
uv run ward scan . --fail-on critical # only exit non-zero on critical findings
uv run ward scan . --format cyclonedx-vex # render exploitability as CycloneDX-VEX instead
uv run ward scan . --llm-provider ollama --llm-model qwen2.5-coder:7b # agent-driven verification
uv run ward scan . --llm-provider ollama --sandbox # + dynamic exploit verification (needs Docker)ward scan auto-discovers every installed scanner (cortexward.scanners entry points), runs
each one, correlates findings by CWE + location into the domain Finding model, and renders
the result β real, working code. With --llm-provider, findings carry real LLM verification
and CPG-grounded reachability evidence instead, and --engine langgraph swaps in the
LangGraph-backed orchestrator for the identical agent pipeline. Add --sandbox (with a running
Docker daemon) to close the loop: CortexWard generates a proof-of-concept, executes it in an
isolated container, and promotes a finding to DYNAMIC_POC / VERIFIED only if the exploit
genuinely fires β then validates any patch against all four gates (applies Β· tests pass Β· rescan
clean Β· original PoC neutralized).
More of the CLI:
uv run ward baseline . -o cortexward-baseline.json # accept today's findings, suppress them later
uv run ward scan . --baseline cortexward-baseline.json # ...then re-scan without re-flagging them
uv run ward threat-model . # STRIDE-categorize findings, JSON to stdout
uv run ward bench run <dataset.json> -o run.json # benchmark against a labeled dataset
uv run ward serve # run the REST API (POST /v1/scans, ...)Run CortexWard on any repository's own CI and get results in GitHub's Security tab:
- uses: actions/checkout@v4
- uses: amarjaleelbanbhan/CortexWard@main
with:
path: . # what to scan (default: repo root)
fail-on: high # none | low | medium | high | critical (default: high)
baseline: "" # optional path to a `ward baseline` file
language: "" # optional, e.g. "python"Installs ward from this repository (pinned via cortexward-ref, defaulting to main) and
uploads the SARIF report via github/codeql-action/upload-sarif. See action.yml.
Requires Python 3.11+ and uv. This is a uv workspace
(ADR-0005): the root pyproject.toml is a virtual manifest, so workspace members must be
synced explicitly with --all-packages.
git clone https://github.com/amarjaleelbanbhan/CortexWard
cd CortexWard
uv sync --all-packages --extra dev
# Run the quality gate exactly as CI does
uv run ruff check packages
uv run ruff format --check packages
for pkg in packages/*/; do uv run mypy "${pkg}src" "${pkg}tests"; done # per-package, see CONTRIBUTING.md
uv run lint-imports # hexagonal dependency-direction check
uv run pytest --cov=cortexward --cov-fail-under=100
# Reproduce the shipped benchmark result in one command
make reproduceThe domain core is usable today:
from cortexward.domain import (
Finding, Evidence, EvidenceKind, Provenance,
SourceLocation, VerificationRung, assess,
)
finding = Finding(
rule_id="py.sql-injection",
title="Possible SQL injection",
message="User input flows into a raw SQL query.",
cwe=89,
locations=(SourceLocation(path="app/db.py", start_line=42),),
provenance=Provenance(producer="semgrep", producer_version="1.90"),
).with_evidence(
Evidence(kind=EvidenceKind.STATIC_MATCH, summary="semgrep rule matched",
provenance=Provenance(producer="semgrep")),
Evidence(kind=EvidenceKind.TAINT_TRACE, rung=VerificationRung.TAINT_CONFIRMED,
summary="request.args β cursor.execute", provenance=Provenance(producer="cpg")),
)
report = assess(finding)
print(report.recommended_state, report.vex_status, round(report.confidence, 2))
# verified under_investigation 0.86
# Corroborated to the taint rung β VERIFIED, but not yet a runnable PoC, so the
# VEX verdict stays "under_investigation" rather than "affected".CortexWard is built in strict, shippable phases, each with tests, documentation, and a green CI before the next begins.
| Phase | What it delivers | Status |
|---|---|---|
| 0 | Research & architecture | β |
| 1 | Foundation β domain core, CI, tooling | β |
| 1.5 | Workspace & port contracts | β |
| 2 | Code Property Graph engine | β |
| 3 | Scanners (Bandit, Semgrep, secrets, deps) + SARIF | β |
| 3.5 | Evaluation harness β RunManifest, golden dataset, ward bench |
π§ |
| 4 | Agent framework β 7 agents, multi-provider LLM, LangGraph engine | β |
| 5 | STRIDE threat modeling, trust boundaries | π§ |
| 6 | Sandbox execution, CycloneDX-VEX output | π§ |
| 7 | Patch generation, gate validation | π§ |
| 8 | CLI, REST API, GitHub Action, VS Code extension | π§ |
| 9 | Benchmarks & reproducibility (make reproduce) |
π§ |
| 10 | Docs site, community, v1.0 release | β³ |
Every π§ phase above is substantially complete with only specific, individually-documented items left open β see ROADMAP.md for the full per-phase breakdown, including exactly what's done, what's next, and why each remaining item is blocked (owner action, missing infrastructure, or an open research question).
Contributions are welcome β CortexWard is built to be extended, and most capabilities are plugin
adapters behind clean ports. Start with CONTRIBUTING.md (setup, workflow, and
where to jump in), our Code of Conduct, and SECURITY.md.
Have a question or idea? See SUPPORT.md and
Discussions. Research ideas and open
questions live in research/.
High-impact areas to contribute: a new ScannerPort or ReporterPort adapter Β· live-testing
the Anthropic/Gemini LLM adapters Β· cross-file taint (the CPG's biggest lever, ROADMAP.md
Milestone 1) Β· widening PoC verification to another CWE class Β· docs and examples.
