fix(6247): a getter is seen by its pulls, so the silent list stops naming every pull door
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 1m5s
CI & Build / Python tests (push) Successful in 1m56s
CI & Build / Build & push image (push) Successful in 22s

usage and rule_usage gain pulled_by_source, read from the per-source rows
the readout already had, and _silent_surfaces counts those doors as having
emitted. The rules-listing points were seen as of the previous commit,
through rule_usage.by_source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 19:28:29 -04:00
co-authored by Claude Opus 5.5
parent d05d4f3632
commit 1fa9245bbf
3 changed files with 59 additions and 0 deletions
@@ -666,6 +666,40 @@ async def test_rule_by_source_says_which_arm_earns_its_lines(_dispose_engine):
await cleanup()
@pytest.mark.integration
@pytest.mark.asyncio
async def test_a_pull_door_and_a_rules_listing_are_not_reported_silent(
_dispose_engine,
):
"""One note pulled through its getter and one rules payload on get_task:
both points emitted, so neither may be named as silent."""
from sqlalchemy import delete
from grimoire.models import async_session
from grimoire.models.note_usage import NoteUsageEvent
from grimoire.services.retrieval_telemetry import retrieval_summary
UID = 990017
cleanup = await _rule_events(UID, [(5401, "surfaced", "get_task")])
async with async_session() as s:
s.add_all([
NoteUsageEvent(user_id=UID, note_id=11, event="surfaced", source="auto_inject"),
NoteUsageEvent(user_id=UID, note_id=11, event="pulled", source="mcp_get_note"),
])
await s.commit()
try:
out = await retrieval_summary(UID, days=30)
assert out["usage"]["pulled_by_source"] == {"mcp_get_note": 1}
quiet = {p["source"] for p in out["silent_surfaces"]}
assert "mcp_get_note" not in quiet
assert "get_task" not in quiet
finally:
await cleanup()
async with async_session() as s:
await s.execute(delete(NoteUsageEvent).where(NoteUsageEvent.user_id == UID))
await s.commit()
@pytest.mark.integration
@pytest.mark.asyncio
async def test_ambient_alone_reports_no_ratio(_dispose_engine):