chore(p0): drop never-enabled hunter tools, test-only functions and receiver delivery

Off every active line (PATHFINDER-2026-10-13/03-unified-proposal.md, cuts).
Deleted: the four hunter tools no caller enables (read_definition,
entry_points, flows, obligations) with their schemas and dispatch, the dead
mapping branch of find_refs; 20 functions whose only caller was one test
(mapping task records, compute_ranking_metrics, build_quick_hunter_prompt,
validate_evidence_transition, should_fuse, harness processors,
rank_targets_with_model, model/report slice rendering, taxonomy
hierarchical/related, config_value.verdict, taint.verdict, roles.load_roles,
features.language_of and build_for_scan, folds.leave_one_*,
features.recorded_case, search BatchExecutor and the three __main__ shims,
delivery.put_input); the receiver delivery mode of the plane. push_inputs.py
moved to benchmarks/push. memory.purge stays: the live-S3 test cleanup uses
it. Net: 2,730 lines deleted, 207 added. 473 targeted tests passed; 3,282
tests collect. breadth.toml records the removals.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Marius Ciepluch
2026-10-13 11:06:09 +02:00
co-authored by Claude Fable 5.1
parent f5a904b7f2
commit f63703a604
60 changed files with 212 additions and 2576 deletions
+4 -78
View File
@@ -15,12 +15,8 @@ from .findings import StaticFinding
from .hunter_tools import (
PathEscapesRepo,
clamp_repo_path,
entry_points,
find_refs,
flows,
grep_repo,
obligations,
read_definition,
read_file,
)
from .provider.openrouter import OpenRouterChatClient, OpenRouterError
@@ -31,7 +27,6 @@ DEFAULT_MAX_STEPS = 4
CLIENT_ENV = "OPENULTRASAST_HUNTER_CLIENT"
_FINDING_ID_PREFIX = "tool-hunter:"
DEFAULT_TOOL_NAMES = ("read_file", "grep_repo", "find_refs")
_HUNTER_TOOL_NAMES = frozenset(DEFAULT_TOOL_NAMES) | {"read_definition", "entry_points", "flows", "obligations"}
_SEVERITIES = frozenset({"critical", "high", "medium", "low", "info"})
_SCRIPTED_FLAGS = frozenset({"scripted", "script"})
_DUMP_FLAGS = frozenset({"dump", "dump-only"})
@@ -91,50 +86,6 @@ HUNTER_TOOLS: list[dict[str, object]] = [
},
},
},
{
"type": "function",
"function": {
"name": "read_definition",
"description": "Resolve one named function to its file, line span and body. Use it instead of guessing what a callee does.",
"parameters": {
"type": "object",
"properties": {"symbol": {"type": "string"}, "path": {"type": "string"}, "max_chars": {"type": "integer"}},
"required": ["symbol"],
},
},
},
{
"type": "function",
"function": {
"name": "entry_points",
"description": "List the handlers this repository exposes, with their access classification. Identifiers and line spans only.",
"parameters": {"type": "object", "properties": {"path": {"type": "string"}}, "required": []},
},
},
{
"type": "function",
"function": {
"name": "flows",
"description": "List adjudicated source-to-sink records inside one function. Identifiers and line numbers only.",
"parameters": {
"type": "object",
"properties": {"path": {"type": "string"}, "function": {"type": "string"}},
"required": ["path", "function"],
},
},
},
{
"type": "function",
"function": {
"name": "obligations",
"description": "List what one function owes and has not discharged: the operation, the missing discharger and why it is owed.",
"parameters": {
"type": "object",
"properties": {"path": {"type": "string"}, "function": {"type": "string"}},
"required": ["path", "function"],
},
},
},
]
_SYSTEM_PROMPT = (
@@ -330,15 +281,13 @@ def run_tool_hunter(
system_prompt: str = _SYSTEM_PROMPT,
user_prompt: str | None = None,
context_files: Sequence[str] = (),
tools: Sequence[str] | None = None,
max_chars: int = _DEFAULT_MAX_CHARS,
tags: Sequence[str] = ("tool-hunter",),
) -> list[StaticFinding]:
"""One bounded hunt. Every keyword defaults to today's behaviour; a per-family detector overrides the
prompt, the context it starts from, the tools it may call and the tags its findings carry."""
"""One bounded hunt with a prompt, starting context and finding tags."""
if max_steps <= 0:
return []
schemas = _tool_schemas(tools)
schemas = HUNTER_TOOLS
messages: list[dict[str, object]] = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": _user_message(root, hotspots, user_prompt, context_files, max_chars)},
@@ -350,7 +299,7 @@ def run_tool_hunter(
if tool_calls:
messages.append(_assistant_tool_message(response.content, tool_calls, response.reasoning))
for call in tool_calls:
if call.name in _HUNTER_TOOL_NAMES:
if call.name in DEFAULT_TOOL_NAMES:
used_tools = True
messages.append(_tool_result_message(root, call, max_chars))
continue
@@ -414,12 +363,6 @@ def _looks_like_json(content: str) -> bool:
return stripped.startswith(("[", "{"))
def _tool_schemas(names: Sequence[str] | None) -> list[dict[str, object]]:
wanted = tuple(names) if names is not None else DEFAULT_TOOL_NAMES
by_name = {str(schema["function"]["name"]): schema for schema in HUNTER_TOOLS} # type: ignore[index]
return [by_name[name] for name in wanted if name in by_name]
def _user_message(root: Path, hotspots: Sequence[Hotspot], user_prompt: str | None, context_files: Sequence[str], max_chars: int) -> str:
# Context files FIRST, the question LAST. DeepSeek bills a cached prefix at 1/30 of a fresh one, and the cache
# is by prefix: with the question first, every candidate in the same file broke the prefix at its first
@@ -502,30 +445,13 @@ def _dispatch_tool(root: Path, name: str, arguments: Mapping[str, object], defau
path = _require_str(arguments, "path")
max_chars = _optional_int(arguments, "max_chars", default_max_chars)
return {"path": path, "content": read_file(root, path, max_chars=max_chars)}
if name == "read_definition":
symbol = _require_str(arguments, "symbol")
scope = arguments.get("path")
found = read_definition(
root,
symbol,
max_chars=_optional_int(arguments, "max_chars", default_max_chars),
path=str(scope) if isinstance(scope, str) and scope else None,
)
return found if found is not None else {"symbol": symbol, "found": False}
if name == "entry_points":
scope = arguments.get("path")
return entry_points(root, path=str(scope) if isinstance(scope, str) and scope else None)
if name == "flows":
return flows(root, path=_require_str(arguments, "path"), function=_require_str(arguments, "function"))
if name == "obligations":
return obligations(root, path=_require_str(arguments, "path"), function=_require_str(arguments, "function"))
if name == "grep_repo":
pattern = _require_str(arguments, "pattern")
max_matches = _optional_int(arguments, "max_matches", _DEFAULT_MAX_MATCHES)
return grep_repo(root, pattern, max_matches=max_matches)
if name == "find_refs":
symbol = _require_str(arguments, "symbol")
return find_refs(root, symbol, None)
return find_refs(root, symbol)
raise ValueError(f"unknown tool: {name}")