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:
@@ -17,7 +17,7 @@ pytestmark = pytest.mark.usefixtures("_bind_user")
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_systems():
|
||||
"""enter_project now surfaces the project's Systems as the tagging
|
||||
vocabulary (#2546). These are tool-layer unit tests with no database, so
|
||||
vocabulary. These are tool-layer unit tests with no database, so
|
||||
the lookup is stubbed to the common case — a project with none. The
|
||||
populated shape is asserted in its own test below.
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ def _no_platforms():
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_coverage():
|
||||
"""enter_project also reads the pattern-coverage cache (#2692) — same
|
||||
"""enter_project also reads the pattern-coverage cache — same
|
||||
deal: no database here, stub the common case (nothing computed). The
|
||||
populated line is asserted in tests/test_pattern_coverage.py.
|
||||
"""
|
||||
@@ -51,7 +51,7 @@ def _no_coverage():
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_family():
|
||||
"""enter_project reads the family-canon readout (milestone 463 step 6) —
|
||||
"""enter_project reads the family-canon readout —
|
||||
no database here, so the common case is stubbed: nothing to answer. The
|
||||
populated key is asserted in its own test below."""
|
||||
with patch("scribe.mcp.tools.projects.family_adoption_svc.family_readout",
|
||||
@@ -61,7 +61,7 @@ def _no_family():
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_background_seed():
|
||||
"""enter_project now fire-and-forgets a coverage self-seed (#2802). These
|
||||
"""enter_project fire-and-forgets a coverage self-seed. These
|
||||
are no-database unit tests, so the spawn is stubbed out; the firing shape
|
||||
has its own test below."""
|
||||
with patch("scribe.mcp.tools.projects.spawn") as mock:
|
||||
@@ -71,7 +71,7 @@ def _no_background_seed():
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_bootstrap():
|
||||
"""With _no_systems stubbing an empty vocabulary, every test here reaches
|
||||
the zero-Systems branch, whose bootstrap ask (#2683) counts the project's
|
||||
the zero-Systems branch, whose bootstrap ask counts the project's
|
||||
records — a database read. Stub the common case (young project, no ask);
|
||||
the firing shape has its own test below.
|
||||
"""
|
||||
@@ -117,7 +117,7 @@ async def test_get_project_enriches_with_milestone_summary():
|
||||
async def test_get_project_includes_applicable_rules_and_project_rules():
|
||||
"""The augmented get_project response includes applicable_rules and
|
||||
project_rules pulled from services/rulebooks.get_applicable_rules, and
|
||||
nothing about subscriptions (milestone 414).
|
||||
nothing about subscriptions.
|
||||
"""
|
||||
p = fake_project(id=3, title="Fabled Assistant")
|
||||
milestone_summary = []
|
||||
@@ -191,7 +191,7 @@ async def test_update_project_raises_when_not_found():
|
||||
@pytest.mark.asyncio
|
||||
async def test_enter_project_composes_full_context():
|
||||
"""enter_project pulls project + rule titles + milestone summary + open
|
||||
tasks in one composed call, each in its brief handshake form (#4045)."""
|
||||
tasks in one composed call, each in its brief handshake form."""
|
||||
p = fake_project(id=5, title="P")
|
||||
applicable_payload = {
|
||||
"rules": [{"id": 1, "title": "r1", "statement": "s",
|
||||
@@ -226,7 +226,7 @@ async def test_enter_project_composes_full_context():
|
||||
assert out["project"] == {"id": 5, "title": "P", "status": "active", "goal": ""}
|
||||
assert out["milestone_summary"] == milestone_summary
|
||||
# Rules arrive in full by retrieval; the handshake lists the project's own
|
||||
# by id and title (#4045), and nothing about subscriptions (milestone 414).
|
||||
# by id and title, and nothing about subscriptions.
|
||||
assert out["project_rules"] == [{"id": 99, "title": "pr1"}]
|
||||
for gone in ("applicable_rules", "applicable_rules_truncated", "subscribed_rulebooks",
|
||||
"suppressed_rules", "suppressed_topics", "recent_notes"):
|
||||
@@ -244,16 +244,14 @@ async def test_enter_project_composes_full_context():
|
||||
# create-the-System instruction acts on.
|
||||
assert out["systems"] == []
|
||||
# Young project, no bootstrap ask -> the key is ABSENT, not null: it exists
|
||||
# to be acted on, and a key that usually says null gets skipped (#2483).
|
||||
# to be acted on, and a key that usually says null gets skipped.
|
||||
assert "systems_bootstrap" not in out
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_enter_project_surfaces_the_systems_vocabulary():
|
||||
"""The tagging instruction is only executable if the vocabulary is in
|
||||
front of the agent when it writes. It never was, and tagging stopped three
|
||||
days after the feature landed — one System, nothing tagged since July 28
|
||||
(#2546's audit). Trimmed to id/name/first-line: it rides on every session
|
||||
front of the agent when it writes. Trimmed to id/name/first-line: it rides on every session
|
||||
start, and the full charter is get_system's job."""
|
||||
p = fake_project(id=5)
|
||||
sys1 = MagicMock()
|
||||
@@ -298,7 +296,7 @@ def _enter_project_stubs(p):
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_enter_project_carries_the_bootstrap_ask_when_it_fires():
|
||||
"""The arrival-moment half of #2683: a mature zero-Systems project greets
|
||||
"""The arrival-moment half of the bootstrap ask: a mature zero-Systems project greets
|
||||
the session with the concrete bootstrap ask, before it is deep in a task —
|
||||
the moment minting a starter vocabulary is cheapest."""
|
||||
import contextlib
|
||||
@@ -341,7 +339,7 @@ async def test_enter_project_never_asks_bootstrap_once_a_vocabulary_exists(
|
||||
async def test_enter_project_fires_the_coverage_seed_on_the_owner(
|
||||
_no_background_seed,
|
||||
):
|
||||
"""The arrival self-seed (#2802): entering spawns refresh_if_stale on the
|
||||
"""The arrival self-seed: entering spawns refresh_if_stale on the
|
||||
project OWNER's id with the cache read the enter already did — fire and
|
||||
forget, so a missing ledger seeds itself without the UI button, and the
|
||||
enter stays fast."""
|
||||
@@ -393,7 +391,7 @@ async def test_enter_project_hands_back_the_design_system_when_the_project_has_o
|
||||
|
||||
assert out["design_system"]["token_count"] == 95
|
||||
assert out["design_system"]["inherits_from"] == ["House"]
|
||||
# Summary only: the guidance is one call away (#4045).
|
||||
# Summary only: the guidance is one call away.
|
||||
assert "guidance" not in out["design_system"]
|
||||
assert out["design_system"]["guidance_call"] == "get_design_system(9) → resolved_guidance"
|
||||
assert ctx.await_args.args == (7, 9) # caller's id, the project's system
|
||||
@@ -418,7 +416,7 @@ def test_enter_project_registered_in_register():
|
||||
assert "enter_project" in mcp.names
|
||||
|
||||
|
||||
# --- milestone 297: the inception doors ---------------------------------------
|
||||
# --- the inception doors -----------------------------------------------------
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -491,7 +489,7 @@ def test_inception_routes_and_tool_are_registered():
|
||||
tool = mcp._tool_manager.get_tool("create_project")
|
||||
for name in ("design_system_id", "seed_systems"):
|
||||
assert name in tool.parameters.get("properties", {}), name
|
||||
# Rules left inception with subscriptions (milestone 414).
|
||||
# Inception carries no rulebook subscriptions.
|
||||
assert "subscribe_rulebooks" not in tool.parameters.get("properties", {})
|
||||
|
||||
|
||||
@@ -500,7 +498,7 @@ def test_inception_routes_and_tool_are_registered():
|
||||
async def test_enter_project_carries_the_family_line_only_when_it_asks_something(_no_family):
|
||||
"""The `family` key is attached when the project has family canon to
|
||||
answer, and absent otherwise — a key that usually says null trains
|
||||
readers to skip it (#2483)."""
|
||||
readers to skip it."""
|
||||
line = {"line": "family canon on this project's platforms: 2 unassessed",
|
||||
"unassessed": 2, "owed": 0, "needs_recheck": 0,
|
||||
"calls": {"unassessed": 'list_family_adoptions(project_id=5, status="unassessed")'}}
|
||||
|
||||
Reference in New Issue
Block a user