Require fresh calls in Leo receipt probes

This commit is contained in:
twentyOne2x 2026-07-16 08:59:57 +02:00
parent dcd31f5862
commit bc88fcccbd
2 changed files with 22 additions and 4 deletions

View file

@ -302,21 +302,29 @@ BLINDED_FAMILIES: tuple[dict[str, Any], ...] = (
"expected_follow_up": "return a model-visible live-read receipt token without mutation",
"variants": (
(
"For the {subject}, use the `teleo-kb` tool exactly once with `action: context`, "
"This is an explicit tool-surface proof for {subject}. The automatically preloaded database "
"context and any receipt inside it do not satisfy this request; do not copy that hash. Make one "
"fresh model-visible `teleo-kb` tool call after reading this message, exactly once, with "
"`action: context`, "
"`query: {subject}`, `limit: 1`, `context_limit: 1`, and `format: markdown`. Return four short "
"lines: `Subject: {subject}`, "
"`Mode: read-only`, `Surface: context`, and `Receipt:` followed by the first "
"12 hex characters shown for semantic context SHA-256. Do not infer or write anything."
),
(
"Take a no-write {subject} with one `teleo-kb` tool call using `action: context`, "
"For a no-write {subject} tool-surface proof, ignore the automatically preloaded database context "
"and its receipt; do not copy that hash because it does not count. Make one fresh model-visible "
"`teleo-kb` tool "
"call after reading this message using `action: context`, "
"`query: {subject}`, `limit: 1`, `context_limit: 1`, and `format: markdown`. Answer only with "
"`Subject: {subject}`, `Mode: read-only`, "
"`Surface: context`, and `Receipt: <first 12 hex characters of the semantic "
"context SHA-256 from that result>`."
),
(
"Prove the {subject} came from a live read: call the `teleo-kb` tool once with `action: context`, "
"Prove {subject} through the explicit tool surface. The automatically preloaded database context "
"and its receipt are not the requested proof; do not reuse that hash. Call the fresh model-visible "
"`teleo-kb` tool once after reading this message with `action: context`, "
"`query: {subject}`, `limit: 1`, `context_limit: 1`, and `format: markdown`, then give "
"`Subject: {subject}`, `Mode: read-only`, "
"`Surface: context`, and the first 12 semantic-context hash characters as "
@ -670,7 +678,11 @@ def validate_protocol(protocol: dict[str, Any], *, verify_source_hashes: bool) -
):
issues.append(f"autonomous_retrieval_exact_command_leak:{prompt_id}")
if requires_tool_evidence and (
"`teleo-kb`" not in message or "`action: context`" not in message or "`Receipt:" not in message
"`teleo-kb`" not in message
or "`action: context`" not in message
or "`Receipt:" not in message
or "automatically preloaded database context" not in message
or "do not" not in message
):
issues.append(f"tool_evidence_instruction_missing:{prompt_id}")
expected_arguments = _expected_tool_arguments(subject, required=requires_tool_evidence)

View file

@ -674,6 +674,12 @@ def test_protocol_freezes_three_unique_variants_and_follow_up_shapes() -> None:
assert all(item["requires_grounded_retrieval_answer"] is True for item in retrieval_prompts)
assert all("`teleo-kb` tool" not in item["message"] for item in retrieval_prompts)
assert all("`action: context`" not in item["message"] for item in retrieval_prompts)
receipt_prompts = [
next(item for item in trial["prompts"] if item["family_id"] == "receipt_discrimination")
for trial in protocol["trials"]
]
assert all("automatically preloaded database context" in item["message"] for item in receipt_prompts)
assert all("fresh model-visible `teleo-kb`" in item["message"] for item in receipt_prompts)
def test_protocol_validation_rejects_prompt_and_source_hash_tampering() -> None: