Record research receipts for semantic unlocks

Record research receipts for semantic unlocks
This commit is contained in:
Dan
2026-07-22 11:30:14 +01:00
committed by GitHub
3 changed files with 29 additions and 2 deletions
+6
View File
@@ -167,6 +167,12 @@ def _post_tool_call_hook(tool_name=None, args=None, result=None, duration_ms=0,
if tool_name == "execute_code" and isinstance(args, dict):
with contextlib.suppress(Exception):
code_execution_audit.record_completion(args.get("code"), result, duration_ms)
if tool_name in {"web_search", "web_extract"}:
session_id = str(kwargs.get("session_id") or "")
eng_dir = _SESSION_ENGAGEMENTS.get(session_id)
if eng_dir:
with contextlib.suppress(Exception):
state.record_research_attempt(eng_dir, tool_name, not bool(result is None))
if tool_name not in {"violin_record_ptt", "violin_review_batch"}:
return
args = args if isinstance(args, dict) else {}
+21 -1
View File
@@ -332,7 +332,8 @@ def record_semantic_review(
next_technique.strip().lower()
and next_technique.strip().lower() != technique.strip().lower()
)
if lock and research_attempted and pivoted:
research_after_lock = bool((data.get("research_attempts") or []) and lock)
if lock and research_after_lock and pivoted:
data.pop("lock", None)
elif count >= 5:
data["lock"] = {
@@ -345,6 +346,25 @@ def record_semantic_review(
return mutate_json(path, record)
def record_research_attempt(eng_dir: str | Path, tool_name: str, success: bool) -> None:
"""Record an actual web research-tool attempt for semantic-lock recovery."""
path = _state_dir(eng_dir) / _SEMANTIC_FILE
def record(data: dict[str, Any]) -> None:
attempts = data.setdefault("research_attempts", [])
attempts.append(
{
"tool": tool_name,
"success": success,
"timestamp": datetime.now(UTC).isoformat().replace("+00:00", "Z"),
}
)
data["research_attempts"] = attempts[-20:]
mutate_json(path, record)
def semantic_lock(eng_dir: str | Path) -> dict[str, Any] | None:
return read_json(_state_dir(eng_dir) / _SEMANTIC_FILE).get("lock")
@@ -32,7 +32,8 @@ def test_semantic_reviews_warn_then_hard_lock_and_require_research_pivot(tmp_pat
assert _review(tmp_path, research_attempted=True)["locked"]
assert _review(tmp_path, next_technique="parameter-discovery")["locked"]
unlocked = _review(tmp_path, research_attempted=True, next_technique="parameter-discovery")
state.record_research_attempt(tmp_path, "web_search", True)
unlocked = _review(tmp_path, next_technique="parameter-discovery")
assert not unlocked["locked"]
assert state.semantic_lock(tmp_path) is None