Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions loopx/chat_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"remote_evidence declares each source's typed status and freshness: read or cached with its read time, unavailable with its typed reason_code, its reason, the last successful read and a coverage effect, not_configured for alias drift, or deferred_budget for a source outside this Turn's one-dial budget. "
"When a source is unavailable, use its reason_code and reason to name the exact cause and the repair it needs in this answer, including when that repair is the owner's own action on this machine such as renewing an expired Kerberos ticket; an untyped unavailable or a cause copied from another source is a wrong answer. "
"Use its rows as the remote evidence and answer the question with them; rows marked stale are last known rather than current, and an unread, stale or unavailable source is a named coverage gap, never evidence that a remote Goal made no progress. "
"evidence_window.source_health carries one typed row per declared source, including the local source, with freshness, the typed reason, a coverage_effect and a next_action: name an unread, stale or unavailable source by its reason and give its next_action as the repair. Read coverage_effect as guidance about what that gap can support, not a machine-checked obligation. "
"When the Turn declares remote_read as on_demand_tool instead, the declared sources were not read for you: read the chosen source_id with loopx_manager_read before answering, and name any source you did not read as the exact gap. "
"Read each delivery's recorded_details: checkpoint_reason and observed_reality describe recorded findings, while result_class and probe_kind describe the reported validation. "
"Synthesize concrete results and counterevidence across receipts; do not replace them with counts, IDs, follow-up plans, or generic missing-evidence disclaimers. "
Expand Down
18 changes: 18 additions & 0 deletions tests/test_chat_manager_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import loopx.chat_manager_context as context
from loopx.chat_manager import (
MANAGER_AGENT_GOAL_ID,
MANAGER_AGENT_OBJECTIVE,
MANAGER_CONTEXT_VERSION,
manager_model_config,
manager_workspace,
Expand Down Expand Up @@ -298,6 +299,23 @@ def test_source_health_rows_type_a_window_that_read_nothing():
assert read[0]["next_action"] is None


def test_manager_prompt_uses_the_window_source_health_rows_as_guidance():
"""The window publishes source_health rows, so the prompt has to name them.

The rows ship as data in every Turn; without a matching sentence the answer
only reads remote_evidence, and a source that was declared but contributed
nothing stays an unexplained gap. The wording also keeps the coverage effect
explicitly guidance rather than a machine-checked obligation.
"""

assert "evidence_window.source_health carries one typed row per declared source" in (
MANAGER_AGENT_OBJECTIVE
)
assert "including the local source" in MANAGER_AGENT_OBJECTIVE
assert "next_action as the repair" in MANAGER_AGENT_OBJECTIVE
assert "not a machine-checked obligation" in MANAGER_AGENT_OBJECTIVE


def test_remote_source_rows_are_typed_and_never_read_as_no_progress():
declared = [
{"source_id": "local", "source_host": "local", "status": "available"},
Expand Down
Loading