commands-resolve: a verb a document names must be one the command dispatches on - #69
commands-resolve: a verb a document names must be one the command dispatches on#69HackingGate wants to merge 2 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (95.14%) is below the target coverage (100.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## owner-and-visibility-from #69 +/- ##
=============================================================
+ Coverage 90.02% 90.25% +0.23%
=============================================================
Files 34 35 +1
Lines 10496 11006 +510
=============================================================
+ Hits 9449 9934 +485
- Misses 1047 1072 +25 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
`links-resolve` resolves a path a reader would CLICK. `anchors-resolve` a value
a reader would BELIEVE. This one a command a reader would RUN, which is the last
of the three things a document asserts about a tree -- and before any of them
existed all three failed the same way: silently, forever, with every gate in
every repository still green.
The defect it was built from is measured rather than imagined. A README opened
with `fg-registry credentials` for as long as the file existed. That command has
two verbs and `credentials` was never one of them; the binary's own error names
the alternatives, so the answer was one invocation away. Nobody invoked it,
because a reader who trusts the README has no reason to and a reader who does
not is not reading the README.
WHY THE DISPATCH AND NOT `--help`. Running the binary needs a build, and a gate
that needs the network is a gate that gets skipped. Worse, it invites resolving
a verb by RUNNING it: `fg-registry sync` in a document would be verified by
fast-forwarding thirty-nine submodules. Only the help text is safe to execute
for, and help text is prose too -- a doc comment drifts from the switch below it
exactly as the README drifted. The switch IS the verb list.
WHY A GRAMMAR. The implementation this ports read dispatches with a regex over
lines and an allow-list of eight subject spellings taken off dispatches in one
workspace. Both halves of its measured false-finding rate come from that: a
tagless `switch {` is a line the matcher cannot read, and a subject list read
off one tree describes one tree. tree-sitter was already in this binary for the
comment checks, so Go is one grammar crate and Rust is already here. A dispatch
is now recognised structurally -- it dispatches on something, two or more
branches match string literals, a catch-all exists -- and each of those three
conditions is a false finding the line matcher produced.
WHY A COMMAND MUST AGREE WITH ITSELF FIRST. A verb list read wrong is worse than
no verb list: it produces confident findings against documents that were right.
The first run of the ported implementation reported 38 findings and one binary
supplied 22 of them, every one false and every one reading as real. So a command
judges documents only when two readings of its own sources agree -- the string
labels of its dispatch, and the verbs its own usage block names about itself --
and when they disagree it is counted, named and skipped. The count is printed
every run, because a check that read four commands out of a hundred otherwise
reads exactly like one that read them all. Zero judged is exit 1 rather than a
pass, for the same reason.
WHY A PATTERN AND NOT A TABLE. `command_sources = ["cmd/{}/*.go"]` says what a
command looks like in this tree and captures the name out of the path. A list of
command names would be a second copy of the tree, free to go stale, which is the
class of defect this rule refuses in documents. The capture also bounds the
union: a command's verbs come from the files its own pattern selected, so a
sibling binary in the same repository cannot lend it verbs -- a repository-wide
widening in the original resolved a flag-only command to its neighbour's verbs,
and a document naming one of them would have passed.
NO BUNDLED SET SHIPS IT. The rule needs a pattern describing one tree's layout,
and a rule arriving from a set cannot be handed a parameter. A set carrying a
layout would either impose one workspace's convention on every inheriting
repository or ship a rule that refuses to run.
Two limits are stated in the reference and asserted by a test rather than left
to be found: a flag taking a separate value hides the verb behind it, and a
binary whose name lives in a manifest rather than in its path is not
discoverable by a path pattern.
Closes #55.
…n sentences
Two defects, both found by pointing the rule at a real workspace of nineteen
commands rather than at its own fixtures.
A TAGLESS SWITCH IS NOT AUTOMATICALLY A CHAIN OF BOOLEANS. "Dispatches on
something" was never the property worth testing. Go spells a dispatch that also
guards its own argument count as `switch { case len(args) > 0 && args[0] ==
"serve": }`, and refusing to read it left a real command judged against a
SUB-dispatch found in another file of the same package -- the `record|last` of
one of its own verbs -- which produced three confident findings against a README
that was right. That is the exact failure this rule exists to prevent, arriving
through the guard against it.
The condition is now: every branch names a literal. A tagless switch whose arms
are `ready()` and `waiting()` still contributes nothing, which is the case the
guard was written for.
A SENTENCE THAT BEGINS WITH THE COMMAND'S NAME IS NOT A USAGE CLAIM. The two
readings fail in opposite directions: a false document finding accuses a file
that was right, while a false USAGE verb costs coverage in silence -- the
readings disagree and the command then judges nothing at all. A command called
`session` collected `for` and `in` out of three ordinary comments ("session in
an already-running browser", "session for the ref"), disagreed with its own
dispatch over words that are not verbs, and skipped itself out of every document
in its repository. Any command whose name is also an English word has that
waiting for it.
So the usage reading now takes only lines whose remainder still reads as an
invocation: a flag, a placeholder, an alternation, or nothing. Applied to the
usage half and deliberately not to the documents, where narrowing would drop
real findings.
df70576 to
1535c9e
Compare
Closes #55. Stacked on #68 -- base retargets to
mainwhen that merges.What it is
The third resolver.
links-resolveresolves a path a reader would CLICK,anchors-resolvea value a reader would BELIEVE, this a command a reader wouldRUN.
The three decisions
A grammar, not a line matcher. The implementation this ports used a regex
over lines plus an allow-list of eight subject spellings read off one
workspace's dispatches, and both halves of its measured false-finding rate come
from that. tree-sitter was already in this binary for the comment checks, so Go
is one new grammar crate and Rust was already here. A dispatch is now recognised
structurally, and each condition is a false finding the line matcher produced:
switch {-- 22 of the original's 38 first-run findingsA command agrees with itself before it judges anyone. Two readings of its own
sources -- the string labels of its dispatch, and the verbs its own usage block
names about itself -- must agree, or the command is counted, named and skipped.
The count prints every run, and zero judged is exit 1 rather than a pass.
A pattern, not a table.
{}is captured out of the path, so the conventionstays in the repository that has one. It also bounds the union: a sibling binary
in the same repository cannot lend a command its verbs.
Not shipped in a bundled set
The rule needs a
command_sourcespattern describing one tree's layout, and arule arriving from a set cannot be handed a parameter. A set carrying a layout
would either impose one workspace's convention on every inheriting repository or
ship a rule that refuses to run.
Limits, asserted rather than left to be found
fg-registry --workspace here syncreadshere.--flag=valuepassesthrough. Nothing in the text tells a flag's value from a verb; only the
command's own flag table does, and reading that is a second parse with a
second way to be wrong.
discoverable by a path pattern.
src/bin/{}.rsworks; a single-binary cratenamed in
Cargo.tomloversrc/main.rsdoes not.Tests
8 unit cases in
src/commands.rs, 9 CLI cases intests/scan_cli.rs.cargo deny checkis clean with the new grammar crate.