Context
Surfaced during validation of the orphan_detection policy (issue #17) and documented in docs/arch-policies.md under "False positives".
Description
The Python parser (py_parser.py) only emits CALLS edges from within function/method bodies. Code at module level — if __name__ == '__main__': blocks, module-level initialisation calls, top-level register_*() patterns — produces no outbound CALLS edges.
Concrete impact:
- Functions called only from
if __name__ == '__main__': appear as orphans in orphan_detection.
- The
/dead-code slash command reports the same false positives.
- Any CALLS-based policy (
layer_bypass, custom Cypher policies) has a blind spot for module-level call chains.
The workaround today is to add a decorator (giving the function a DECORATED_BY edge) or to disable orphan_detection for the affected path prefix — both are blunt instruments.
Suggested approach
Extend py_parser.py to walk module-level expression_statement nodes (specifically call nodes at the top scope of a module body) and emit CALLS edges from a synthetic __module__ function or from the File node directly. The edge target can be resolved the same way method-level calls are resolved today.
This is a Stage 1.5 / Stage 2 parser enhancement — it doesn't need to land before orphan_detection ships, but should be tracked so the known false-positive gap gets closed.
Context
Surfaced during validation of the
orphan_detectionpolicy (issue #17) and documented indocs/arch-policies.mdunder "False positives".Description
The Python parser (
py_parser.py) only emitsCALLSedges from within function/method bodies. Code at module level —if __name__ == '__main__':blocks, module-level initialisation calls, top-levelregister_*()patterns — produces no outboundCALLSedges.Concrete impact:
if __name__ == '__main__':appear as orphans inorphan_detection./dead-codeslash command reports the same false positives.layer_bypass, custom Cypher policies) has a blind spot for module-level call chains.The workaround today is to add a decorator (giving the function a
DECORATED_BYedge) or to disableorphan_detectionfor the affected path prefix — both are blunt instruments.Suggested approach
Extend
py_parser.pyto walk module-levelexpression_statementnodes (specificallycallnodes at the top scope of amodulebody) and emitCALLSedges from a synthetic__module__function or from theFilenode directly. The edge target can be resolved the same way method-level calls are resolved today.This is a Stage 1.5 / Stage 2 parser enhancement — it doesn't need to land before
orphan_detectionships, but should be tracked so the known false-positive gap gets closed.