2026-06-22 20:00:42 +02:00
# End-to-end examples
Each example is self-contained. Artifacts land under
`<target>/.openultrasast/runs/<scan-id>/` and `.openultrasast/` is gitignored.
## 1. Quick scan a local repo (deterministic, no keys)
```bash
uv run ousast scan /path/to/code --mode quick
run = /path/to/code/.openultrasast/runs/<scan-id>
cat " $run /report.md" # findings + evidence (secrets redacted)
jq . " $run /score.json" # 0– 100 project score + gate verdict
" $run /report.sarif" # SARIF for code-scanning / IDEs
```
## 2. CI gate
```bash
# Fail the build on any evidence-verified finding:
uv run ousast scan . --mode quick --fail-on verified
# The hard detection gate (>=90% recall, <10% FP), score-independent:
uv run python -m openultrasast.gate
```
## 3. Benchmark a known-vulnerable corpus
```bash
uv run ousast benchmark benchmarks/manifests/python-vulnerable.toml --mode quick
# -> expected / matched / missed counts + a per-rule recommendation delta
```
2026-09-04 13:57:33 +02:00
## 4. Vuln vs fixed pair eval (efficiency, not cheat-sheet recall)
```bash
uv run ousast pairs # local fixtures + vendored GitHub VFCs
uv run ousast pairs --slice github --json # honesty dashboard as JSON
uv run ousast pairs --slice sast # OWASP Benchmark + Juliet Youden (TPR-FPR)
2026-09-05 10:37:53 +02:00
uv run ousast pairs --slice vibe-py --pointers # nightly: pointer pairs via the local cache (network)
2026-09-05 15:35:08 +02:00
uv run ousast mechanisms export --slice vibe-py # maintainer: seed mechanism candidates from trusted pairs (offline)
uv run ousast improve bench.toml --pair-catalog benchmarks/pairs/catalog.toml # the mechanisms lever admits candidates the holdout pairs prove; the scan then searches them
uv run ousast pairs --slice vibe-py --loo # leave-one-out: the corpus's own detection rate (reports/loo.json)
2026-09-04 13:57:33 +02:00
uv run python -m openultrasast.pair_gate # CI: local pairs must all pass
```
Each case is two isolated trees (vuln file vs patched file, same relative path).
`pair_correct` means the harness fired on the vuln side and stayed silent on the
fix. Misses and fix-side leaks become `miss` /`fp` signals for `ousast improve` .
The catalog and public dataset pointers live in `benchmarks/pairs/` .
## 5. Self-improve the ruleset from benchmark feedback
2026-06-22 20:00:42 +02:00
```bash
uv run ousast improve benchmarks/manifests/java-spring-boot-vulnerable.toml --dry-run # preview
uv run ousast improve benchmarks/manifests/java-spring-boot-vulnerable.toml # apply
# Accepted edits land in <target>/.openultrasast/calibration/rule_policy.json,
# which the next scan/benchmark of that target loads automatically.
```
2026-09-30 12:45:29 +02:00
## 6. Running the agentic plane
Model work over whole repositories runs as a Run manifest on ax, one isolated actor
per task (bring-up: [ops/ax/README.md ](../ops/ax/README.md )). The provider key is
read from the environment (or `.env` ) by `ousast` and sent only in each task's start
request.
2026-06-22 20:00:42 +02:00
```bash
2026-09-30 12:45:29 +02:00
uv run ousast plane doctor # kind, Agent Substrate, ax controller, runner image
uv run ousast plane run plane/runs/validation-46.yaml # repo-facts, verify a/b(/c), agree, remember per case
uv run ousast plane status validation-46 # per-task status and token attribution
uv run ousast plane remember validation-46 # re-ingest the run's memory rows (OUSAST_MEMORY)
# Feed the stored rows back into the ruleset loop (same validator and gate)
uv run ousast improve benchmarks/manifests/java-spring-boot-vulnerable.toml --dry-run --memory
2026-06-22 20:00:42 +02:00
```
2026-09-30 12:45:29 +02:00
Each task in the Run carries its own Model and `budget: {usd, calls}` ; a task that
reaches its ceiling stops as `unfinished` and resumes on a rerun with a larger
budget. A local `ousast scan --mode standard` stays deterministic apart from the
optional `[models] hunter` tool hunter.
2026-09-04 13:57:33 +02:00
## 7. Drive it from an MCP client (OpenCode / IDE)
2026-06-22 20:00:42 +02:00
```jsonc
{ "command" : "uv" , "args" : [ "run" , "ousast" , "mcp" ] }
```
Then: `openultrasast.scan {path}` → `run_dir` → `openultrasast.findings {run_dir}` →
`openultrasast.explain {run_dir, finding_id}` . See the README "MCP server" section.