docs(6209): twelve more test files say which behaviour they pin
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 1m12s
CI & Build / Python tests (push) Successful in 1m53s
CI & Build / Build & push image (push) Successful in 12s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 1m12s
CI & Build / Python tests (push) Successful in 1m53s
CI & Build / Build & push image (push) Successful in 12s
shape ledger, MCP projects/search/rulebooks tools, backup, chunking, plugin context, derived mirror, rule band, shape form gate, plugin version mint and note usage tests drop issue, milestone and rule numbers, dates and one-install figures from docstrings, comments and messages. Three shape-form-gate test names that told the discovery story now name the property: a registry module's helpers are not service functions, the divergence gate silences only a family contradiction, and callable helpers beside a callable canon still prompt. The rulebook tool-count comment that logged each milestone's additions is replaced by the reason it is a count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,7 @@ async def test_fable_search_returns_repackaged_results():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_search_shows_the_passage_that_matched_not_the_opening():
|
||||
"""The point of #4243. A record can rank on its sixth paragraph; showing
|
||||
"""A record can rank on its sixth paragraph; showing
|
||||
its first is showing the caller a span the search already judged less
|
||||
relevant, and letting them decide from it."""
|
||||
_user_id_ctx.set(7)
|
||||
@@ -131,7 +131,7 @@ async def test_fable_search_content_type_filters_at_service_layer():
|
||||
specific kinds arrived — it is BROAD here (any non-task, snippets and
|
||||
lessons included) while the web facet of the same name is narrow. Pinning
|
||||
it stops a later tidy-up from silently removing snippets from every caller
|
||||
that already asks this way (#4250)."""
|
||||
that already asks this way."""
|
||||
_user_id_ctx.set(7)
|
||||
mock_search = AsyncMock(return_value=[])
|
||||
with patch("scribe.mcp.tools.search.semantic_search_notes", mock_search):
|
||||
@@ -149,7 +149,7 @@ async def test_fable_search_content_type_filters_at_service_layer():
|
||||
assert mock_search.call_args.kwargs["is_task"] is None
|
||||
|
||||
|
||||
# --- the specific kinds: the engine already supported them (#4250) -----------
|
||||
# --- the specific kinds the engine supports ----------------------------------
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -181,9 +181,8 @@ async def test_each_specific_kind_reaches_the_engine_filter_it_names(
|
||||
|
||||
|
||||
def test_the_vocabulary_is_derived_from_the_facet_table_not_recopied():
|
||||
"""#3161's property, held at this door too: adding a kind to `_FACETS` is
|
||||
one edit. A hand-kept list here is exactly how the agent's search came to
|
||||
offer two kinds while the web's offered nine."""
|
||||
"""Adding a kind to `_FACETS` is one edit, at this door too. A hand-kept
|
||||
list here lets the agent's search offer fewer kinds than the web's."""
|
||||
from scribe.services.knowledge import FACET_TYPES, content_type_filters
|
||||
|
||||
for facet in FACET_TYPES:
|
||||
@@ -191,7 +190,7 @@ def test_the_vocabulary_is_derived_from_the_facet_table_not_recopied():
|
||||
assert "is_task" in filters, facet
|
||||
|
||||
# The guard can fail: a name absent from the table is refused, so this is
|
||||
# membership in the table and not "every string works" (#167).
|
||||
# membership in the table and not "every string works".
|
||||
with pytest.raises(ValueError):
|
||||
content_type_filters("a-kind-that-is-not-in-the-facet-table")
|
||||
|
||||
@@ -215,7 +214,7 @@ async def test_an_unknown_content_type_is_refused_rather_than_returning_nothing(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_the_docstring_names_every_kind_the_tool_accepts():
|
||||
"""The docstring IS the agent-facing contract (#2846) — a filter an agent
|
||||
"""The docstring IS the agent-facing contract — a filter an agent
|
||||
has not been told about is unreachable however well it is wired."""
|
||||
from scribe.mcp.tools.search import search as search_tool
|
||||
from scribe.services.knowledge import FACET_TYPES
|
||||
@@ -229,12 +228,12 @@ async def test_the_docstring_names_every_kind_the_tool_accepts():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_an_explicit_search_reaches_a_lesson_from_any_project():
|
||||
"""The wiring half of milestone 385 step 3.
|
||||
"""An explicit search reaches lessons in every project.
|
||||
|
||||
A lesson records an insight that transfers, so a project filter that hid it
|
||||
would hide it precisely on the project that has not learned it yet. This is
|
||||
the EXPLICIT search — the operator asked — so it opts in; the unasked-for
|
||||
injection arms decide their own budget separately (step 5).
|
||||
injection arms decide their own budget separately.
|
||||
|
||||
Asserted on the kwarg rather than on results, because what can regress here
|
||||
is the wiring: the service grew the capability and a call site that never
|
||||
@@ -269,7 +268,7 @@ async def test_fable_search_limit_is_clamped():
|
||||
(0, {"everywhere": True}),
|
||||
])
|
||||
async def test_rule_search_scopes_to_the_project_it_is_given(project_id, scope):
|
||||
"""With a project: global rules plus that project's (milestone 414).
|
||||
"""With a project: global rules plus that project's.
|
||||
Without one: every rule, because an unscoped "is there a rule about this"
|
||||
is asking the whole rulebook — unlike a hook, which speaks unasked."""
|
||||
_user_id_ctx.set(7)
|
||||
@@ -293,14 +292,13 @@ def test_a_milestone_is_embedded_by_what_it_is_for_then_its_plan():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_milestone_search_is_its_own_shape_and_scopes_to_the_project():
|
||||
"""milestone 415: 'is there already a plan for this?' has a tool."""
|
||||
"""'Is there already a plan for this?' has a tool."""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
_user_id_ctx.set(7)
|
||||
# `body` is a REAL string, not left to MagicMock's attribute autovivication:
|
||||
# the result now reads it, and a mock body would make `matched` a mock
|
||||
# object and `body_length` zero while the assertion still looked green
|
||||
# (lesson #2833).
|
||||
# object and `body_length` zero while the assertion still looked green.
|
||||
ms = MagicMock(id=339, title="M3 — Metadata", description="works, editions",
|
||||
status="active", project_id=30,
|
||||
body="Step 4 — the metadata editions table.")
|
||||
@@ -323,7 +321,7 @@ async def test_milestone_search_is_its_own_shape_and_scopes_to_the_project():
|
||||
assert out["results"] == [{
|
||||
"id": 339, "title": "M3 — Metadata", "description": "works, editions",
|
||||
# The plan body stays out; the passage that matched comes along, and
|
||||
# says which of the two it is (#4243).
|
||||
# says which of the two it is.
|
||||
"matched": "Step 4 — the metadata editions table.",
|
||||
"matched_is": "matched_passage",
|
||||
"body_length": len("Step 4 — the metadata editions table."),
|
||||
@@ -332,7 +330,7 @@ async def test_milestone_search_is_its_own_shape_and_scopes_to_the_project():
|
||||
}]
|
||||
|
||||
|
||||
# --- systems: the charter as an answer, not a filter (#4251) -----------------
|
||||
# --- systems: the charter as an answer, not a filter -------------------------
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -340,7 +338,7 @@ async def test_system_search_is_its_own_shape_and_carries_the_matched_passage():
|
||||
"""A System's charter runs to several hundred words and a result shows its
|
||||
NAME — so a match on the paragraph that actually decides where a record
|
||||
belongs would be previewed by two words that cannot. The passage comes
|
||||
along, marked as the passage (#4243)."""
|
||||
along, marked as the passage."""
|
||||
_user_id_ctx.set(7)
|
||||
charter = (
|
||||
"Opening sentence about the area in general. "
|
||||
@@ -349,7 +347,7 @@ async def test_system_search_is_its_own_shape_and_carries_the_matched_passage():
|
||||
)
|
||||
fake = MagicMock(id=3, project_id=2, description=charter)
|
||||
# `name` is MagicMock's own constructor kwarg — passed in, it names the
|
||||
# mock and leaves `.name` a mock object, which is note #2833's whole point.
|
||||
# mock and leaves `.name` a mock object.
|
||||
fake.name = "Retrieval & recall"
|
||||
|
||||
async def _system_search(uid, q, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user