CI & Build / Python lint (push) Successful in 5s
CI & Build / Plugin hooks (push) Successful in 17s
CI & Build / TypeScript typecheck (push) Successful in 57s
CI & Build / integration (push) Successful in 1m19s
CI & Build / Python tests (push) Successful in 2m2s
CI & Build / Build & push image (push) Successful in 15s
Docstrings, section headers and assertion messages drop the record number, milestone or step that introduced the behaviour, and incident accounts are restated as the present-tense failure shape. A dead pointer to a design doc that is not in the repo is removed. Renamed to the property they check: test_the_old_shape_would_be_caught -> test_a_rank_then_scope_query_is_caught test_a_ledger_repeat_no_longer_produces_that_case_at_all -> test_a_ledger_repeat_is_counted_not_withheld test_the_header_no_longer_promises_once_per_session -> test_the_header_explains_the_seen_marker test_the_portal_case_no_longer_stamps_one_canon_onto_a_whole_file -> test_one_canon_is_not_stamped_onto_a_whole_file test_the_repos_own_prose_no_longer_defines_with -> test_the_repos_own_prose_does_not_define_with test_the_original_regression_create_note_with_content -> test_the_real_server_refuses_content_on_create_note Fixture and example ids stay: "note 5" in a supersession chain, "rule 156" in an illustrative question, `#2275` as the hex-versus-citation case, `#3244` as the example of a bare number, fixed dates in date-filter tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
441 lines
19 KiB
Python
441 lines
19 KiB
Python
"""A canon may only be urged on a shape that could plausibly BE it.
|
|
|
|
WHY. `dominant_canon` is a base rate: it answers "what is most common in this
|
|
directory" and never "is this that". With `kind` carrying only `css | sym`, a
|
|
frozen dataclass, a module constant, a sync predicate, a class and an async
|
|
service function are all siblings, so the prior is the entire argument — it
|
|
would tell a registry module of pure helpers to build from an
|
|
`async_session` service canon. An auto-stamp without a resemblance floor
|
|
asserts 0.69 as confidently as 0.95.
|
|
|
|
The two halves compound: loose stamping manufactures the density that the
|
|
divergence check then reads as authority. Both are held by the same
|
|
primitive, and it is tested here on REAL signatures taken from the ledger —
|
|
Python, Go, TypeScript and Vue — rather than invented ones, because a
|
|
classifier that only works on the examples its author imagined is the failure
|
|
this is meant to end.
|
|
|
|
The unknown case is tested hardest. `forms_agree` requires BOTH sides to be
|
|
known, so an unreadable signature makes the checks quieter rather than more
|
|
confident. A guard that treats "I cannot tell" as "match" is the shape of the
|
|
bug, not the fix.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from scribe.services.shape_ledger import (
|
|
FORM_UNKNOWN, canon_form, comparable_siblings, dominant_canon,
|
|
families_conflict, forms_agree, shape_family, shape_form, signature_in,
|
|
)
|
|
|
|
|
|
class _Row:
|
|
"""A ledger row, as `canon_form` reads one."""
|
|
|
|
def __init__(self, signature, snippet_id=7, status="instance", kind="sym"):
|
|
self.signature, self.snippet_id = signature, snippet_id
|
|
self.status, self.kind = status, kind
|
|
|
|
|
|
# ── shape_form, on signatures actually in the ledger ──────────────────────
|
|
|
|
@pytest.mark.parametrize("signature,want", [
|
|
# Python
|
|
("class SessionAbsent(RuntimeError):", "type"),
|
|
("def build_channel() -> str:", "fn"),
|
|
("async def attach(self) -> None:", "async-fn"),
|
|
("async def _make_room(self, user_id: int, credential_id: int, opening) -> bool:",
|
|
"async-fn"),
|
|
("def test_version_regex_rejects_bad_formats():", "fn"),
|
|
# Go
|
|
("func NewService(pool *pgxpool.Pool, cfg *lidarrconfig.Service) *Service {", "fn"),
|
|
("type Store struct {", "type"),
|
|
# TypeScript / Vue SFC
|
|
("export function useBuild() {", "fn"),
|
|
("function offsetWords(minutes: number): string {", "fn"),
|
|
("export default class Thing {", "type"),
|
|
("interface Lesson {", "type"),
|
|
("const handler = async (req) => {", "async-fn"),
|
|
("const offset = (n) => n + 1", "fn"),
|
|
("const MAX_BUDGET = 10", "binding"),
|
|
# Unreadable
|
|
("", FORM_UNKNOWN),
|
|
(" ", FORM_UNKNOWN),
|
|
("# just a comment", FORM_UNKNOWN),
|
|
("}", FORM_UNKNOWN),
|
|
])
|
|
def test_shape_form_reads_real_signatures(signature, want) -> None:
|
|
assert shape_form(signature, "sym") == want
|
|
|
|
|
|
def test_css_is_its_own_form_regardless_of_signature() -> None:
|
|
assert shape_form(".pin {", "css") == "css"
|
|
assert shape_form("", "css") == "css"
|
|
|
|
|
|
def test_a_registry_modules_helpers_are_not_service_functions() -> None:
|
|
"""The concrete case. The canon is an `async def` service unit; none of
|
|
these is one."""
|
|
canon = shape_form("async def create_note(user_id: int, ...):", "sym")
|
|
assert canon == "async-fn"
|
|
for sig in (
|
|
"class Point:",
|
|
"def _p(source, kind, what, **kw) -> tuple[str, Point]:",
|
|
"def get_point(source: str) -> Point | None:",
|
|
"def is_registered(source: str) -> bool:",
|
|
"def sources_expected_to_emit() -> list[str]:",
|
|
):
|
|
assert not forms_agree(shape_form(sig, "sym"), canon), sig
|
|
|
|
|
|
def test_the_divergence_gate_silences_only_a_family_contradiction() -> None:
|
|
"""HONEST ACCOUNTING, and it is deliberately an assertion rather than a
|
|
comment so it fails the day the answer changes.
|
|
|
|
Divergence gates at FAMILY level and only on contradiction, because a form
|
|
mismatch is the PREMISE of a divergence prompt, not an objection to it —
|
|
see `shape_family`. So of these five this silences one: `Point` is a type
|
|
and the canon is a callable. The four `def` helpers are callables like the
|
|
canon and still ask.
|
|
|
|
That is not a shortcoming of the gate, it is the limit of the signature:
|
|
at this level those four are indistinguishable from the divergence
|
|
readout's acceptance case, where a sync `confirmDanger` beside an async
|
|
confirm helper SHOULD be flagged.
|
|
|
|
Widening `kind` does not separate them: it buys the silence by bucketing
|
|
`fn` apart from `async-fn`, which takes the async canon out of a sync
|
|
candidate's denominator and silences the acceptance case by the identical
|
|
mechanism, one layer down. Whatever separates these four
|
|
has to distinguish a helper that does the canon's JOB from one that does
|
|
not, and no signature carries that. A comparison of meaning is the only
|
|
lever, not one of two."""
|
|
canon = shape_form("async def create_note(user_id: int, ...):", "sym")
|
|
silenced = {
|
|
sig: families_conflict(shape_form(sig, "sym"), canon)
|
|
for sig in (
|
|
"class Point:",
|
|
"def _p(source, kind, what, **kw) -> tuple[str, Point]:",
|
|
"def get_point(source: str) -> Point | None:",
|
|
"def is_registered(source: str) -> bool:",
|
|
"def sources_expected_to_emit() -> list[str]:",
|
|
)
|
|
}
|
|
assert silenced["class Point:"] is True
|
|
assert sum(silenced.values()) == 1
|
|
|
|
|
|
def test_a_sync_function_beside_an_async_canon_is_still_a_fair_question() -> None:
|
|
"""The divergence readout's acceptance case: gating divergence on
|
|
`forms_agree` would silence a hand-rolled sync confirm in a directory
|
|
where an async confirm helper is canon — the exact prompt the readout
|
|
exists to produce."""
|
|
canon = shape_form("async function onTrash() {", "sym")
|
|
mine = shape_form("function confirmDanger() {", "sym")
|
|
assert canon == "async-fn" and mine == "fn"
|
|
assert not forms_agree(mine, canon) # the STAMP gate would refuse
|
|
assert not families_conflict(mine, canon) # the DIVERGENCE gate asks anyway
|
|
|
|
|
|
@pytest.mark.parametrize(("form", "want"), [
|
|
("fn", "callable"), ("async-fn", "callable"), ("type", "type"),
|
|
("binding", "value"), ("css", "css"), (FORM_UNKNOWN, ""),
|
|
])
|
|
def test_every_form_has_a_family_and_unknown_has_none(form, want) -> None:
|
|
assert shape_family(form) == want
|
|
|
|
|
|
@pytest.mark.parametrize(("a", "b"), [
|
|
(FORM_UNKNOWN, "fn"), ("fn", FORM_UNKNOWN), (FORM_UNKNOWN, FORM_UNKNOWN),
|
|
])
|
|
def test_an_unreadable_form_never_silences_a_divergence_prompt(a, b) -> None:
|
|
"""Same direction as everywhere else in this module: not knowing makes the
|
|
check quieter about ASSERTING and never quieter about ASKING."""
|
|
assert not families_conflict(a, b)
|
|
|
|
|
|
# ── forms_agree: unknown never matches ────────────────────────────────────
|
|
|
|
def test_two_known_equal_forms_agree() -> None:
|
|
assert forms_agree("fn", "fn")
|
|
|
|
|
|
def test_different_forms_do_not() -> None:
|
|
assert not forms_agree("fn", "async-fn")
|
|
assert not forms_agree("type", "fn")
|
|
|
|
|
|
@pytest.mark.parametrize("a,b", [
|
|
(FORM_UNKNOWN, "fn"), ("fn", FORM_UNKNOWN), (FORM_UNKNOWN, FORM_UNKNOWN),
|
|
])
|
|
def test_unknown_never_agrees_with_anything(a, b) -> None:
|
|
"""Including with itself — "I cannot tell" twice is not a match."""
|
|
assert not forms_agree(a, b)
|
|
|
|
|
|
# ── canon_form: a canon whose own rows disagree has no opinion ────────────
|
|
|
|
def test_a_canon_whose_instances_agree_asserts_that_form() -> None:
|
|
rows = [_Row("async def a():"), _Row("async def b():"), _Row("async def c():")]
|
|
assert canon_form(rows, 7) == "async-fn"
|
|
|
|
|
|
def test_a_canon_whose_instances_disagree_asserts_nothing() -> None:
|
|
"""One snippet recorded as canon for a class, a plain def, an async def
|
|
and a dozen tests. That spread is the SYMPTOM of
|
|
loose stamping, so reading it as "no opinion" makes the two fixes
|
|
cooperate — a poisoned canon falls silent instead of flagging others."""
|
|
rows = [_Row("class A:"), _Row("def b():"), _Row("async def c():")]
|
|
assert canon_form(rows, 7) == FORM_UNKNOWN
|
|
|
|
|
|
def test_a_clear_majority_still_asserts() -> None:
|
|
rows = [_Row("def a():"), _Row("def b():"), _Row("def c():"), _Row("class D:")]
|
|
assert canon_form(rows, 7) == "fn"
|
|
|
|
|
|
def test_rows_of_other_canons_and_unjudged_rows_do_not_vote() -> None:
|
|
rows = [
|
|
_Row("def a():"), _Row("def b():"), _Row("def c():"),
|
|
_Row("class X:", snippet_id=9), # another canon
|
|
_Row("class Y:", status="unclassified"), # not judged
|
|
_Row("class Z:", status="variant"), # a departure, not a vote
|
|
]
|
|
assert canon_form(rows, 7) == "fn"
|
|
|
|
|
|
def test_a_canon_with_no_readable_signatures_asserts_nothing() -> None:
|
|
assert canon_form([_Row(""), _Row(""), _Row("")], 7) == FORM_UNKNOWN
|
|
|
|
|
|
def test_a_canon_with_no_rows_at_all_asserts_nothing() -> None:
|
|
assert canon_form([], 7) == FORM_UNKNOWN
|
|
|
|
|
|
# ── signature_in: the payload is where a brand-new shape lives ────────────
|
|
|
|
CODE = '''
|
|
import re
|
|
|
|
MAX = 10
|
|
|
|
class Point:
|
|
"""A point."""
|
|
|
|
async def fetch(user_id: int) -> None:
|
|
...
|
|
|
|
def helper(x):
|
|
return x
|
|
|
|
export function useBuild() {
|
|
'''
|
|
|
|
|
|
@pytest.mark.parametrize("symbol,want_form", [
|
|
("Point", "type"),
|
|
("fetch", "async-fn"),
|
|
("helper", "fn"),
|
|
("useBuild", "fn"),
|
|
("MAX", "binding"),
|
|
])
|
|
def test_a_definition_in_the_payload_is_found(symbol, want_form) -> None:
|
|
assert shape_form(signature_in(CODE, symbol, "sym"), "sym") == want_form
|
|
|
|
|
|
def test_a_symbol_that_is_only_CALLED_is_not_a_definition() -> None:
|
|
"""The conflation worth keeping out: referencing a name is evidence of
|
|
USE, never of being that shape."""
|
|
assert signature_in("value = helper(3)\nreturn fetch(x)", "helper", "sym") == ""
|
|
|
|
|
|
def test_a_missing_symbol_yields_nothing_rather_than_a_guess() -> None:
|
|
assert signature_in(CODE, "nowhere", "sym") == ""
|
|
assert shape_form(signature_in(CODE, "nowhere", "sym"), "sym") == FORM_UNKNOWN
|
|
|
|
|
|
def test_an_empty_payload_yields_nothing() -> None:
|
|
assert signature_in("", "Point", "sym") == ""
|
|
|
|
|
|
def test_a_css_class_is_found_by_its_selector() -> None:
|
|
assert signature_in(".pin { color: red; }", "pin", "css").startswith(".pin")
|
|
assert signature_in(".pin { }", ".pin", "css").startswith(".pin")
|
|
|
|
|
|
def test_a_near_name_is_not_matched() -> None:
|
|
"""Word-bounded, so `helper` never claims `helper_two`."""
|
|
assert signature_in("def helper_two(x):\n ...", "helper", "sym") == ""
|
|
|
|
|
|
# ── The burden scales with the evidence ───────────────────────────────────
|
|
#
|
|
# Two kinds of evidence reach the stamp, and treating them alike was the
|
|
# first version of this fix and was wrong in both directions. An explicit
|
|
# by-name reference — the payload literally names the canon's symbol — is
|
|
# strong; demanding positive form agreement there silenced it whenever the
|
|
# shape's definition was not in the payload (an Edit rather than a Write),
|
|
# turning strong evidence into none for a reason unrelated to the code.
|
|
# A whole-file resemblance SCORE is weak: one number speaks for every symbol
|
|
# in the file, which is precisely how a class, an async method and a private
|
|
# helper were all recorded as instances of one snippet.
|
|
|
|
from scribe.services.shape_ledger import _stamp_allowed, forms_conflict # noqa: E402
|
|
|
|
|
|
@pytest.mark.parametrize("a,b,want", [
|
|
("fn", "type", True),
|
|
("async-fn", "fn", True),
|
|
("fn", "fn", False),
|
|
(FORM_UNKNOWN, "fn", False), # cannot contradict what you cannot read
|
|
("fn", FORM_UNKNOWN, False),
|
|
(FORM_UNKNOWN, FORM_UNKNOWN, False),
|
|
])
|
|
def test_forms_conflict_needs_both_sides_readable(a, b, want) -> None:
|
|
assert forms_conflict(a, b) is want
|
|
|
|
|
|
def test_a_named_reference_stands_unless_the_forms_contradict() -> None:
|
|
assert _stamp_allowed(2, "fn", "fn")
|
|
assert _stamp_allowed(2, FORM_UNKNOWN, "fn") # unreadable shape, strong evidence
|
|
assert _stamp_allowed(2, "fn", FORM_UNKNOWN)
|
|
assert not _stamp_allowed(2, "type", "fn") # a class is not that function
|
|
|
|
|
|
def test_a_resemblance_score_must_positively_agree() -> None:
|
|
"""The weak path, and the one that produced the mess being fixed."""
|
|
assert _stamp_allowed(1, "fn", "fn")
|
|
assert not _stamp_allowed(1, FORM_UNKNOWN, "fn")
|
|
assert not _stamp_allowed(1, "fn", FORM_UNKNOWN)
|
|
assert not _stamp_allowed(1, "type", "fn")
|
|
|
|
|
|
def test_one_canon_is_not_stamped_onto_a_whole_file() -> None:
|
|
"""A class, an async method and a sync helper in one file, against one
|
|
payload-level score. The score alone cannot carry any of them; only a
|
|
matching form can."""
|
|
canon = "async-fn"
|
|
written = [("class SessionAbsent(RuntimeError):", False),
|
|
("async def attach(self) -> None:", True),
|
|
("def _run_control_client(self, command: str) -> None:", False)]
|
|
for signature, should_stamp in written:
|
|
assert _stamp_allowed(1, shape_form(signature, "sym"), canon) is should_stamp
|
|
|
|
|
|
def test_the_resemblance_floor_is_above_the_retrieval_floors() -> None:
|
|
"""An unattended WRITE about the codebase should need more evidence than
|
|
a suggestion shown to a reader — the retrieval bars sit near 0.70."""
|
|
from scribe.services.shape_ledger import _RESEMBLE_MIN
|
|
|
|
assert _RESEMBLE_MIN >= 0.80
|
|
|
|
|
|
# ── The denominator, not the gate ─────────────────────────────────────────
|
|
#
|
|
# `dominant_canon` is a base rate, and a base rate is only a statement about
|
|
# something if its denominator is a population somebody asked a question
|
|
# about. It counted every code symbol in a directory as one bucket: a frozen
|
|
# dataclass, a module constant and an async service unit were three
|
|
# comparable things, and "372 judged siblings" was the authority the
|
|
# divergence line spoke with.
|
|
#
|
|
# `comparable_siblings` narrows it using the SAME predicate as the gate, so
|
|
# the count and the verdict cannot drift into disagreeing about what
|
|
# comparable means.
|
|
|
|
|
|
# `_Row` above is reused rather than redefined. A second class of the same
|
|
# name here shadowed the first — same fields, different `snippet_id` default —
|
|
# and silently broke three `canon_form` tests that had been passing, which is
|
|
# a neater demonstration of this file's subject than anything it asserts.
|
|
SERVICE = "async def get_note(user_id: int, note_id: int) -> Note | None:"
|
|
HELPER = "def is_registered(source: str) -> bool:"
|
|
|
|
|
|
def test_a_type_is_not_counted_against_a_directory_of_callables() -> None:
|
|
rows = [_Row(SERVICE) for _ in range(6)] + [_Row("class Point:", snippet_id=9)]
|
|
assert len(comparable_siblings(rows, shape_form("class Point:"))) == 1
|
|
|
|
|
|
def test_a_callable_is_not_counted_against_a_dataclass() -> None:
|
|
"""The honest-denominator half, and the one that changes reported numbers:
|
|
`judged` stops overstating how much of the directory was ever comparable."""
|
|
rows = [_Row(SERVICE) for _ in range(6)] + [_Row("class Point:", snippet_id=9)]
|
|
assert len(comparable_siblings(rows, shape_form(HELPER))) == 6
|
|
|
|
|
|
def test_the_async_canon_stays_in_a_sync_candidates_denominator() -> None:
|
|
"""THE DIVERGENCE READOUT'S ACCEPTANCE CASE, and the reason this narrows by family
|
|
rather than by form.
|
|
|
|
A hand-rolled sync `confirmDanger` in a directory where an async confirm
|
|
helper is canon must still be flagged. Bucketing the denominator by exact
|
|
form — which is what widening `kind` to carry `fn` vs `async-fn` amounts
|
|
to — would take the canon out of this count and silence it.
|
|
"""
|
|
rows = [_Row("async def confirmDanger(message: str) -> bool:") for _ in range(5)]
|
|
kept = comparable_siblings(rows, shape_form("function confirmDanger(message) {"))
|
|
assert len(kept) == 5
|
|
assert dominant_canon(kept) is not None
|
|
|
|
|
|
def test_an_unreadable_sibling_stays_counted() -> None:
|
|
"""Quieter, never louder. Dropping unknown rows shrinks `judged`, raises
|
|
the dominant canon's share, and fires the check MORE on exactly the
|
|
directories it can read least."""
|
|
rows = [_Row(SERVICE) for _ in range(4)] + [_Row("")]
|
|
assert len(comparable_siblings(rows, shape_form(SERVICE))) == 5
|
|
|
|
|
|
def test_an_unreadable_candidate_narrows_nothing() -> None:
|
|
"""The other side of the same discipline: a candidate whose own signature
|
|
says nothing gets the full denominator, not a guessed one."""
|
|
rows = [_Row(SERVICE), _Row("class Point:")]
|
|
assert comparable_siblings(rows, FORM_UNKNOWN) == rows
|
|
|
|
|
|
def test_a_family_passed_where_a_form_belongs_would_be_a_silent_no_op() -> None:
|
|
"""A REGRESSION GUARD ON A BUG THIS CHANGE ACTUALLY HAD.
|
|
|
|
`families_conflict` coarsens both sides itself, so handing it a family
|
|
makes `shape_family("callable")` return "" and the whole narrowing becomes
|
|
a no-op — while every call site still reads as though it applied. Pinned
|
|
because the wrong value is the right TYPE and the failure is silent.
|
|
"""
|
|
# A CALLABLE candidate, deliberately: `fn`'s family is `callable`, a word
|
|
# that is not itself a form, so `shape_family("callable")` is "" and the
|
|
# exclusion never fires. Picking `type` here would prove nothing — `type`
|
|
# is both a form and a family name, so passing the family still narrows
|
|
# and the bug hides. That near-miss is why this test exists at all.
|
|
rows = [_Row(SERVICE) for _ in range(6)] + [_Row("class Point:", snippet_id=9)]
|
|
form = shape_form("def helper(x) -> bool:")
|
|
assert shape_family(form) != form, "this test needs a form whose family differs"
|
|
by_form = comparable_siblings(rows, form)
|
|
by_family = comparable_siblings(rows, shape_family(form))
|
|
assert len(by_form) == 6, "the dataclass is not comparable to a function"
|
|
assert len(by_family) == len(rows), "a family narrows nothing — that is the bug"
|
|
assert by_form != by_family
|
|
|
|
|
|
def test_callable_helpers_beside_a_callable_canon_still_prompt() -> None:
|
|
"""HONEST ACCOUNTING, matching the sibling test above.
|
|
|
|
The narrowed denominator does not silence the four `def` helpers, and
|
|
cannot: they are callables, the canon is a callable, so nothing is
|
|
excluded from their count. What it buys is that the count is over
|
|
comparable things. Asserted so the claim cannot quietly rot into
|
|
"this fixed it".
|
|
"""
|
|
rows = [_Row(SERVICE) for _ in range(6)] + [_Row("class Point:", snippet_id=9)]
|
|
for sig in (
|
|
"def _p(source, kind, what, **kw) -> tuple[str, Point]:",
|
|
"def get_point(source: str) -> Point | None:",
|
|
"def is_registered(source: str) -> bool:",
|
|
"def sources_expected_to_emit() -> list[str]:",
|
|
):
|
|
kept = comparable_siblings(rows, shape_form(sig))
|
|
dom = dominant_canon(kept)
|
|
assert dom is not None, sig
|
|
assert not families_conflict(shape_form(sig), canon_form(kept, dom[0])), sig
|