Files
Open_Ultra_SAST/.kiro/specs/detection-core/research.md
T

3.7 KiB

Research Log: detection-core

Gap analysis (2026-10-30)

Current-state inventory (from codebase exploration)

The security trace already exists for one family (access_control) in the prover: Trace/PathRecord/ProverResult (src/openultrasast/hunt/prover.py, semantic/obligations/trace.py), three-way judgment (PairJudgment, semantic/obligations/judgment.py), coverage counters (Coverage, stage_funnel, resolution buckets in semantic/obligations/resolution.py), digest stamping (benchmarks/valid/run_manifests.py AnalyzerBundle, _input_digest/_population_digest in arm_regression.py), and the admission workflow (benchmarks/valid/prover_admission.py, admission_scoring.py, admission_run.py).

Requirement-to-asset map

Req Existing asset Status
1 trace object Trace/ProverResult in prover Exists, access_control-only; needs family-agnostic core contract
2 three-way judgment PairJudgment, judgment.py Exists; promote to core vocabulary
3 coverage accounting Coverage, stage_funnel, resolution buckets Exists; zero-byte refusal lives only in runners
4 measured budget static BUDGET_SECONDS = 120.0 in runners; per-change seconds recorded Gap: budget is a constant; complexity features not recorded; no per-class derivation. Evidence: dev pool 20/483 overruns (max 240s) vs pilot max 7.7s
5 verdict contract findings carry witness; indeterminate handling in prover Exists; needs core-level contract (proven vs bounded silence)
6 digests/provenance AnalyzerBundle, input/population digests Exists; stamping rule must become core-level
7 admission gate prover_admission.py/admission_scoring.py/admission_run.py Exists for one arm; needs family-agnostic generalization
8 no fitting on labels steering rule only (detection-quality.md) Gap: no reversed-pair probe harness exists
9 bounded model role zero-shot judge measured 2026-10-28 (nearly inert, safe) Policy; core must state the boundary contract
10 fact packs ruleset/obligations/*.toml, fact_init.py Exists per language; needs family-pack admission + scope tagging
11 consumer contract each runner has its own envelope (prover_arm.run/summarize, push.admission.defects) Gap: no shared core interface
12 measurement schema score.rate, summarize_* Partial; vocabulary/digest fields not unified

Implementation approach options

  • A. Extend in place: grow the prover modules into the core. Minimal new files, but bloats family-specific code and keeps the "one arm = one contract" problem.
  • B. New core module, prover reimplemented: clean contract, but discards measured, reviewer-approved code (risk of regression in the 34.8%-recall strict lane).
  • C. Hybrid (recommended): new thin core-contract package that the prover's existing types implement, and the runners consume incrementally. Contract extracted, behavior preserved; migration is per-consumer, each step reviewable.

Effort / risk

  • Effort: M-L (contract extraction across ~6 runner modules plus core package).
  • Risk: Medium — contract extraction touches measured code paths; mitigated by keeping existing behavior byte-identical per consumer during migration and re-running the admission suite as the regression gate.

Research needed (carried to design)

  • Measured-budget model: which complexity features predict reply time on the two pools (dev 483 changes with seconds; pilot 264). Carry the 13.3/13.4 record sets as the fitting data — measurement only, never training a detector on them.
  • Reversed-pair probe harness for Req 8: fix/reversed-fix pairs exist in the pools.