Is your feature request related to a problem? Please describe.
codeanalyzer/entrypoints/rules.py accepts exactly one matcher kind under heuristics: — decorators — and rejects unknown keys by design (_TOP_LEVEL_KEYS, and the comment at rules.py:22: blocks not implemented are "deliberately absent here rather than accepted-and-ignored, so a user file using them fails loudly instead of loading clean and doing nothing").
codeanalyzer-typescript is adding a second matcher kind to the same block, heuristics.calls, because its ecosystem declares entrypoints by call as often as by decorator — Express, Koa and Fastify are app.get('/p', handler), not @Get('/p'). Design and rationale: codeanalyzer-typescript docs/design/specs/entrypoint-detection.md, section "The heuristic tier".
The semantics are the ones #185 defined — written spelling, no resolution, runs on every node regardless of frameworks_detected, confidence: heuristic forced by the loader, runs last, never doubles a record a framework rule made — applied to a call expression's callee instead of a decorator. Same tier, same engine, one more shape.
Consequence today: a rules file shared between the two analyzers that contains heuristics.calls is a hard error in python. That is the loader working as intended, which is exactly why this needs a decision rather than a workaround.
Describe the solution you'd like
Describe alternatives you've considered
Not stated in the original issue.
Additional context
Scope boundary
Loader acceptance only. Python does not need to act on calls: — it has no call-declared entrypoint frameworks in its shipped ruleset.
Not in scope: implementing a call-site matcher in python.
Caveats and known risks
- Accepted-and-ignored is the thing
rules.py:22 argues against, and rightly. The distinction here: calls: is not an unimplemented python feature a user might be relying on — it is a matcher kind that has no python meaning. Validating its shape while not acting on it keeps a malformed rule loud without pretending python matches calls. Worth stating in the code comment, so the next reader does not see it as an exception to the rule.
- If python ever grows a call-declared framework worth shipping rules for, the key is already there.
Definition of done
- The shared-format test loads a file with both keys and asserts python produced entrypoints only from
decorators
- A
heuristics.calls entry with a malformed shape still raises RulesError
- An unknown key under
heuristics still raises RulesError
Is your feature request related to a problem? Please describe.
codeanalyzer/entrypoints/rules.pyaccepts exactly one matcher kind underheuristics:—decorators— and rejects unknown keys by design (_TOP_LEVEL_KEYS, and the comment atrules.py:22: blocks not implemented are "deliberately absent here rather than accepted-and-ignored, so a user file using them fails loudly instead of loading clean and doing nothing").codeanalyzer-typescript is adding a second matcher kind to the same block,
heuristics.calls, because its ecosystem declares entrypoints by call as often as by decorator — Express, Koa and Fastify areapp.get('/p', handler), not@Get('/p'). Design and rationale: codeanalyzer-typescriptdocs/design/specs/entrypoint-detection.md, section "The heuristic tier".The semantics are the ones #185 defined — written spelling, no resolution, runs on every node regardless of
frameworks_detected,confidence: heuristicforced by the loader, runs last, never doubles a record a framework rule made — applied to a call expression's callee instead of a decorator. Same tier, same engine, one more shape.Consequence today: a rules file shared between the two analyzers that contains
heuristics.callsis a hard error in python. That is the loader working as intended, which is exactly why this needs a decision rather than a workaround.Describe the solution you'd like
heuristics.callsis a known key: validated for shape (a list of rules withid,match, and the same optionalroute/methodsspec asdecorators, plushandler), then ignoredheuristics.decoratorsandheuristics.callsloads cleanheuristics.<anything else>still fails loudly, so the "no silent no-ops" property is keptDescribe alternatives you've considered
Not stated in the original issue.
Additional context
Scope boundary
Loader acceptance only. Python does not need to act on
calls:— it has no call-declared entrypoint frameworks in its shipped ruleset.Not in scope: implementing a call-site matcher in python.
Caveats and known risks
rules.py:22argues against, and rightly. The distinction here:calls:is not an unimplemented python feature a user might be relying on — it is a matcher kind that has no python meaning. Validating its shape while not acting on it keeps a malformed rule loud without pretending python matches calls. Worth stating in the code comment, so the next reader does not see it as an exception to the rule.Definition of done
decoratorsheuristics.callsentry with a malformed shape still raisesRulesErrorheuristicsstill raisesRulesError