fix(steward): use the window source_health rows in the manager guidance - #4891
Conversation
The evidence window publishes evidence_window.source_health - one typed row per declared source, including the local source, with freshness, the typed reason, a coverage_effect and a next_action - but the manager objective only named the remote_evidence rows, so those rows were delivered as data with no instruction to use them and a declared-but-unread source stayed an unexplained gap. Add the matching guidance sentence next to the remote_evidence line, keeping the coverage effect explicitly guidance rather than a machine-checked obligation, and pin the prompt text with a focused assertion. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Reviewed exact head 5e9c474a3470a6562b1e02de7db0058ee251c98a.
动机
evidence_window.source_health 已经为每个 declared source(包括 local)提供 typed row:freshness、reason、coverage_effect 和 next_action 都齐全;但共享 manager objective 只明确解释了 remote_evidence。这会导致数据生产正确、消费契约却缺一段,尤其 local source 未读时,模型可能不给出具体原因与修复,甚至错误地把覆盖缺口说成“没有进展”。
改动思路
把修复放在共享的 MANAGER_AGENT_OBJECTIVE 是正确边界。所有 manager 入口已经复用这个 objective,source-health producer 也已经是 provider-neutral typed contract;因此无需改 row schema、复制 per-channel prompt,或新增 machine gate。新增语句只负责教模型如何消费现有数据。
具体改动
- 明确
evidence_window.source_health对每个 declared source 都有一行,并点名包括 local source。 - 对 unread / stale / unavailable source,要求使用该行自己的 typed
reason,并把next_action作为 repair。 - 明确
coverage_effect是关于证据支持范围的 guidance,不是 machine-checked obligation。 - 新增 focused prompt contract test,固定 field 名、local inclusion、repair 与 guidance/obligation 四个关键语义。
关键代码讲解
新增句子没有重新分类 source 状态,也不解析 prose;分类仍来自 _source_health_rows 的 typed producer。共享 objective 只是把 row 的 reason / next_action 投影到回答,并保留“缺少证据不是没有进展”的既有原则。rg 核对表明 chat manager、coordination、server 以及两个 Lark goal-topic runtime 路径都使用同一 objective,因此一处修改覆盖所有 active callers。
对主干的风险
这是一次有意的默认 manager guidance 变化,但没有新增权限、source read、状态写入、quota 或 scheduler effect。风险主要是 prompt contract 只能确定输入与指导语义,不能证明随机模型每次都严格服从;不过 typed producer、共享 load path 和 guidance-vs-obligation 边界都是确定性的。
验证结果完整:exact-head 与当前 origin/main 集成态的 focused pytest 均为 25 passed,Ruff、diff check、clean integration 通过,远端 CI 全绿。
我的整体评价
这个 PR 用最小改动补齐了“typed projection 已存在但 consumer 没有显式使用”的真实缺口,并且没有把 advisory evidence semantics 误升级成 machine obligation。未发现阻塞项,也没有必要增加额外 abstraction 或 per-channel 分叉。
English verdict: APPROVE - The exact head closes the shared source-health consumer gap with precise typed guidance, preserves authority boundaries, and is fully covered by focused and repository checks.
Goal / gap
evidence_window.source_healthalready ships one typed row per declared source — including the local source — withfreshness, the typedreason, acoverage_effectand anext_action, and_source_health_rowsalready documents why: a source that was declared but read nothing is a coverage fact the answer must name, never evidence that a Goal made no progress.The manager objective, however, named only the
remote_evidencerows. So the window rows were delivered as data with no instruction to use them, and a source that was declared but contributed nothing stayed an unexplained gap in the answer. The prompt said how to read remote rows and how to describe the dated window, but never how to read the per-source health that the same window publishes.Change
loopx/chat_manager.py: one guidance sentence next to the existingremote_evidenceline — name an unread, stale or unavailable source by itsreasonand give itsnext_actionas the repair, and readcoverage_effectas guidance about what that gap can support, not a machine-checked obligation (the coverage effect is advisory text, so it is not described as an obligation).tests/test_chat_manager_context.py: a focused assertion on the prompt text for the guidance sentence, the local-source coverage, thenext_action as the repairwording, and the guidance-vs-obligation phrase.No behaviour, gate, or payload change: the rows already exist, and this only makes the answer read them.
Validation
uv run --extra test python -m pytest tests/test_chat_manager_context.py -q→ 25 passed (includestest_source_health_rows_type_a_window_that_read_nothingand the new prompt-text assertion).uv run --extra test python -m ruff check loopx/chat_manager.py tests/test_chat_manager_context.py→ clean.Note on the first-screen / chat delivery work
This is one of the two remaining non-owner-gated rows for the steward lane; the first-screen look and the merge decisions stay with the owner.
Control-plane change: proposed for review, not self-merged.