fix(librarian): quiet healthy-search coverage notes, tag clearing, strict result pairing

Phase A review minors:

- Coverage note: source_status (when present) is now used exclusively;
  the source_counts-absence fallback only considers the optional legs
  the request explicitly enabled (web/documents/volatile). library-desk
  computes source_counts from the final top-N fused results only, so
  absence of the always-on vector/graph legs is normal ranking behavior
  - the old heuristic warned on virtually every healthy search
- update_wiki_page: the empty-list tags sentinel (leave unchanged) made
  clearing all tags impossible; pass exactly ["__CLEAR__"] to send an
  empty tag list, documented in the docstring for the local model
- Text-delegation parallel fallback: zip(..., strict=True) with an
  explicit count-mismatch guard so results can never be silently
  attributed to the wrong agent

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbFZyDvYksazX6nYQYZ67L
This commit is contained in:
2026-07-14 11:59:15 +02:00
co-authored by Claude Fable 5
parent 31b948a748
commit 8cf3609948
5 changed files with 119 additions and 12 deletions
+16 -1
View File
@@ -178,9 +178,24 @@ async def _handle_text_delegation(
]
results = await asyncio.gather(*tasks, return_exceptions=True)
# asyncio.gather returns exactly one item per task; a length
# mismatch would mean results are attributed to the wrong
# agent, so fail loudly instead of mispairing silently.
if len(results) != len(matches):
logger.error(
"delegation_result_count_mismatch",
expected=len(matches),
got=len(results),
conversation_id=conversation_id,
)
return (
"I apologize, sir. I was unable to complete the "
"requested delegations."
)
# Combine results (failures carry curated user-safe sentences)
summaries = []
for (agent, task), item in zip(matches, results, strict=False):
for (agent, task), item in zip(matches, results, strict=True):
agent_name = agent.lower()
if isinstance(item, BaseException):
logger.error(