docs(6209): snippets, rule embeddings, notes, ledger ageing and references, routes, reporting, handshake, lesson kind, request deadlines, contract-around-change, family models
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 1m0s
CI & Build / integration (push) Successful in 1m14s
CI & Build / Python tests (push) Successful in 1m59s
CI & Build / Build & push image (push) Successful in 15s

Twelve more test files drop issue, milestone, rule, note, lesson and
snippet numbers and the dated or one-project figures that recorded how
each property was found; the docstrings state the property and why it
holds. The contract-around-the-change guard keeps the dict-key example as
the failure a signature-watcher misses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 21:34:24 -04:00
co-authored by Claude Opus 5.5
parent ead4a7e2ad
commit d0d278dcce
12 changed files with 100 additions and 112 deletions
+10 -10
View File
@@ -1,9 +1,9 @@
"""The enter_project handshake stays a small primer (#4045).
"""The enter_project handshake stays a small primer.
enter_project once carried every milestone's full plan body, the whole project
record, full rule text and ~9k of design guidance. On a project with 39
milestones that came to ~222k characters, past what an MCP client accepts as
a tool result, so the session handshake arrived as a file to page through.
Every milestone's full plan body, the whole project record, full rule text and
the design guidance add up, on a project with a few dozen milestones, to more
than an MCP client accepts as a tool result — and the session handshake
arrives as a file to page through.
"""
import contextlib
import json
@@ -66,7 +66,7 @@ def test_brief_rows_leave_out_the_plan_and_what_the_caller_already_knows():
"id": 1, "title": "M1", "description": "what M1 is for", "status": "active",
"order_index": 1, "total": 4, "completed": 2, "pct": 50.0,
"status_counts": {"todo": 2, "in_progress": 0, "done": 2, "cancelled": 0},
# Trimmed of the plan body, but NOT of which step is next (#4154): the
# Trimmed of the plan body, but NOT of which step is next: the
# listing is where "2 of 4 done" gets read, and that number is exactly
# what invites a reader to name the open step from memory.
"next_step": {"id": 901, "title": "M1 step 3", "status": "todo"},
@@ -187,7 +187,7 @@ async def test_open_tasks_name_their_milestone_even_when_it_is_not_listed():
@pytest.mark.asyncio
async def test_omitted_key_is_absent_when_nothing_was_left_out():
"""Attached only when it applies (#2483)."""
"""Attached only when it applies."""
out, _ = await _enter(*_enter_stubs(fake_project(id=5), _history(3), []))
assert len(out["milestone_summary"]) == 3
assert "milestone_summary_omitted" not in out
@@ -217,8 +217,8 @@ async def test_list_milestones_lists_every_milestone_without_plans():
def test_a_planning_read_lists_rules_without_restating_them():
"""#4081: a project's listing is every global rule tagged to its areas, so
the full rule_brief of each put start_planning at 92k characters. Planning
"""A project's listing is every global rule tagged to its areas, so the
full rule_brief of each would make a planning read enormous. Planning
reads name the rules; get_rule reads one."""
from scribe.services.rulebooks import rules_payload
@@ -241,7 +241,7 @@ def test_a_planning_read_lists_rules_without_restating_them():
assert len(json.dumps(out)) < 6_000, len(json.dumps(out))
# ── Milestones with no steps are open work (milestone 415) ─────────────────
# ── Milestones with no steps are open work ─────────────────────────────────
def _planless(mid: int, status: str = "active") -> dict: