WIP: docs and evidence for h3y7 forward guard, hkbc and c7mu
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
+30
-10
@@ -218,14 +218,33 @@ its verdict. The list is checked in **both** directions, so an entry that starts
|
||||
being composed fails just as loudly as one that stops
|
||||
(`doctrine(a_stale_list_of_what_is_missing_is_worse_than_no_list)`).
|
||||
|
||||
Two limits are worth stating, because the check is a source scan.
|
||||
`#[cfg(test)]` items are dropped by a line scan that relies on rustfmt putting
|
||||
an item's closing brace at the attribute's own indentation; over-stripping would
|
||||
**fail** the test rather than pass it, which is the safe direction. And a
|
||||
`Command::X` inside `matches!` or `if let` is read as a construction rather than
|
||||
a pattern, which can only make the check *weaker* for that variant — never raise
|
||||
a false alarm. A variant nothing composes at all is immune to both, since its
|
||||
only pattern occurrence is its own fold arm, which `=>` identifies.
|
||||
The check is a source scan, and **what counts as source has one home**:
|
||||
`improvise_protocol::source_scan::production_code`, shared with the forward
|
||||
guard below (improvise-c7mu). It removes three things a scan must not see.
|
||||
|
||||
- **Comments and literals.** Both are blanked, and newlines are kept. Before
|
||||
this, a `// TODO: Command::SetYanked(...)` left where the real composer had
|
||||
been deleted still passed all four tests. That is the *weaker* direction, the
|
||||
one a scan weakness was supposed to be unable to go. It was live in a small
|
||||
way: a `///` in `project.rs` named `Command::SwitchView`, which has real
|
||||
composers, so no verdict was wrong yet. It also had a mirror: a comment
|
||||
explaining that a `NOT_COMPOSED` variant is held back would have raised a
|
||||
false "stale entry" alarm.
|
||||
- **Test items inside a file.** A line scan that relies on rustfmt putting an
|
||||
item's closing brace at the attribute's own indentation. It treats
|
||||
`cfg(any(test, …))` as test code and `cfg(not(test))` as production.
|
||||
Over-stripping **fails** the test rather than passing it, which is the safe
|
||||
direction.
|
||||
- **Test-only files.** A `#[cfg(test)] mod x;` makes `x.rs` and everything under
|
||||
`x/` test code, even though nothing inside the file says so. Before
|
||||
improvise-c7mu, this checker's own file and `improvise-io`'s
|
||||
`roundtrip_tests.rs` were scanned as production.
|
||||
|
||||
One limit remains. A `Command::X` inside `matches!` or `if let` is read as a
|
||||
construction rather than a pattern. That can only make the check *weaker* for
|
||||
that variant; it never raises a false alarm. A variant nothing composes at all
|
||||
is immune, since its only pattern occurrence is its own fold arm, which `=>`
|
||||
identifies.
|
||||
|
||||
### And forwards: every effect is on the wire or has a verdict (improvise-h3y7)
|
||||
|
||||
@@ -254,8 +273,9 @@ kinds, and the check verifies each kind:
|
||||
improvise-2mqz).
|
||||
|
||||
The list is also checked in reverse. An entry that is now on the wire fails,
|
||||
and so does an entry that names no effect. A test-only fake effect is scanned
|
||||
on purpose. It fails loudly and never passes silently.
|
||||
and so does an entry that names no effect. The scan is `production_code`, so
|
||||
the comments, strings and test fakes that name an effect do not count as
|
||||
effects. If they did, a stale verdict could outlive the effect it names.
|
||||
|
||||
What it does **not** check is whether a same-named pair *agrees*: whether
|
||||
`reduce_view`'s arm does what the effect does. The name match is the
|
||||
|
||||
@@ -4903,3 +4903,27 @@ The control for the test above, and it is stated separately rather than folded
|
||||
in so that a change making the fixture's load stop rebasing fails *here*, where
|
||||
the message says what actually broke, rather than turning the rollback test
|
||||
green by emptying it.
|
||||
|
||||
### ui::reduce::vocabulary_is_complete::every_effect_is_on_the_wire_or_has_a_verdict
|
||||
|
||||
improvise-h3y7, the forward direction of the vocabulary derivation. It is the
|
||||
direction `ViewBack`/`ViewForward` failed: they were missing, so no client ever
|
||||
had a back history. The test scans this crate's production `src/` for
|
||||
`impl Effect for X` and `simple_effect!(X`. That covers both spellings, and the
|
||||
h3y7 audit's brace-matcher missed nine effects by seeing only the first. It
|
||||
then requires each name to be a `Command` or `ModelCommand` variant (read off
|
||||
serde's derive) or to carry a `NOT_ON_THE_WIRE` verdict.
|
||||
|
||||
Faults injected, together: `HelpPageNext`'s verdict replaced by one for
|
||||
`SetSelected`. This test failed naming `HelpPageNext`, and
|
||||
`the_verdict_list_names_nothing_that_is_on_the_wire` failed naming
|
||||
`SetSelected`. Separately, `HelpPageSet`'s verdict was pointed at
|
||||
`Command::HelpPag`, and
|
||||
`the_verdict_list_names_only_real_effects_and_real_variants` failed.
|
||||
|
||||
`the_scan_reaches_every_way_an_effect_is_declared` pins one effect of each
|
||||
spelling plus `SetTransientPrefix` (which lives in `command/keymap.rs`). A
|
||||
broken walk therefore fails that test instead of shrinking the set.
|
||||
`an_effect_named_only_in_a_comment_or_string_is_not_an_effect` shares
|
||||
improvise-c7mu's fault. With `code_only` made the identity, it failed with
|
||||
`["SaveAs", "ExportCsv", "Real", "SetYanked", "AlsoReal"]`.
|
||||
|
||||
@@ -969,3 +969,63 @@ That assertion is the discriminating one: a fold arm that removed the key would
|
||||
give `None` and fail. Asserting only that `"command"` survived would pass under
|
||||
either behaviour, which is what the old spelling amounted to for the cleared
|
||||
key.
|
||||
|
||||
### vocabulary_is_composed::a_variant_named_only_in_a_comment_or_string_is_not_composed
|
||||
|
||||
improvise-c7mu, found by the post-merge review of PR #160. `constructed_in` ran
|
||||
over raw source text, so any `Command::X` counted as a composer, including one
|
||||
inside a comment or a string. The review deleted the real `Command::SetYanked`
|
||||
composer from `resolve.rs`, left `// TODO: Command::SetYanked(value)` in its
|
||||
place, and all four tests passed. The test feeds the whole per-file pipeline a
|
||||
line comment, a block comment and a string that each name a variant, and
|
||||
asserts that none of them counts. A positive control asserts that a real
|
||||
construction still does.
|
||||
|
||||
Fault injected: `code_only` made the identity function. This test failed with
|
||||
`["SetYanked", "SetSearchMode", "ChangeMode"]`, and so did
|
||||
`source_scan::tests::comments_and_literals_are_blanked_and_code_is_kept`. The
|
||||
four whole-tree tests stayed green under that fault. This confirms the review's
|
||||
finding that no live comment gives a wrong verdict *today*, and it is the
|
||||
reason the property has to be pinned on a fixture rather than on the tree.
|
||||
|
||||
The fault on the real tree (deleting `resolve.rs`'s composer) was not rerun
|
||||
here. `resolve.rs` is outside this lane, and the edit was refused as another
|
||||
agent's ground.
|
||||
|
||||
### source_scan::tests::a_test_only_module_file_is_not_production_code
|
||||
|
||||
improvise-c7mu, the second half. `#[cfg(test)] mod x;` makes a whole file test
|
||||
code, and nothing inside the file says so. The old scan saw it as production,
|
||||
and that included this checker's own file. The test builds a fixture tree:
|
||||
`lib.rs` declares `mod p;` and `#[cfg(test)] mod t;`, and `t.rs` declares a
|
||||
nested `mod deeper;`. It asserts that `production_code` returns exactly
|
||||
`lib.rs` and `p.rs`.
|
||||
|
||||
Fault injected: the file filter in `production_code` made always-true. This
|
||||
test failed with `["lib.rs", "p.rs", "t.rs", "t/deeper.rs"]`. Before this
|
||||
fixture existed, the `improvise-protocol` and `improvise-command` lib suites
|
||||
**stayed green** under the same fault, and so did
|
||||
`test_only_items_and_modules_are_not_production`, which checks the helpers one
|
||||
by one. The wiring between them was untested until this fixture existed.
|
||||
|
||||
### reduce::tests::every_model_command_field_is_position_free
|
||||
|
||||
improvise-hkbc. improvise-6nsd's "a stale layout tier cannot misdirect a
|
||||
mutation" holds only while no `ModelCommand` carries a row or column. The guard
|
||||
is the signature of `position_free`. It destructures every variant with no `..`,
|
||||
down into `RecordCell`, and hands each field to a function that accepts only
|
||||
`&str`, a path, a `RecordHash`, a `CellValue`, an `Axis` or an optional name.
|
||||
The `#[test]` only keeps that signature compiled and reached.
|
||||
|
||||
Faults injected, one per half, each compiling only `improvise-protocol`:
|
||||
|
||||
- A new variant `ScrollTo { row: usize }`, also added to `records_named`'s
|
||||
or-pattern the way an author would. The lib built. The test build failed
|
||||
with `non-exhaustive patterns: ScrollTo` **at `position_free` and nowhere
|
||||
else**.
|
||||
- The same variant classified as `ScrollTo { row } => name(row)`. The test
|
||||
build failed with `expected &str, found &usize`.
|
||||
|
||||
A field added to an existing variant is caught too, but not in isolation,
|
||||
because every constructor of that variant also fails. Reverted with
|
||||
`git restore`.
|
||||
|
||||
Reference in New Issue
Block a user