Repository navigation
docs(cli): collect create-sg-rule's authoring traps into one Quirks section - #488
Merged
Merged
Conversation
…ection
The recipe had its traps in four places: the `language:` traps and the
Markdown note in step 4, the separator trap as step 5, and "Two ways a
relational rule matches nothing" after the steps. An agent whose rule matches
less than it should had no one place to look.
They now live under one Quirks section. It opens with the two ways a quirk
fails (a config error that aborts the scan, or a silent zero) and a table of
every entry with its symptom. Each entry gives the symptom, a repro, and the
workaround. Step 5 becomes "check the rule against Quirks", so the check
keeps its place in the step order.
Two new entries, both measured against ast-grep 0.45.3:
- A keyword is not a valid `kind`. `--debug-query=cst` prints `readonly` as
a node, but `kind: readonly` exits 8 with "Kind `readonly` is invalid":
`kind:` takes named nodes only. `--debug-query=ast` prints named nodes
only, which is the reliable way to tell them apart.
- An awaited generic call hides its callee. `await rpc<Foo>("x")` parses as
a call of the await expression, so a callee-keyed rule silently skips it.
`!`, `void` and `typeof` do the same through `unary_expression`; `yield`
does not; Tsx matches TypeScript. The workaround's match spans the
`await`, so a `fix:` rewrites it too, measured.
The vendor contract pins both against the binary so a grammar bump that
fixes either goes red, and agent-extensions pins the recipe text.
Fixes #485
theCodeDrift
added a commit
that referenced
this pull request
Oct 12, 2026
A post-merge review of #488 found the recipe's own workarounds reintroduced the silent failures the section warns about. All measured on ast-grep 0.45.3. - The `readonly` workaround (`^readonly\b` on `required_parameter`) matched 1 of 4 real shapes. It missed `private readonly x` and a decorated parameter, whose text starts before the keyword, and `readonly x?`, which is an `optional_parameter`. The new regex covers all four and keeps out a `readonly` type and a parameter named `readonly`. - The awaited-call workaround and the repro both used a `regex` with no sibling `kind`, which `verify` refuses (`sg-regex-needs-kind`). Both now carry `kind: identifier`. The recipe also shows the method form: under `await`, `client.rpc<Foo>()` wraps a `member_expression`, and the identifier branch found 0 of 2. - Step 5 claimed every quirk "verifies clean", but `verify` does report the `language:` spelling and a TypeScript rule whose `files:` names `.tsx`. The table gains a column saying which quirks `verify` reports. The vendor contract now pins the claims it previously took on trust: Tsx parses awaited generics the same way, `!`/`void`/`typeof` wrap the callee in `unary_expression` and `yield` does not, and both workarounds match exactly what the recipe says. The header reads "measured at" rather than "added at", since a bump did not introduce these. `typescriptMatches` and `arityMatches` were the third copy of the same parse chain; both now go through `grammarMatches`. The topic moves to v7, because v6 already shipped in the nightly, and the pending changeset says so.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
create-sg-rulehad its authoring traps in four places (step 4'slanguage:and Markdown notes, step 5's separator trap, and "Two ways a relational rule matches nothing"). This pulls them into one Quirks section and adds the two tree-sitter traps from #485.Structure
language:list and points to Quirks for the spelling traps. Step 5 becomes "check the rule against Quirks", so the check keeps its place in the step order. Step 6 asks for an awaited generic call among theinvalid:cases when the rule keys on a callee.New entries (measured on ast-grep 0.45.3)
kind.kind: readonlyexits 8 withKind `readonly` is invalid.--debug-query=astprints named nodes only, so it shows which names are usable kinds; the CST dump does not distinguish them. Workaround: match the named parent (kind: required_parameter+regex: "^readonly\\b").await rpc<Foo>("x")parses ascall_expression(function: await_expression). Also true for!,voidandtypeof(viaunary_expression), and in Tsx;yieldis unaffected. Workaround: ananybranch onawait_expression. Measured: that match spans theawait, so afix:rewrites it too, and the recipe says so.Tests
ast-grep-vendor-contract.test.tspins both quirks and both workarounds against the binary, so a grammar bump that fixes either one fails the suite.agent-extensions.test.tspins that the recipe names them.Patch changeset:
.changeset/sg-rule-quirks.md.Fixes #485