@@ -26,9 +26,10 @@ and must not contain `/`; directory ownership is encoded by file location.
2626
2727Each YAML file must contain exactly one document, and that document must be a
2828mapping. A complete rule file requires string ` id ` and ` description ` fields,
29- rejects unknown top-level keys, and uses exactly one of these top-level modes:
29+ rejects unknown top-level keys, and chooses one of these rule modes:
3030
31- - ` patterns ` : structural expression matching
31+ - structural: non-empty ` patterns ` , or ` inside-expr ` with ` patterns ` ,
32+ ` patterns-not ` , or both
3233- ` taint ` : intraprocedural taint modeling compiled to the ` taint ` package
3334
3435` patterns ` must be a non-empty array when present. Structural rules may also
@@ -168,9 +169,8 @@ patterns:
168169 - shape: $(expr:exp) == $(expr:exp)
169170` ` `
170171
171- Use `$(name:id)` when the same source-level name must be consistent across
172- binders, identifier expressions, pattern variables, labels, or simple variable
173- targets :
172+ Use `$(name:id)` when the same source-level name must remain consistent between
173+ its definition and use sites :
174174
175175` ` ` yaml
176176patterns:
@@ -218,7 +218,7 @@ patterns:
218218 - shape: $(expr:exp) == $(expr:exp)
219219` ` `
220220
221- This is a good fit for supported repeated expression shapes such as :
221+ This is a good fit for whole- expression comparisons such as :
222222
223223- ` x == x`
224224- ` user.profile.name == user.profile.name`
@@ -283,14 +283,14 @@ Rules for `inside-expr`:
283283- it must place exactly one supported `__TARGET__`; place it where a whole
284284 expression is expected so runtime traversal can search that subtree
285285- ` __TARGET__` is reserved and must not be used as an inline metavar name
286- - inner `patterns` must not contain `__TARGET__`; the target placeholder
287- selects the subtree to search, but it is not a binding available to inner
288- shapes
286+ - inner `patterns` and `patterns-not` must not contain `__TARGET__`; the target
287+ placeholder selects the subtree to search, but it is not a binding available
288+ to inner shapes
289289- inherited `id` captures observe lexical shadowing inside the searched target
290290 subtree
291- - inner `patterns` reference outer captures by repeating the same inline
292- metavar form, such as `$(prefix:exp)`; using the same name with a different
293- kind is rejected
291+ - inner `patterns` and `patterns-not` reference outer captures by repeating the
292+ same inline metavar form, such as `$(prefix:exp)`; using the same name with a
293+ different kind is rejected
294294
295295# ## 3.6 Use `patterns-not` to prune blocked branches
296296
@@ -438,7 +438,7 @@ patterns:
438438Why it works:
439439
440440- ` counter` is compared by normalized identifier name, not by raw AST equality
441- - ` start` , `limit`, and `body` are expression captures stored as parser AST nodes
441+ - ` start` , `limit`, and `body` are expression captures stored as untyped AST nodes
442442
443443# ## Same rule, multiple shapes
444444
@@ -483,9 +483,9 @@ exact supported normalization cases in [RuleSpec.md](RuleSpec.md).
483483
484484# ## A rule with `guard` fails to load
485485
486- Check that `guard` is under a structural `patterns` entry, that it is a
487- mapping, and that every key names an `id` or `const` capture visible to that
488- pattern. `guard` is still rejected in taint clauses.
486+ Check that `guard` is under a structural `patterns` or `patterns-not` entry,
487+ that it is a mapping, and that every key names an `id` or `const` capture
488+ visible to that pattern. `guard` is still rejected in taint clauses.
489489
490490# # Testing Workflow
491491
0 commit comments