From 4c150cbc2f3194486372720bd20be86f5674a068 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 21 Oct 2026 21:46:57 -0400 Subject: [PATCH] =?UTF-8?q?docs(6209):=20test=20prose=20in=20the=20present?= =?UTF-8?q?=20tense=20=E2=80=94=20"used=20to",=20"previously",=20"before?= =?UTF-8?q?=20this"=20restated=20as=20the=20failure=20shape?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Twenty-eight test files described the code they guard by what it did before a fix. Each is now the property and the failure it prevents, in the present tense: the backfill snapshot, the per-dial calibration query, the rule scope, the lesson trigger filter, the subshell global, the trash owner scope, the version readout fallback, and others. A docstring line that narrated the backup suite's own history is removed. Co-Authored-By: Claude Opus 5.5 --- tests/test_backfill_reads_current_text.py | 14 +++++----- tests/test_calibration_stamp.py | 4 +-- tests/test_chunking.py | 2 +- tests/test_create_tools_disambiguate.py | 8 +++--- tests/test_frontend_request_deadlines.py | 1 - .../test_integration_backup_note_roundtrip.py | 2 +- tests/test_integration_rule_scope.py | 6 ++--- tests/test_ledger_references_not_silence.py | 8 +++--- tests/test_lesson_insight_round_trip.py | 16 +++++------ tests/test_mcp_list_family.py | 9 +++---- tests/test_mcp_tool_projects.py | 6 ++--- tests/test_mcp_tool_search.py | 4 +-- tests/test_milestone_summary_brief.py | 2 +- tests/test_note_usage.py | 4 +-- tests/test_preference_write_path.py | 2 +- tests/test_reply_discipline.py | 4 +-- tests/test_retrieval_tuning.py | 5 ++-- tests/test_rule_usage_wiring.py | 6 ++--- tests/test_scribe_marker.py | 12 ++++----- tests/test_search_scope_shape.py | 12 ++++----- tests/test_services_backup.py | 27 ++++++++----------- tests/test_services_plugin_context.py | 11 ++++---- tests/test_services_retrieval_telemetry.py | 8 +++--- tests/test_services_snippets.py | 4 +-- tests/test_services_trash.py | 4 +-- tests/test_shared_write_access.py | 8 +++--- tests/test_version_readout.py | 8 +++--- tests/test_write_path_trigger.py | 4 +-- 28 files changed, 96 insertions(+), 105 deletions(-) diff --git a/tests/test_backfill_reads_current_text.py b/tests/test_backfill_reads_current_text.py index f1c4c7fb..3c747c36 100644 --- a/tests/test_backfill_reads_current_text.py +++ b/tests/test_backfill_reads_current_text.py @@ -1,12 +1,12 @@ """A backfill repairs to current truth; it does not replay a snapshot. -The bug these pin: every backfill used to SELECT the text alongside the id and -then iterate that snapshot, sleeping between records. A run over a real corpus -takes minutes, so anything edited inside that window was re-embedded by its own -write path and then OVERWRITTEN with the pre-edit text the scan had captured — -and stamped at the current chunker version, so the next boot considered it -current and never repaired it. The record stayed findable by what it used to -say, silently, until someone happened to edit it again. +The failure these pin: a backfill that SELECTs the text alongside the id and +then iterates that snapshot, sleeping between records. A run over a real corpus +takes minutes, so anything edited inside that window is re-embedded by its own +write path and then OVERWRITTEN with the pre-edit text the scan captured — and +stamped at the current chunker version, so the next boot considers it current +and never repairs it. The record stays findable by what it used to say, +silently, until someone happens to edit it again. That window is exactly "forward work continues while a long backfill runs", which is the normal condition, not an unlucky one. diff --git a/tests/test_calibration_stamp.py b/tests/test_calibration_stamp.py index e865df30..e0369ee4 100644 --- a/tests/test_calibration_stamp.py +++ b/tests/test_calibration_stamp.py @@ -195,8 +195,8 @@ async def test_a_dial_is_read_per_dial_not_from_the_newest_two_rows(): "The newest two rows" and "the newest row of each dial" differ the moment one dial moves more often than the other — which is the normal case, since - floors get walked and budgets rarely do. Before this was one query per dial, - a surface with three floor changes and one budget change reported the budget + floors get walked and budgets rarely do. Without a query per dial, a + surface with three floor changes and one budget change reports the budget as untouched: a WRONG calibration answer rather than a missing one, and wrong in the direction a reader would not think to check. """ diff --git a/tests/test_chunking.py b/tests/test_chunking.py index 650b28a1..d63235d3 100644 --- a/tests/test_chunking.py +++ b/tests/test_chunking.py @@ -171,7 +171,7 @@ def _assert_nothing_thin_and_nothing_lost(title: str, body: str) -> list[str]: def test_a_heading_over_one_long_paragraph_is_not_a_chunk_of_its_own(): - """A work log whose entry is one long paragraph: the split used to flush + """A work log whose entry is one long paragraph: the split must not flush the heading as its own piece before cutting the paragraph.""" entry = " ".join(["The deploy was verified against the live instance."] * 40) _assert_nothing_thin_and_nothing_lost( diff --git a/tests/test_create_tools_disambiguate.py b/tests/test_create_tools_disambiguate.py index 48fe9563..58a9fd31 100644 --- a/tests/test_create_tools_disambiguate.py +++ b/tests/test_create_tools_disambiguate.py @@ -8,10 +8,10 @@ choice is the only moment a correction is cheap. The tool docstring IS the agent-facing contract (product guidance lives there and nowhere else), so a docstring that only documents parameters answers "how do I call this" while leaving "should I be calling this at all" unasked. -The gap was lopsided before this: `create_rule` and `start_planning` both -carried a real disambiguator, and `create_note` — far and away the -highest-volume surface — carried none. Guidance sat in the rarest tool and -was missing from the most common one. +The gap tends to be lopsided: `create_rule` and `start_planning` are where a +disambiguator gets written first, while `create_note` — far and away the +highest-volume surface — is where it matters most. Guidance that sits only in +the rarest tools misses the most common one. WHAT THIS PINS, AND WHAT IT DOES NOT diff --git a/tests/test_frontend_request_deadlines.py b/tests/test_frontend_request_deadlines.py index 90ec31ab..87200075 100644 --- a/tests/test_frontend_request_deadlines.py +++ b/tests/test_frontend_request_deadlines.py @@ -14,7 +14,6 @@ resolves is indistinguishable from work still in progress. The practice names clients, a bare `await` on a stream — supplying the deadline is part of using it, not a hardening pass for later. -Before this guard, no request in the app carried one. """ from __future__ import annotations diff --git a/tests/test_integration_backup_note_roundtrip.py b/tests/test_integration_backup_note_roundtrip.py index 7af665f7..acb5ca8c 100644 --- a/tests/test_integration_backup_note_roundtrip.py +++ b/tests/test_integration_backup_note_roundtrip.py @@ -29,7 +29,7 @@ RESTORED_USERNAME = "backup_roundtrip_restored" @pytest_asyncio.fixture async def source(): """A snippet, a process, and an issue that arose from a work task — the - shapes whose identity the backup used to drop — exported as backup rows. + shapes whose identity a backup can drop — exported as backup rows. Deleted children-first: `arose_from_id` is a real FK, so removing the origin while the issue still points at it is asking the database a diff --git a/tests/test_integration_rule_scope.py b/tests/test_integration_rule_scope.py index 68e8571e..22618ab5 100644 --- a/tests/test_integration_rule_scope.py +++ b/tests/test_integration_rule_scope.py @@ -1,8 +1,8 @@ """Real-Postgres tests for WHERE a rule reaches. -A rule lives in a rulebook topic (global) or on one project. Retrieval used to -ignore that and search every rule the user owned, so each project's rules were -injected into every other project's sessions. What a mock cannot show is the +A rule lives in a rulebook topic (global) or on one project. Retrieval that +ignores the home and searches every rule the user owns injects each project's +rules into every other project's sessions. What a mock cannot show is the join doing the scoping: these seed real rules with hand-made vectors and stub only the embedder, so every rule is an equally good match and the home alone decides what comes back. diff --git a/tests/test_ledger_references_not_silence.py b/tests/test_ledger_references_not_silence.py index 610f1439..b5780b9f 100644 --- a/tests/test_ledger_references_not_silence.py +++ b/tests/test_ledger_references_not_silence.py @@ -121,11 +121,11 @@ async def test_the_repeat_is_counted_not_reported_as_a_result(): @pytest.mark.asyncio async def test_a_call_where_everything_was_already_seen_is_readable(): - """The fact that could not be expressed before. + """A call where every hit was already seen is not a call nothing cleared. - Previously this call logged zero results with no suppression count, so it - was indistinguishable from a bar nothing cleared — and the operator tuning - that bar would have been reading the wrong number. + Logged as zero results with no suppression count, it would be + indistinguishable from a bar nothing cleared — and the operator tuning + that bar would be reading the wrong number. """ rec = MagicMock() hits = [(0.80, fake_note(id=11, title="Pool sizing decision", user_id=1))] diff --git a/tests/test_lesson_insight_round_trip.py b/tests/test_lesson_insight_round_trip.py index 3487d504..f8bc2d64 100644 --- a/tests/test_lesson_insight_round_trip.py +++ b/tests/test_lesson_insight_round_trip.py @@ -15,13 +15,13 @@ worth having wherever a record is stored composed and edited in parts: not "does the strip remove the marker" — it did — but "does an edit that changes nothing change nothing". -WHAT WENT WRONG. The derivation used to filter out body LINES matching the -trigger marker's pattern, which is `re.M` and therefore matches one line. -`when_to_apply` is free text and is routinely several paragraphs; the -composer writes all of it after the marker, so paragraphs 2..n were ordinary -lines that the filter had no reason to touch. They came back as "the -insight", the full trigger was prepended again, and the stored lesson gained -(n-1) paragraphs per update — silently, compounding, and in the half of the +WHAT GOES WRONG. A derivation that filters out body LINES matching the +trigger marker's pattern, which is `re.M` and therefore matches one line, +leaves the rest of the trigger behind. `when_to_apply` is free text and is +routinely several paragraphs; the composer writes all of it after the marker, +so paragraphs 2..n are ordinary lines that the filter has no reason to touch. +They come back as "the insight", the full trigger is prepended again, and the +stored lesson gains (n-1) paragraphs per update — silently, compounding, and in the half of the document that does the retrieving. On a three-paragraph trigger the body grows by the length of paragraphs 2 and @@ -180,7 +180,7 @@ def test_the_insight_is_derived_from_the_row_not_from_the_body_alone(): """Why the function takes a note. The body on its own does not say where the trigger ends — that is the - information the old shape did not have and guessed at. The mirror in + information a line-wise filter does not have and guesses at. The mirror in `data` is where it comes from, so a caller holding only the body string cannot be served, and this pins that the argument is the record.""" note = _stored(MANY_PARAGRAPHS, INSIGHT, []) diff --git a/tests/test_mcp_list_family.py b/tests/test_mcp_list_family.py index 29b80218..35be9938 100644 --- a/tests/test_mcp_list_family.py +++ b/tests/test_mcp_list_family.py @@ -16,11 +16,10 @@ a real promise rather than a shape coincidence. THE CONTRACT: a `limit` without an `offset` is a truncation with no continuation. The caller is told there are 250 results and handed 50, with no -way to ask for the rest. Both tools that had this were capped over a service -that already accepted an offset — `snippets_svc.list_snippets(offset=0)` was -simply not exposed, and `list_processes` passed a hardcoded `offset=0` into -`query_knowledge`. The capability existed one layer down in both cases; only -the door was missing. +way to ask for the rest. The usual cause is a tool capped over a service that +already accepts an offset — the service's `offset` simply not exposed, or a +hardcoded `offset=0` passed into `query_knowledge`. The capability exists one +layer down; only the door is missing. As in `test_mcp_auth`, the CANDIDATES are derived and the DECISION is explicit. Deriving the exemption too would make the contract follow a naming convention, diff --git a/tests/test_mcp_tool_projects.py b/tests/test_mcp_tool_projects.py index 9f765240..d0e99714 100644 --- a/tests/test_mcp_tool_projects.py +++ b/tests/test_mcp_tool_projects.py @@ -363,9 +363,9 @@ async def test_enter_project_fires_the_coverage_seed_on_the_owner( @pytest.mark.asyncio async def test_enter_project_hands_back_the_design_system_when_the_project_has_one(): """The handshake is where an agent learns what binds it, and a design - system binds the same way a rule does. Before this it was reachable only by - an agent that already knew to call resolve_design_system — so the standards - were present in the store and absent from the work.""" + system binds the same way a rule does. Reachable only by an agent that + already knows to call resolve_design_system, the standards would be present + in the store and absent from the work.""" p = fake_project(id=5, design_system_id=9) design = {"id": 9, "title": "App kit", "guidance": [{"title": "House"}], "token_count": 95, "token_groups": ["surface"], diff --git a/tests/test_mcp_tool_search.py b/tests/test_mcp_tool_search.py index 004f7967..ecd1aa2b 100644 --- a/tests/test_mcp_tool_search.py +++ b/tests/test_mcp_tool_search.py @@ -168,8 +168,8 @@ async def test_fable_search_content_type_filters_at_service_layer(): async def test_each_specific_kind_reaches_the_engine_filter_it_names( content_type, expected ): - """`note_type` and `task_kind` were parameters of the search all along — - what was missing was a way to ask for them from the agent's door. Asking + """`note_type` and `task_kind` are parameters of the search, and the + agent's door passes them through. Asking for a snippet must narrow to snippets, not merely to non-tasks.""" _user_id_ctx.set(7) mock_search = AsyncMock(return_value=[]) diff --git a/tests/test_milestone_summary_brief.py b/tests/test_milestone_summary_brief.py index 5ae28ece..68529c1b 100644 --- a/tests/test_milestone_summary_brief.py +++ b/tests/test_milestone_summary_brief.py @@ -134,7 +134,7 @@ async def _enter(*stubs): async def test_enter_project_stays_small_however_large_the_project(): """The ceiling is the point: a long-lived project's handshake must not grow with its history. 200 milestones with 5k-character plans, 60 project - rules and 40 Systems would be well over 1M characters in the old shape.""" + rules and 40 Systems would be well over 1M characters carried whole.""" project = fake_project(id=5, design_system_id=9, goal=GOAL, description="Background. " * 300) rules = { diff --git a/tests/test_note_usage.py b/tests/test_note_usage.py index 777a050e..cf41cdeb 100644 --- a/tests/test_note_usage.py +++ b/tests/test_note_usage.py @@ -2,8 +2,8 @@ Covers the payload shaping and the two contracts that make this safe to leave in the hot path: telemetry never raises, and telemetry never blocks. Plus the thing -the feature exists for — that the write-path PLACE arm is now recorded, since -before this it surfaced snippets while leaving no trace anywhere. +the feature exists for — that the write-path PLACE arm is recorded, so a +snippet it surfaces leaves a trace. """ from unittest.mock import AsyncMock, MagicMock, patch diff --git a/tests/test_preference_write_path.py b/tests/test_preference_write_path.py index 762c48de..ae8dfb5e 100644 --- a/tests/test_preference_write_path.py +++ b/tests/test_preference_write_path.py @@ -160,7 +160,7 @@ async def test_update_preference_forwards_what_taught_the_change(): def test_the_rule_door_still_asks_before_writing(): """Half one of the asymmetry. If this fails, the gate was tidied away and - preferences are no longer the exception — they are just the same thing. + preferences are not the exception — they are just the same thing. """ doc = _doc(MODULE, "create_rule").lower() asks = ("approve", "propose", "ask", "question") diff --git a/tests/test_reply_discipline.py b/tests/test_reply_discipline.py index 97957800..a6d9baec 100644 --- a/tests/test_reply_discipline.py +++ b/tests/test_reply_discipline.py @@ -70,8 +70,8 @@ def test_the_reply_carries_a_length_discipline(): def test_the_reply_gets_a_second_pass_for_what_can_go(): """Cutting is a separate act from writing, and needs saying separately. - The pre-existing check asked whether anything was MISSING, which a bloated - reply passes. + A check that asks only whether anything is MISSING is one a bloated reply + passes. """ text = _flat() assert "what can go" in text diff --git a/tests/test_retrieval_tuning.py b/tests/test_retrieval_tuning.py index 50c37113..89fe9437 100644 --- a/tests/test_retrieval_tuning.py +++ b/tests/test_retrieval_tuning.py @@ -134,9 +134,8 @@ async def test_an_unknown_surface_is_refused_before_anything_is_written(): @pytest.mark.asyncio @pytest.mark.parametrize("dial", ["threshold", "limit", "", "FLOOR"]) async def test_an_unknown_dial_is_refused(dial): - """The near-misses are the old vocabulary — `threshold` and `limit` are what - these were called before this step, so they are exactly what a stale caller - will send, and a silent no-op there would be indistinguishable from a + """The near-misses are the generic vocabulary — `threshold` and `limit` are + what a caller that has not read the dial names will send, and a silent no-op there would be indistinguishable from a change that did not take.""" session, ctx = _patches() with ctx[0], ctx[1], ctx[2], ctx[3], pytest.raises(ValueError): diff --git a/tests/test_rule_usage_wiring.py b/tests/test_rule_usage_wiring.py index 4460b456..82c5210a 100644 --- a/tests/test_rule_usage_wiring.py +++ b/tests/test_rule_usage_wiring.py @@ -446,9 +446,9 @@ async def test_the_prompt_arm_retrieves_against_what_the_operator_SAID(): Both other arms are keyed on an act — a file write, a command. A rule that governs what to SAY has no act in front of it: extract intent from loose phrasing, raise a conflict before acting, end a finding with an offer all - bind on a response. Before this, the operator's message reached only - `semantic_search_notes`, so no rule had ever been retrieved against a - thing the operator actually said. + bind on a response. If the operator's message reached only + `semantic_search_notes`, no rule would ever be retrieved against a thing + the operator actually said. """ rec = MagicMock() search = AsyncMock(return_value=[(0.79, fake_rule( diff --git a/tests/test_scribe_marker.py b/tests/test_scribe_marker.py index 23378293..030a6c8e 100644 --- a/tests/test_scribe_marker.py +++ b/tests/test_scribe_marker.py @@ -119,13 +119,13 @@ def test_an_unusable_marker_is_refused_rather_than_sent(tmp_path, body): def test_the_reason_survives_the_command_substitution_that_fetches_it(tmp_path): - """Regression on a bug this nearly shipped with. + """The reason cannot be a global the function sets. - The reason used to be a global the function set, which every caller reads - through `$( )` — a subshell, so the assignment died with it and the caller - saw an UNSET variable. The hooks all run `set -u`, where reading one aborts - the script: a directory with a misaddressed marker would have cost the - session its entire SessionStart context, to fetch a warning about a file. + Every caller reads the function through `$( )` — a subshell, so a global + assignment dies with it and the caller sees an UNSET variable. The hooks all + run `set -u`, where reading one aborts the script: a directory with a + misaddressed marker would cost the session its entire SessionStart context, + to fetch a warning about a file. So the reason comes back through stdout with the id, and this asserts on the shape the caller actually uses: read in a subshell, split, and used diff --git a/tests/test_search_scope_shape.py b/tests/test_search_scope_shape.py index c8a81f10..00414299 100644 --- a/tests/test_search_scope_shape.py +++ b/tests/test_search_scope_shape.py @@ -3,13 +3,13 @@ Ordered straight off a `*_embeddings` table, the planner walks the HNSW index: it takes ~`hnsw.ef_search` (40) nearest chunks from every owner and project and filters them afterwards, so an in-scope record behind 40 nearer ones the -caller cannot see is silently dropped. The fix is one shape, `_rank_scoped`, -and these pin that every search goes through it — the rule search was fixed -alone first, and the other three kept the fault because nothing said they -were the same query. +caller cannot see is silently dropped. The remedy is one shape, `_rank_scoped`, +and these pin that every search goes through it — fixed in one search alone, +the others keep the fault, because nothing says they are the same query. The integration lane's crowd tests show the behaviour on a real index; these -are the guard that fails on the old shape whatever plan Postgres picks. +are the guard that fails on a rank-then-scope query whatever plan Postgres +picks. """ from __future__ import annotations @@ -54,7 +54,7 @@ def test_every_semantic_search_ranks_through_the_scoped_shape(): calls = _calls(fn) assert "_rank_scoped" in calls, f"{name} does not rank through _rank_scoped" assert "_scoped_chunks" in calls, f"{name} does not build its scope as chunks" - # Its own ORDER BY is the old shape: a distance ordered on the + # Its own ORDER BY is the rank-then-scope shape: a distance ordered on the # embedding table, which the index serves before the scope applies. assert "order_by" not in calls, f"{name} orders by distance itself" diff --git a/tests/test_services_backup.py b/tests/test_services_backup.py index 2ee25d5a..94bed647 100644 --- a/tests/test_services_backup.py +++ b/tests/test_services_backup.py @@ -7,9 +7,7 @@ need only a stand-in and a builder. The full FK-remapping round-trip needs real Postgres and lives in the `test_integration_backup_*_roundtrip.py` modules, which drive the real -`restore_full_backup`. That sentence used to read "it is not written yet"; -four of those files exist now, the newest covering the three `code_shapes` -columns the import guard below found missing. +`restore_full_backup`. """ from datetime import datetime, timezone from types import SimpleNamespace @@ -268,18 +266,16 @@ def test_every_column_is_exported_or_declared_excluded(table): """THE COLUMN GUARD — _NOT_INCLUDED's shape, one level down. The table guard below catches a whole table going missing. It cannot catch - a COLUMN going missing from a table it already considers covered, which is - how nine of them vanished from `notes` alone: note_type and task_kind, so - every snippet and process restored as a plain note and every issue and - spike as `work`; arose_from_id, so every provenance edge went; the - recurrence pair, so recurring tasks stopped recurring. Plus milestones.body - — which IS the plan — and repo_bindings.ref. + a COLUMN going missing from a table it already considers covered, and the + cost is large: without note_type and task_kind every snippet and process + restores as a plain note and every issue and spike as `work`; without + arose_from_id every provenance edge goes; without the recurrence pair + recurring tasks stop recurring. - Each arrived the same way: added to the model and the migration, both of - which fail loudly, and never to the serialiser, which fails silently. - - A new column must now be exported or named in _COLUMN_EXCLUSIONS with a - reason. Forgetting is no longer expressible. + A column arrives in the model and the migration, both of which fail loudly, + and is easy to leave out of the serialiser, which fails silently. So a new + column must be exported or named in _COLUMN_EXCLUSIONS with a reason, and + forgetting is not expressible. """ model, helper = _column_guard_targets()[table] [row] = helper([_stand_in(model)]) @@ -536,8 +532,7 @@ def test_every_table_is_either_backed_up_or_explicitly_excluded(): ) # And the reverse: a name in either list that no longer exists is a lie the - # guard would otherwise keep telling. This half is what caught "embeddings", - # "invitations" and "password_resets" — three entries that named nothing. + # guard would otherwise keep telling. phantom = accounted - schema assert not phantom, ( f"backup lists table(s) that are not in the schema: {sorted(phantom)}. " diff --git a/tests/test_services_plugin_context.py b/tests/test_services_plugin_context.py index 943e437e..878f391d 100644 --- a/tests/test_services_plugin_context.py +++ b/tests/test_services_plugin_context.py @@ -86,9 +86,8 @@ async def test_build_autoinject_hint_titles_only_with_margin_gate(): assert "get_note(id)" in out["context"] assert "↳" not in out["context"] # Telemetry fired for BOTH retrievals this path runs: the scored menu and - # the reuse-slot query competing against it. The slot's query used to be - # the one unlogged retrieval on this path — the hit it displaced was in - # retrieval_logs, and the query that displaced it must be too. + # the reuse-slot query competing against it. The hit the slot displaces is + # in retrieval_logs, so the query that displaced it must be too. sources = [c.kwargs["source"] for c in rec.call_args_list] assert sources == ["auto_inject", "reuse_slot", "lesson_slot"] @@ -235,9 +234,9 @@ async def test_a_project_id_that_does_not_resolve_is_reported_not_dropped(): another instance, or names a deleted project, the session has to be told — it cannot infer it from an absence. - This used to render nothing whatsoever: the branch hung off `if project_id` - as an `elif`, so an id that was sent and failed took the outer arm, found - no project, and fell out of the block having said nothing at all. + The trap is a branch hung off `if project_id` as an `elif`: an id that was + sent and failed takes the outer arm, finds no project, and falls out of the + block having said nothing at all. """ from scribe.services.plugin_context import build_session_context with patch("scribe.services.plugin_context.projects_svc.get_project", diff --git a/tests/test_services_retrieval_telemetry.py b/tests/test_services_retrieval_telemetry.py index dffd70c3..90db6961 100644 --- a/tests/test_services_retrieval_telemetry.py +++ b/tests/test_services_retrieval_telemetry.py @@ -929,10 +929,10 @@ async def test_a_section_is_complete_only_from_its_latest_contributor( def test_a_call_that_returned_nothing_still_records_what_it_nearly_showed(): """The whole point, at the payload grain. - This is the row a threshold is tuned from and the one that used to carry no - score at all: `top_score` and `min_score` are both null here, correctly, and - a reader was left unable to tell a bar rejecting 0.71s from one rejecting - 0.30s. Both render as a zero-result call. + This is the row a threshold is tuned from: `top_score` and `min_score` are + both null here, correctly, and without the near-miss a reader cannot tell a + bar rejecting 0.71s from one rejecting 0.30s. Both render as a zero-result + call. """ p = _build_payload( user_id=1, source="pre_tool_rule", query="git push --force", diff --git a/tests/test_services_snippets.py b/tests/test_services_snippets.py index aedff9d6..2f618f80 100644 --- a/tests/test_services_snippets.py +++ b/tests/test_services_snippets.py @@ -82,8 +82,8 @@ def test_parse_does_not_promote_a_caller_tag_to_language(): def test_caller_tag_survives_an_update_round_trip_without_a_language(): - # Regression: the tag used to be read back as the language, then dropped - # from the extra-tag set on re-compose — so it silently disappeared. + # A tag read back as the language would be dropped from the extra-tag set + # on re-compose — and silently disappear. tags = s.compose_tags("", ["auth"]) fields = s.parse_snippet_fields("n — u", s.compose_body(code="x = 1"), tags) extra = [t for t in tags if t not in (s.SNIPPET_TAG, fields["language"])] diff --git a/tests/test_services_trash.py b/tests/test_services_trash.py index 45f756c3..cddff525 100644 --- a/tests/test_services_trash.py +++ b/tests/test_services_trash.py @@ -124,8 +124,8 @@ async def test_purge_expired_deletes_across_models_when_positive(): def test_owner_clause_scopes_every_model(): - """Regression: every trash op must owner-scope, including topics/rules - which previously had NO owner check (IDOR across tenants).""" + """Every trash op must owner-scope, topics and rules included — a model + with no owner check is an IDOR across tenants.""" from scribe.services.trash import _owner_clause, _MODEL_FOR from scribe.models.note import Note from scribe.models.rulebook import Rulebook, RulebookTopic, Rule diff --git a/tests/test_shared_write_access.py b/tests/test_shared_write_access.py index e587d0aa..a10adb7b 100644 --- a/tests/test_shared_write_access.py +++ b/tests/test_shared_write_access.py @@ -1,9 +1,9 @@ """Editing a shared record: an editor grant is enough, a viewer grant is not. -The agent and web paths used to disagree — and worse, within the agent path -`delete_snippet` honoured editor shares while `update_snippet` did not, so a -colleague's snippet could be destroyed through an agent but not improved. Both -now resolve the read scope and then require WRITE, which is what the sharing UI +The agent and web paths must agree, and so must the doors within one path: a +`delete_snippet` that honours editor shares beside an `update_snippet` that +does not lets a colleague's snippet be destroyed through an agent but not +improved. Every door resolves the read scope and then requires WRITE, which is what the sharing UI already promises: viewer / editor / admin are distinct grants. A record readable-but-not-writable raises PermissionError rather than reporting diff --git a/tests/test_version_readout.py b/tests/test_version_readout.py index 84104f52..f9548b32 100644 --- a/tests/test_version_readout.py +++ b/tests/test_version_readout.py @@ -33,11 +33,11 @@ def test_something_actually_reads_the_version_endpoint(): def test_the_footer_does_not_default_to_a_plausible_version(): - """The regression this readout was built to remove. + """A failed fetch does not render a plausible version. - `appVersion` used to start life as the literal `"dev"` and the fetch - swallowed its own failure, so an instance that could not answer rendered - exactly what a healthy local build renders. Two very different states, one + If `appVersion` starts life as the literal `"dev"` and the fetch swallows + its own failure, an instance that cannot answer renders exactly what a + healthy local build renders. Two very different states, one string, and no way to tell them apart from the page. Pinned as "the ref does not start at a version-shaped literal" rather than diff --git a/tests/test_write_path_trigger.py b/tests/test_write_path_trigger.py index 8c752c4c..0350cc5b 100644 --- a/tests/test_write_path_trigger.py +++ b/tests/test_write_path_trigger.py @@ -1342,10 +1342,10 @@ async def test_a_pulled_snippet_already_seen_is_evidence_not_menu(): # ...and the menu carries it, marked. seven = next(line for line in out["context"].splitlines() if "#7" in line) assert "seen" in seven - # #8 (0.80) now falls OUTSIDE the margin band, because #7 (0.91) anchors it + # #8 (0.80) falls OUTSIDE the margin band, because #7 (0.91) anchors it # at 0.81 instead of being filtered out first. That is the point rather than # a casualty: the band measures distance from the best answer, and the best - # answer here is #7 — suppressing it used to promote a materially weaker hit + # answer here is #7 — suppressing it would promote a materially weaker hit # into a slot it had not earned, with nothing in the output saying so. assert out["note_ids"] == [7] # The stamp saw the pull and the resemblance score for this payload.