Commit Graph
5 Commits
Author SHA1 Message Date
Marius CiepluchandClaude Opus 4.8 ef59c0ae3d feat(harnessx): Phase 3 task 6 — hunter sub-harness + llm-judge verifier + fallback
Adopt HarnessX at the hunter loop and verifier, capability-gated so the default
zero-dependency scan is byte-identical and CI (no extra) exercises the fallback.

- 6.1/6.2 build_sast() (single, lazy HarnessX composition site in harness_ext.py,
  mirrors DocuHarnessX make_docgen) + HxScanOrchestrator (hunter_harness.py): a
  drop-in for run_hunter_pool that runs one bounded HarnessX agent task per ranked
  target (ModelConfig(main=AnthropicProvider).agentic(build_sast()).run(BaseTask)),
  parses findings from a JSON structured-output contract, returns the existing
  HunterPoolResult, maps scan_id->session_id and emits per-target exit_reason/cost/
  steps to the outer trace.
- 6.4 verify_judge.verify_findings_dispatch: a drop-in superset of
  verification.verify_findings — structural verifier verbatim by default (rejects
  unknown reachability), HarnessX llm-judge (build_judge_prompt/parse_judge_response)
  when the extra + a verifier model are present; verdict mapped to VerificationResult
  evidence-gated (plausible>=0.6 accepted; unsupported/refused rejected; infra
  failure never auto-rejects).
- 6.5 cli capability gate (hx_hunter/hx_verify): selects HxScanOrchestrator /
  judge only in standard mode with a configured model AND has_harnessx(); otherwise
  falls back and records a {stage,reason:harnessx_extra_unavailable} degradation in
  the manifest (new append-only write_manifest degradations kwarg). With no model
  configured the manifest stays byte-identical.
- pyproject: mypy override ignore_missing_imports for harnessx.* (absent in the
  type-check env).

Verified the HarnessX path constructs against the real extra in a throwaway venv
(build_sast -> HarnessConfig; orchestrator -> Harness; build_judge_prompt/
parse_judge_response/verdict mapping) — only the live agent.run()/provider.complete()
LLM calls are offline-untestable and stay gated. 109 tests pass (2 construction
smokes skip without the extra), ruff + mypy clean, detection gate 93.6%/0% intact.
Tasks 6.1/6.2/6.4/6.5 done; 6.3 (deterministic stages as HarnessX processors) deferred.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 16:29:52 +02:00
Marius CiepluchandClaude Opus 4.8 5e206df166 feat(harnessx): Phase 3 task 5.2 — SHA-pinned optional extra + capability guard
Wire HarnessX as an optional, SHA-pinned extra with a lazy capability guard,
keeping the core install zero-dependency.

- pyproject: add [project.optional-dependencies] harnessx pinned to commit
  274c512 (Darwin-Agent/HarnessX). Core dependencies stays []. uv_build emits
  `Requires-Dist: harnessx @ git+...@<sha> ; extra == 'harnessx'` +
  `Provides-Extra: harnessx` (verified via uv build); release ships to GitHub
  Releases, not PyPI, so the direct-reference is fine.
- harness_ext.py: the capability seam. has_harnessx() probes via find_spec
  (never imports harnessx); require_harnessx() imports lazily on demand and
  raises HarnessXUnavailableError with install guidance when absent. Every
  Phase 3+ HarnessX path routes through here so heavy imports stay cold by default.
- uv.lock refreshed: the universal lock now resolves the harnessx tree (149 pkgs)
  but `uv sync --group dev` installs only 57 — harnessx is NOT importable in the
  default/CI venv (verified), so CI stays lean and never re-locks.
- Tests: core deps empty; the extra is a 40-hex SHA-pinned git URL; importing
  openultrasast.cli does not import harnessx; has_harnessx probes without
  importing; require_harnessx raises with guidance when absent.

98 tests pass; ruff + mypy clean; detection gate 93.6%/0% intact. Spec task 5
(5.1 + 5.2) checked off; next is task 6 (build_sast hunter sub-harness).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 16:08:43 +02:00
Marius CiepluchandClaude Opus 4.8 8fe8911020 ci: exclude benchmark fixtures from ruff
CI runs `ruff format --check .` and `ruff check .` over the whole repo. The
benchmark fixtures are intentionally vulnerable, unformatted sample code (e.g.
a `% uid` SQL injection that ruff flags as UP031), and reformatting them would
shift the ground-truth line numbers the manifests depend on. Exclude
benchmarks/fixtures from ruff so lint/format only cover real project sources.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 14:17:22 +02:00
Marius Ciepluch 1e6c1f4436 ci: add quality gates and release workflows 2026-06-18 10:06:21 +02:00
Marius Ciepluch e7df721d16 feat(scan): add initial SAST pipeline 2026-06-17 21:13:51 +02:00