docs(6209): rulebooks, pull telemetry, lesson usage, duplicate arm, cited status, trigger shape
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 1m3s
CI & Build / Python tests (push) Successful in 1m55s
CI & Build / Build & push image (push) Successful in 13s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 1m3s
CI & Build / Python tests (push) Successful in 1m55s
CI & Build / Build & push image (push) Successful in 13s
Six more test files state their pinned properties without the issue and milestone history: the pull-telemetry guard explains enumerating kinds instead of listing two getter incidents, cited-record status explains why a hint's id needs its status instead of recounting one misreported step, and the trigger-shape guard keeps its reasoning about why prose heuristics fail while dropping the dated corpus audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,21 +1,18 @@
|
||||
"""A lesson's surfaced-vs-opened counts reach a reader (#4196).
|
||||
"""A lesson's surfaced-vs-opened counts reach a reader.
|
||||
|
||||
The lesson slot has recorded usage since it shipped, and until this nothing
|
||||
showed it. `get_lesson`'s REST door attached it; the list did not, neither MCP
|
||||
door did, and no view rendered it — so the one kind whose central question is
|
||||
"is this trigger firing on the right situation" was the one kind whose answer
|
||||
was unreadable.
|
||||
Every door — the REST list and detail, both MCP doors, and the view — carries
|
||||
the counts, because the one kind whose central question is "is this trigger
|
||||
firing on the right situation" needs that answer readable.
|
||||
|
||||
WHY THE COUNTS MATTER MORE HERE THAN ON A SNIPPET. #4196 asks whether a lesson
|
||||
repeatedly followed should become a rule, and names the trap: raw frequency
|
||||
WHY THE COUNTS MATTER MORE HERE THAN ON A SNIPPET. Whether a lesson repeatedly
|
||||
followed should become a rule has a trap: raw frequency
|
||||
cannot tell "this should bind" from "this trigger is too broad", which is the
|
||||
commoner reading. Surfaced-AND-opened can. Neither question is answerable by
|
||||
anything that cannot see the numbers, which is why this is the first step and
|
||||
not the threshold.
|
||||
|
||||
NO THRESHOLD IS ASSERTED ANYWHERE HERE, deliberately. At the time of writing
|
||||
the corpus is 10 lessons with 7 recorded surfacings and 3 opens; a promotion
|
||||
rule fitted to that would be fitting noise, and `UsageBadge` already declines
|
||||
NO THRESHOLD IS ASSERTED ANYWHERE HERE, deliberately. A promotion rule fitted
|
||||
to a small corpus would be fitting noise, and `UsageBadge` already declines
|
||||
to render a verdict on fewer than three surfacings for the same reason.
|
||||
"""
|
||||
import inspect
|
||||
@@ -115,11 +112,10 @@ async def test_get_lesson_reads_the_count_before_recording_its_own_pull():
|
||||
assert out["usage"]["pull_count"] == 1
|
||||
|
||||
|
||||
# ── the REST door, on structure (rule 167) ───────────────────────────────────
|
||||
# ── the REST door, on structure ──────────────────────────────────────────────
|
||||
#
|
||||
# MOVED 2026-09-21 (#4230), not weakened. These used to look for
|
||||
# `usage_for_notes(` and `empty_usage()` in the route body. Both now live in
|
||||
# ONE seam, `note_usage.attach_usage`, which seven doors share — so the
|
||||
# `usage_for_notes(` and `empty_usage()` live in ONE seam,
|
||||
# `note_usage.attach_usage`, which seven doors share — so the
|
||||
# zero-fill and the single aggregate are pinned once, against the seam, in
|
||||
# tests/test_usage_attach_seam.py. What stays HERE is what only this route can
|
||||
# get wrong: that it calls the seam at all, once, and before it records a pull.
|
||||
@@ -166,7 +162,7 @@ def test_the_rest_detail_door_also_reads_before_it_records():
|
||||
|
||||
|
||||
def test_these_guards_can_fail():
|
||||
"""Rule 167: falsify the shape they assert against, so a guard that has
|
||||
"""Falsify the shape they assert against, so a guard that has
|
||||
quietly stopped describing anything cannot pass by describing nothing."""
|
||||
src = _route_source("list_lessons_route")
|
||||
assert "def list_lessons_route" in src
|
||||
@@ -174,21 +170,21 @@ def test_these_guards_can_fail():
|
||||
|
||||
|
||||
def test_the_detail_view_renders_the_badge_rather_than_respelling_it():
|
||||
"""Snippet #3460: reach for UsageBadge and pass the kind's own advice; a
|
||||
view's scoped re-spelling of `.usage-tag` is what that component replaced.
|
||||
"""Reach for UsageBadge and pass the kind's own advice; a view's scoped
|
||||
re-spelling of `.usage-tag` is what that component exists to prevent.
|
||||
|
||||
The advice is the kind-specific half. For a lesson it points at the
|
||||
trigger, not at deletion — a lesson nobody opens is usually keyed to a
|
||||
situation nobody is in, which is `update_lesson`'s own words and the
|
||||
reading #4196 calls the commoner one.
|
||||
commoner reading.
|
||||
"""
|
||||
view = (Path(__file__).resolve().parents[1]
|
||||
/ "frontend/src/views/LessonDetailView.vue").read_text()
|
||||
assert "UsageBadge" in view
|
||||
assert "usage-tag" not in view, "re-spelled the chip instead of reusing it"
|
||||
|
||||
# The sentence moved out of this template into the shared table (#4230,
|
||||
# recorded on #3460). Assert BOTH halves, so the guard cannot pass by the
|
||||
# The sentence lives in the shared table, not this template. Assert BOTH
|
||||
# halves, so the guard cannot pass by the
|
||||
# view pointing at an entry that no longer says the right thing.
|
||||
assert "DEAD_WEIGHT_ADVICE.lesson" in view, "the view no longer reads the lesson advice"
|
||||
table = (Path(__file__).resolve().parents[1]
|
||||
|
||||
Reference in New Issue
Block a user