merge(cleanup): second legacy inventory -- vector index, equality test, unread config keys, status notes

Also drops the removed ousast index line from the scan skill.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-10-02 20:02:53 +02:00
co-authored by Claude Fable 5.1
17 changed files with 75 additions and 454 deletions
+12 -21
View File
@@ -25,7 +25,6 @@ def test_load_config_reads_toml(tmp_path: Path) -> None:
config = load_config(config_path)
assert config.models.ranker == "openrouter/test-ranker"
assert config.embeddings.store == "json-local"
assert config.sandbox.memory_mb == 1024
@@ -74,6 +73,11 @@ def test_retired_llm_keys_fail_naming_the_replacement(tmp_path: Path, body: str,
('[evidence]\nminimum_patch = "root_cause_explained"\n', "`[evidence] minimum_patch`"),
("[variants]\nenabled = false\n", "`[variants] enabled`"),
("[variants]\nmax_mechanisms = 10\n", "`[variants] max_mechanisms`"),
('[embeddings]\nmodel = "openai/text-embedding-3-small"\n', "`[embeddings] model`"),
('[embeddings]\nstore = "json-local"\n', "`[embeddings] store`"),
("[sandbox]\nnetwork = true\n", "`[sandbox] network`"),
("[sandbox]\nworkspace_readonly = false\n", "`[sandbox] workspace_readonly`"),
("[complexity]\ntop_k = 3\n", "`[complexity] top_k`"),
],
)
def test_unread_keys_fail_naming_why(tmp_path: Path, body: str, key: str) -> None:
@@ -140,30 +144,27 @@ def test_write_resolved_config_creates_json(tmp_path: Path) -> None:
payload = json.loads(output.read_text())
assert payload["sandbox"]["memory_mb"] == 2048
# retired 2026-10-02 (never read): the unread sections are not echoed as if they configured something
assert not {"dynamic", "evidence", "variants"} & set(payload) and "patcher" not in payload["models"]
assert not {"dynamic", "evidence", "variants", "embeddings"} & set(payload) and "patcher" not in payload["models"]
def test_complexity_and_regress_defaults_when_section_absent() -> None:
config = load_config(None)
assert config.complexity.top_k == 20
assert config.complexity.max_hunter_hotspots == 8
assert config.regress.max_candidates == 5
assert config.regress.images == ()
assert config.sandbox.network is False
assert config.sandbox.workspace_readonly is True
assert config.sandbox.memory_mb == 2048
assert config.sandbox.timeout_seconds == 300
assert config.sandbox.pids_limit == 512
def test_override_changes_top_k_and_max_candidates_only(tmp_path: Path) -> None:
def test_override_changes_max_hunter_hotspots_and_max_candidates_only(tmp_path: Path) -> None:
config_path = tmp_path / "openultrasast.toml"
config_path.write_text(
"\n".join(
[
"[complexity]",
"top_k = 3",
"max_hunter_hotspots = 3",
"[regress]",
"max_candidates = 2",
]
@@ -172,12 +173,9 @@ def test_override_changes_top_k_and_max_candidates_only(tmp_path: Path) -> None:
config = load_config(config_path)
assert config.complexity.top_k == 3
assert config.complexity.max_hunter_hotspots == 3
assert config.regress.max_candidates == 2
assert config.complexity.max_hunter_hotspots == 8
assert config.regress.images == ()
assert config.sandbox.network is False
assert config.sandbox.workspace_readonly is True
assert config.sandbox.memory_mb == 2048
assert config.sandbox.timeout_seconds == 300
assert config.sandbox.pids_limit == 512
@@ -201,24 +199,17 @@ def test_load_config_reads_regress_image_pins(tmp_path: Path) -> None:
assert config.regress.max_candidates == 4
assert dict(config.regress.images) == {"python": "python:3.12-slim", "javascript": "node:22-slim"}
assert config.complexity.top_k == 20
assert config.complexity.max_hunter_hotspots == 8
assert config.sandbox.memory_mb == 2048
def test_load_dotenv_sets_missing_keys_only(tmp_path: Path, monkeypatch) -> None: # type: ignore[no-untyped-def]
env_file = tmp_path / ".env"
env_file.write_text("OPENROUTER_API_KEY=from-file\nOPENROUTER_EMBEDDING_MODEL=openai/text-embedding-3-small\n")
env_file.write_text("OPENROUTER_API_KEY=from-file\nS3_REGION=us-east-1\n")
monkeypatch.setenv("OPENROUTER_API_KEY", "already-set")
monkeypatch.delenv("OPENROUTER_EMBEDDING_MODEL", raising=False)
monkeypatch.delenv("S3_REGION", raising=False)
load_dotenv(env_file, force=True)
assert os.environ["OPENROUTER_API_KEY"] == "already-set"
assert os.environ["OPENROUTER_EMBEDDING_MODEL"] == "openai/text-embedding-3-small"
def test_embeddings_model_from_env(monkeypatch) -> None: # type: ignore[no-untyped-def]
monkeypatch.setenv("OPENROUTER_EMBEDDING_MODEL", "openai/text-embedding-3-small")
config = load_config(None)
assert config.embeddings.model == "openai/text-embedding-3-small"
assert os.environ["S3_REGION"] == "us-east-1"
-65
View File
@@ -1,65 +0,0 @@
"""The equality instrument (harnessx-removal design section 3) sees a difference when there is one.
A comparison that always says "equal" would prove nothing, so these tests feed it records that differ in one
place each and require it to name that place, and records that differ only in excluded fields and require it
to pass.
"""
from __future__ import annotations
import importlib.util
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
_SPEC = importlib.util.spec_from_file_location("hxr_equality", ROOT / "benchmarks" / "archive" / "harnessx_removal_equality.py")
assert _SPEC is not None and _SPEC.loader is not None
equality = importlib.util.module_from_spec(_SPEC)
_SPEC.loader.exec_module(equality)
def _record(path: Path, *, findings: object, suite: dict[str, str], stdout: str = "findings=3\n") -> Path:
(path / "scan").mkdir(parents=True)
(path / "suite.json").write_text(equality.dump(suite))
(path / "scan" / "findings.json").write_text(equality.dump(findings))
(path / "scan" / "stdout.txt").write_text(stdout)
(path / "env.json").write_text(json.dumps({"tree_ish": str(path)}))
return path
def _normalized(raw: dict[str, object], root: str) -> object:
return equality.normalize(raw, root, "/tmp/x")
def test_excluded_fields_and_run_ids_do_not_count(tmp_path: Path) -> None:
a = _normalized({"rule": "sqli", "runtime_seconds": 1.2, "path": "/r1/runs/20260930T101010Z-0123abcd/f.py", "t_ms": 4}, "/r1")
b = _normalized({"rule": "sqli", "runtime_seconds": 9.9, "path": "/r2/runs/20261001T111111Z-ffffffff/f.py", "t_ms": 7}, "/r2")
suite = {"tests.test_x::test_a": "passed"}
diffs = equality.compare(_record(tmp_path / "a", findings=a, suite=suite), _record(tmp_path / "b", findings=b, suite=suite), {})
assert diffs == []
def test_a_changed_finding_is_reported_with_its_key(tmp_path: Path) -> None:
suite = {"tests.test_x::test_a": "passed"}
a = _record(tmp_path / "a", findings=[{"rule": "sqli", "line": 3}], suite=suite)
b = _record(tmp_path / "b", findings=[{"rule": "sqli", "line": 4}], suite=suite)
assert equality.compare(a, b, {}) == ["scan/findings.json: $[0].line: 3 -> 4"]
assert equality.main(["compare", str(a), str(b)]) == 1
def test_a_changed_outcome_or_unmapped_test_is_reported(tmp_path: Path) -> None:
a = _record(tmp_path / "a", findings=[], suite={"t::a": "passed", "t::gone": "passed", "t::old": "skipped"})
b = _record(tmp_path / "b", findings=[], suite={"t::a": "failure", "t::new": "skipped", "t::extra": "passed"}, stdout="findings=2\n")
diffs = equality.compare(a, b, {"deleted": ["t::gone"], "renamed": {"t::old": "t::new"}})
assert diffs == [
"suite.json: t::a passed -> failure",
"suite.json: t::extra new in candidate",
"scan/stdout.txt: first differing line 1: 'findings=3' -> 'findings=2'",
]
def test_a_file_present_on_one_side_only_is_reported(tmp_path: Path) -> None:
a = _record(tmp_path / "a", findings=[], suite={})
b = _record(tmp_path / "b", findings=[], suite={})
(b / "scan" / "fusion.json").write_text("[]\n")
assert equality.compare(a, b, {}) == ["scan/fusion.json: present only in candidate"]
+14 -83
View File
@@ -1,80 +1,9 @@
import json
from pathlib import Path
import pytest
from openultrasast.index import (
CodeChunk,
build_code_chunks,
build_retrieval_package,
build_vector_index,
chunk_text_namespace,
index_reuse_key,
query_vector_index,
read_vector_index,
write_vector_index,
)
from openultrasast.preprocess import RepoSnapshot, preprocess_repository
from openultrasast.index import chunk_text_namespace
class FakeEmbeddingClient:
def embed(self, *, model: str, inputs: list[str], timeout_seconds: int = 60) -> list[list[float]]:
return [[float(len(text)), 1.0] for text in inputs]
def test_build_code_chunks_preserves_metadata_filters(tmp_path: Path) -> None:
repo = tmp_path / "repo"
repo.mkdir()
(repo / "app.py").write_text("def login(user):\n return user\n")
_, targets = preprocess_repository(repo)
chunks = build_code_chunks(repo, targets, max_lines=1)
assert len(chunks) == 2
assert chunks[0].metadata["path"] == "app.py"
assert chunks[0].metadata["language"] == "python"
assert chunks[0].start_line == 1
def test_json_vector_index_round_trips_and_filters(tmp_path: Path) -> None:
repo = tmp_path / "repo"
repo.mkdir()
(repo / "app.py").write_text("def login(user):\n return user\n")
snapshot, targets = preprocess_repository(repo)
chunks = build_code_chunks(repo, targets)
index = build_vector_index(snapshot=snapshot, chunks=chunks, embedding_model="openrouter/embed", client=FakeEmbeddingClient())
output = tmp_path / "index.json"
write_vector_index(index, output)
loaded = read_vector_index(output)
matches = query_vector_index(loaded, [20.0, 1.0], metadata_filter={"language": "python"})
assert loaded.embedding_model == "openrouter/embed"
assert matches[0][1].path == "app.py"
assert json.loads(output.read_text())["store"] == "json-local"
def test_vector_index_rejects_embedding_count_mismatch() -> None:
class EmptyEmbeddingClient:
def embed(self, *, model: str, inputs: list[str], timeout_seconds: int = 60) -> list[list[float]]:
return []
chunk = CodeChunk(
chunk_id="chunk-1",
namespace="repo_code",
path="app.py",
language="python",
start_line=1,
end_line=1,
text="print('x')",
metadata={"path": "app.py", "language": "python"},
)
snapshot = RepoSnapshot(root="/repo", commit=None, file_count=0, languages={})
with pytest.raises(ValueError):
build_vector_index(snapshot=snapshot, chunks=[chunk], embedding_model="model", client=EmptyEmbeddingClient())
def test_namespace_chunks_and_reuse_key_are_metadata_scoped() -> None:
def test_namespace_chunks_are_metadata_scoped() -> None:
chunks = chunk_text_namespace(
namespace="skills",
path="semgrep.md",
@@ -82,21 +11,23 @@ def test_namespace_chunks_and_reuse_key_are_metadata_scoped() -> None:
metadata={"language": "markdown", "vulnerability_class": "mapping"},
max_lines=1,
)
snapshot = RepoSnapshot(root="/repo", commit="abc", file_count=1, languages={"python": 1})
assert len(chunks) == 2
assert chunks[0].namespace == "skills"
assert chunks[0].language == "markdown"
assert chunks[0].metadata["vulnerability_class"] == "mapping"
assert index_reuse_key(snapshot, "embed-a") != index_reuse_key(snapshot, "embed-b")
assert (chunks[0].start_line, chunks[0].end_line) == (1, 1)
assert chunks[0].chunk_id != chunks[1].chunk_id
def test_retrieval_package_is_bounded_by_character_budget() -> None:
chunks = chunk_text_namespace(namespace="docs", path="README.md", text="alpha\n" + "beta" * 100, max_lines=1)
snapshot = RepoSnapshot(root="/repo", commit=None, file_count=1, languages={"markdown": 1})
index = build_vector_index(snapshot=snapshot, chunks=chunks, embedding_model="model", client=FakeEmbeddingClient())
def test_blank_blocks_are_skipped_and_the_language_defaults_to_text() -> None:
chunks = chunk_text_namespace(namespace="docs", path="README.md", text="alpha\n\n\nbeta\n", max_lines=1)
package = build_retrieval_package(role="verifier", index=index, query_embedding=[4.0, 1.0], max_chars=80)
assert [chunk.text for chunk in chunks] == ["alpha", "beta"]
assert chunks[0].language == "text"
assert package.role == "verifier"
assert package.hits
assert package.truncated is True
@pytest.mark.parametrize(("namespace", "max_lines"), [("unknown", 80), ("docs", 0)])
def test_invalid_namespace_or_window_is_rejected(namespace: str, max_lines: int) -> None:
with pytest.raises(ValueError):
chunk_text_namespace(namespace=namespace, path="x", text="y", max_lines=max_lines)