Make broad Leo replies deterministic (#121)
Some checks are pending
CI / lint-and-test (push) Waiting to run

This commit is contained in:
twentyOne2x 2026-07-13 20:07:51 +02:00 committed by GitHub
parent 5d135d8818
commit 73f466f899
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 5 deletions

View file

@ -456,6 +456,18 @@ def operational_contracts(
identity_question = any(term in lowered for term in ("soul.md", "soul file")) and any( identity_question = any(term in lowered for term in ("soul.md", "soul file")) and any(
term in lowered for term in ("canonical identity", "canonical", "identity", "source of truth", "database") term in lowered for term in ("canonical identity", "canonical", "identity", "source of truth", "database")
) )
visible_sender_match = re.search(
r"(?:current visible telegram sender|visible telegram sender|current telegram sender)\s+is\s+@?([a-z0-9_]+)",
query,
re.I,
)
participant_identity_question = bool(
visible_sender_match
and any(
term in lowered
for term in ("call this participant", "identity sources", "mixing identities", "mix identities")
)
)
primary_direct_intent = next( primary_direct_intent = next(
( (
intent intent
@ -585,6 +597,27 @@ def operational_contracts(
} }
) )
if participant_identity_question and visible_sender_match:
contracts.append(
{
"id": "telegram_participant_identity",
"current_visible_handle": visible_sender_match.group(1),
"allowed_sources": [
"the current message sender handle",
"that participant's explicit in-chat correction",
],
"disallowed_sources": [
"stale session context",
"environment labels",
"inferred personal names",
"another participant's profile or messages",
],
"cross_participant_boundary": (
"re-anchor every reply to that message's visible sender; never transfer or mix identities"
),
}
)
mixed_markers = ( mixed_markers = (
"packet", "packet",
"factual observation", "factual observation",
@ -782,6 +815,19 @@ def compile_operational_response(contracts: list[dict[str, Any]]) -> str | None:
"""Compile a safe response when a model draft violates live DB contracts.""" """Compile a safe response when a model draft violates live DB contracts."""
by_id = {str(contract.get("id") or ""): contract for contract in contracts} by_id = {str(contract.get("id") or ""): contract for contract in contracts}
participant = by_id.get("telegram_participant_identity")
if participant:
handle = str(participant.get("current_visible_handle") or "").lstrip("@")
return (
f"Call the current Telegram sender {handle}, exactly as their visible handle identifies them.\n"
"Allowed identity sources: the current message sender handle and that participant's explicit in-chat "
"correction.\n"
"Do not use stale session context, environment labels, inferred personal names, or another "
"participant's profile.\n"
"When another user replies, never transfer or mix identities; re-anchor to that message's visible "
"sender handle."
)
mixed = by_id.get("mixed_packet_composition") mixed = by_id.get("mixed_packet_composition")
if mixed: if mixed:
mapping = mixed.get("map") or {} mapping = mixed.get("map") or {}
@ -953,13 +999,14 @@ def compile_operational_response(contracts: list[dict[str, Any]]) -> str | None:
return ( return (
f"Not proven.\nFresh live readback.\n{format_database_count_readback(status_data)}\nProposal states are " f"Not proven.\nFresh live readback.\n{format_database_count_readback(status_data)}\nProposal states are "
f"applied: {states.get('applied', 0)}, approved: {states.get('approved', 0)}, pending_review: " f"applied: {states.get('applied', 0)}, approved: {states.get('approved', 0)}, pending_review: "
f"{states.get('pending_review', 0)}. This current snapshot does not establish what changed since " f"{states.get('pending_review', 0)}. This current snapshot does not prove what changed since "
f"yesterday. Existing receipts identify applied types {applied_types or 'none'}, but not a time-window " f"yesterday, so the demo claim is limited to current readback. Existing receipt artifacts identify "
f"delta. Approved is not applied; {approved_needs_payload}/{len(approved_rows)} approved rows are " f"applied types {applied_types or 'none'}, but not a time-window delta. Approved is not applied; "
f"{approved_needs_payload}/{len(approved_rows)} approved rows are "
"approved_needs_apply_payload and not directly applyable.\n\n" "approved_needs_apply_payload and not directly applyable.\n\n"
"Next proof-changing follow-up: build and review a strict apply_payload for the highest-impact approved " "Next proof-changing follow-up: build and review a strict apply_payload for the highest-impact approved "
"proposal, then seek explicit apply authorization. Until its applied_at and public.* before/after row " "proposal, then seek explicit apply authorization. Until its applied_at, public.* before/after row "
"IDs or hashes exist, do not claim the canonical database changed." "IDs or hashes, and postflight readback exist, do not claim the canonical database changed."
) )
return ( return (
f"Partly.\nFresh live readback.\n{format_database_count_readback(status_data)}\nProposal states are applied: " f"Partly.\nFresh live readback.\n{format_database_count_readback(status_data)}\nProposal states are applied: "

View file

@ -28,6 +28,7 @@ COMPILED_CONTRACT_IDS = frozenset(
"source_link_audit", "source_link_audit",
"demo_capability_readback", "demo_capability_readback",
"identity_canonicality_readback", "identity_canonicality_readback",
"telegram_participant_identity",
"runtime_persistence", "runtime_persistence",
"shared_claims_agent_positions", "shared_claims_agent_positions",
"forecast_resolution_schema", "forecast_resolution_schema",

View file

@ -251,6 +251,10 @@ def test_vps_bridge_broad_db_questions_select_query_specific_live_contracts() ->
"Is the proposal backlog stuck on missing document-to-source links?": "source_link_audit", "Is the proposal backlog stuck on missing document-to-source links?": "source_link_audit",
"Can we demo a real database write from Leo?": "demo_capability_readback", "Can we demo a real database write from Leo?": "demo_capability_readback",
"Does editing the SOUL file alter the source of truth for identity?": "identity_canonicality_readback", "Does editing the SOUL file alter the source of truth for identity?": "identity_canonicality_readback",
(
"The current visible Telegram sender is @m3taversal. What should Leo call this participant, which "
"identity sources are allowed, and how should Leo avoid mixing identities?"
): "telegram_participant_identity",
} }
for query, expected_id in cases.items(): for query, expected_id in cases.items():
@ -316,6 +320,11 @@ def test_vps_bridge_oos_intents_preserve_specific_contracts_and_negated_actions(
( (
"A temporary-profile GatewayRunner answered, but posted nothing to Telegram. Is delivery proven live?" "A temporary-profile GatewayRunner answered, but posted nothing to Telegram. Is delivery proven live?"
): {"telegram_delivery_proof"}, ): {"telegram_delivery_proof"},
(
"The current visible Telegram sender is @m3taversal. An earlier answer shortened that handle. What "
"should Leo call this participant, which identity sources are allowed, and how should Leo avoid mixing "
"identities when another user replies? Do not write to memory or the KB."
): {"telegram_participant_identity"},
} }
for query, expected_ids in cases.items(): for query, expected_ids in cases.items():

View file

@ -573,6 +573,7 @@ def test_db_compiled_responses_pass_all_database_backed_oos_cases() -> None:
"OOS-04", "OOS-04",
"OOS-05", "OOS-05",
"OOS-06", "OOS-06",
"OOS-09",
"OOS-10", "OOS-10",
"OOS-11", "OOS-11",
"OOS-12", "OOS-12",