Commit Graph
13 Commits
Author SHA1 Message Date
Marius CiepluchandClaude Opus 4.8 b5e40318db feat(hardening): Phase 15 — redaction, retry/backoff, budgets, threat-model docs
Release-readiness hardening.

- redaction.py (zero-dep): redact_secrets masks provider API keys, AWS/GitHub/Slack/
  Google tokens, bearer tokens, URL-embedded credentials, PEM private keys, and
  sensitive key=value assignments. Wired into the trace writer and the markdown report
  (on by default), so scan artifacts never leak a credential quoted from source.
- provider/openrouter.py: call_with_retry — exponential backoff on transient failures
  (HTTP 429/5xx, connection errors, timeouts); non-transient errors fail fast. Both the
  chat and embedding clients use it (max_attempts/retry_base_delay configurable).
- config [hardening]: redact_secrets (default true) + max_findings (bounded-CI output
  cap, 0 = unlimited; truncation is severity-ordered and disclosed as a `budget`
  degradation). Agentic spend stays bounded by [harnessx] max_cost_usd/token_threshold.
- docs/threat-model.md (trust boundaries, controls, sandbox limits) + docs/examples.md
  (six end-to-end walkthroughs); README "Security & hardening" section links both.
- CI lint/typecheck/test/detection-gate/dagger gates already existed.

tests/test_redaction.py, test_provider_retry.py, test_hardening_pipeline.py + config
tests. 206 passed, 4 skipped; ruff + mypy clean; detection gate PASS.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 20:02:34 +02:00
Marius CiepluchandClaude Opus 4.8 3fd0057e5f feat(skills): Phase 14 — Trail of Bits skill index + router
Replace the hardcoded skill-name stub with a real, routable skill index.

- skills.py (zero-dep): SkillDescriptor inventory (~22 ToB skills with routing
  metadata — languages, tags, vulnerability classes, stages — plus a short operating
  checklist each), aligned with the spec's routing examples. route_skills scores by
  vulnerability-class/tag/stage signal with a language filter+bonus, and never selects
  on a pure language match. route_skills_for_target derives vuln classes from tags;
  select_skill_context packs checklists into a char budget; skill_chunks chunks the
  guidance into the `skills` retrieval namespace.
- hunter.select_skill_snippets now delegates to the router (existing C-memory and
  crypto+auth routing expectations preserved).
- hunter_harness._describe feeds the budget-capped routed skill context into the
  HarnessX hunter prompt (the genuine consumer of skill_budget_chars).
- 8.4 zero-dep guard extended to cover skills.py.

tests/test_skills.py (9 tests: C parser → memory/fuzzing, crypto → constant-time/
vector, language-mismatch + language-only exclusion, stage filtering, budget cap,
namespace chunking). openrouter-sast-harness Phase 14 checked off.

188 passed, 4 skipped; ruff + mypy clean; detection gate PASS.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 19:51:04 +02:00
Marius CiepluchandClaude Opus 4.8 9c917dd6aa feat(mcp): Phase 12 — narrow MCP server + ousast mcp
A zero-dependency MCP server over stdio (newline-delimited JSON-RPC 2.0) for
OpenCode/IDE integration, exposing only stable project-level operations.

- mcp.py: McpServer (pure handle() dispatch) + serve() stdio loop, stdlib-only.
  Ten tools: openultrasast.scan/status/findings/get_finding/evidence/artifacts/
  benchmark/explain/propose_patch/export_report. scan/benchmark run the bounded
  analysis pipeline; NO tool accepts a free-form command — no shell, Docker, or
  internal hunter tools are exposed. propose_patch degrades visibly (patch oracle
  is a later phase). initialize/tools/list/tools/call/ping handled; notifications
  get no response; errors surface as JSON-RPC errors instead of crashing the loop.
- cli: `ousast mcp` subcommand launches the stdio server (lazy import → keeps the
  mcp↔cli cycle one-directional).
- tests/test_mcp.py: tool listing is exactly the narrow surface, surface-safety
  (no shell/exec/command tool), scan→status→findings→explain→evidence flow,
  export_report, propose_patch degradation, and the stdio loop round-trip.
- README "MCP server" section; openrouter-sast-harness Phase 12 checked off.

Verified end-to-end over real stdio (initialize → tools/list → scan). 179 passed,
4 skipped; ruff + mypy clean; detection gate PASS.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 19:42:01 +02:00
Marius CiepluchandClaude Opus 4.8 867bd536a2 feat(fusion): Phase 13 — two-panel fusion adjudication
OpenUltraCode-style deepening for findings that need more reasoning than the
ranker→hunter→verifier→mapping loop provides.

- fusion.py (zero-dep core + lazy LLM path): a deterministic trigger policy
  (critical/high severity, verifier disagreement, static-vs-semantic conflict,
  gates-risky-fix, high-assurance request); two panels that steel-man the
  vulnerability and false-positive cases; a deterministic, auditable decider that
  reconciles to one of five dispositions (accepted/rejected/mitigated/deferred/
  blocked); full disclosure (votes, model IDs, degradations, warnings, decision
  source). fuse_findings_dispatch routes panels through the configured HarnessX
  provider when panel_model + extra are present, else deterministic + a degradation.
- config [fusion]: enabled (default true), panel_model, decider_model,
  high_assurance.
- cli: standard-mode fusion stage runs on triggered findings, writes fusion.json
  and a manifest `fusion` block; quick mode never fuses. reports.write_manifest
  gained the fusion summary param.
- 8.4 zero-dep guard extended to cover fusion.py (lazy harnessx import only).
- README fusion section marked implemented + documented; openrouter-sast-harness
  Phase 13 checked off.

tests/test_fusion.py (16 tests) + config tests. 169 passed, 4 skipped; ruff + mypy
clean; detection gate PASS.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 18:57:03 +02:00
Marius CiepluchandClaude Opus 4.8 9c4af4f546 feat(calibration): automatic in-pipeline false-positive feedback
Close the HarnessX self-improving loop without an agent in the loop. Every scan
now feeds its verifier outcomes back into the next scan's ranking:

- New `calibrate` stage (after rank, before findings) loads a persistent ledger
  of scoped false-positive learnings and demotes every previously-rejected scope
  (`calibrate_rankings`), writing `calibration/applied_calibrations.json`.
- New `record_calibration` stage (after verify) converts this run's non-accepted
  verifier outcomes into scoped `FalsePositiveLearning` records
  (`learnings_from_verifications`) and merges them into
  `.openultrasast/calibration/false_positive_learnings.json`, de-duplicated by
  finding ID so a repeat rejection does not compound without bound.
- Lower the calibration floor (MIN_CALIBRATED_PRIORITY = 0.1) so accumulated
  rejections can demote a scope below the natural ranking minimum.

Demotion is scoped and reversible: a rejection in one path never touches an
accepted finding in another, and priority is demoted rather than the finding
deleted so the audit trail explains every downgrade. First run is a no-op
(empty ledger), so existing single-run behavior is unchanged.

Adds tests/test_pipeline_calibration.py (two-run demotion, order-independent),
documents the realized loop in the README, and checks off the
standard_security_harness milestone in tasks.md.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 20:44:08 +02:00
Marius CiepluchandClaude Opus 4.8 6699f1f8f9 chore: add kiro spec-driven tooling and steering docs
Add the Kiro-style agentic SDLC tooling used to drive this project: the
.opencode/skills/kiro-* skill set (discovery, spec init/requirements/design/
tasks, validation, implementation, review, steering), the .kiro/settings
templates, and AGENTS.md describing the workflow. Update the spec docs
(assessment/design/requirements/tasks) to current state.

Scope tests/test_opencode_skills.py to the project's own openultrasast-*
skills so the third-party kiro-* tooling (which uses a different frontmatter
convention) no longer breaks the frontmatter check.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 14:28:19 +02:00
Marius Ciepluch be65aed96e feat(hunter): add standard-mode scheduling 2026-06-18 10:59:25 +02:00
Marius Ciepluch cad70721cb feat(reports): add SARIF manifest artifacts 2026-06-18 10:16:25 +02:00
Marius Ciepluch 5519413c82 feat(verification): add evidence ladder verifier 2026-06-18 09:59:28 +02:00
Marius Ciepluch f8c690999a feat(harness): add runtime and reachability mapping 2026-06-18 07:57:06 +02:00
Marius Ciepluch 33757db14a feat(opencode): add OpenUltraSAST steering skills 2026-06-17 21:16:20 +02:00
Marius Ciepluch e7df721d16 feat(scan): add initial SAST pipeline 2026-06-17 21:13:51 +02:00
Marius Ciepluch 43a41b5e78 docs(spec): add OpenRouter SAST harness spec 2026-06-17 19:39:58 +02:00