Skip to content

test(kb): a shrink-only guard over every knowledge-base read entry point #16667

Description

@mrveiss

Parent: #16654. This is #16654's AC3, landed early as a ratchet so that every later sub-issue shrinks it.

Problem

No test enumerates the knowledge-base read entry points. A new route, tool or prompt path can read facts unfiltered, and nothing notices. Today only /api/knowledge/search/scoped and /rag/scoped filter; every other path listed in #16654's sub-issues does not.

Acceptance criteria

Refs #16654

Activity

  1. mrveiss commented on Sep 13, 2026

    @mrveiss
    OwnerAuthor

    AC1 is still open after the first guard PR. That PR installs a call-site guard (repo_tests/kb_read_visibility_guard_test.py) with a frozen, shrink-only allowlist of 84 entries. Its AST detector finds <kb receiver>.<read primitive>(...) calls, plus advanced_search on RAG receivers, but it cannot see:

    • a KB method stored as a bound method and called later (HybridSearcher keeps self.search, knowledge/search.py:141-144);
    • polymorphic backend dispatch (VectorSearchEngine._select_backend → backend.search);
    • filters hidden in **kwargs (services/knowledge_base_adapter.py:82/85, api/knowledge_search.py:606/610);
    • the infra MCP server's HTTP hop to /mcp/search_knowledge_base;
    • reads that bypass the primitives:
      • direct fact:* Redis reads (api/knowledge_vectorization.py:616, background_vectorization.py:290, api/knowledge_organization.py:158/277);
      • raw ChromaDB collection reads (api/knowledge_maintenance.py:1909, api/knowledge_chroma.py:264/350);
      • the summary and temporal search services (api/knowledge_graph_routes.py);
    • receivers outside the known set (kb, self.kb, knowledge_base, kb_to_use, …), and reads outside any function.

    To close AC1, the detector must cover these, or each one gets its own guard. Until then the per-path sub-issues (#16664, #16665, #16666) carry the paths themselves.

  2. added this to the v0.11.0 milestone on Sep 14, 2026
  3. mrveiss commented on Sep 20, 2026

    @mrveiss
    OwnerAuthor

    This landed via PR #16674 (merged 2026-09-14, branch pr16674new assigned to this issue is a stale local snapshot of it — checked, superseded, not reviving) and has been extended further since. Verifying each AC against current origin/main (repo_tests/kb_read_visibility_guard_test.py / kb_read_visibility_allowlist.py):

    • Static-analysis guard over every production entry point. kb_reads()/_scan()/_production_files() (kb_read_visibility_guard_test.py:174-327) walk production source with Python's ast module — no hand-kept list of entry points, the scan finds them. test_the_scan_is_not_blind and test_every_scan_root_is_reached guard against the scan silently reaching nothing.
    • Every entry point filters or sits in a reasoned, shrink-only allowlist; fails both directions. test_every_unfiltered_kb_read_is_allowlisted catches a new bypass; test_every_allowlist_entry_is_still_an_unfiltered_read catches an allowlisted entry that started filtering but is still listed (exactly AC2's two-directional requirement); test_every_allowlist_reason_is_classified requires each entry carry a real reason.
    • Ratchet enforces shrink, never re-grows silently. UNFILTERED_READ_CEILING = 95 (:168) plus _ceiling_verdict/test_the_detected_unfiltered_reads_sit_at_the_recorded_ceiling/test_the_ceiling_verdict_turns_both_ways (:363-389) fail on growth AND on an unlowered ceiling after a shrink — the "landed early as a ratchet so every later sub-issue shrinks it" framing this issue exists for is live and enforced now, which is what this issue's own scope was (the shrinking itself is security(kb): fact visibility is not enforced on the canonical read paths — knowledge_search and the grounded-agent RAG path never call check_access #16654's later sub-issues' job, tracked there).

    All three ACs met with code evidence on current main. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions