@@ -369,6 +369,135 @@ class PyExternalSymbol(BaseModel):
369369 module : Optional [str ] = None # best-effort owning module, e.g. "requests"
370370
371371
372+ @builder
373+ @msgpk
374+ class PyGraphNode (BaseModel ):
375+ """A CFG node of one callable's level-3 graphs. ``id`` is the source-span
376+ order index within the callable (synthetic ENTRY = 0, EXIT = last CFG id);
377+ ``(signature, id)`` is the cross-section join key."""
378+
379+ id : int
380+ kind : Literal [
381+ "entry" , "exit" , "statement" , "branch" , "loop" , "return" , "raise" , "handler"
382+ ] = "statement"
383+ start_line : int = - 1
384+ end_line : int = - 1
385+ start_column : int = - 1
386+ end_column : int = - 1
387+
388+
389+ @builder
390+ @msgpk
391+ class PyCFGEdge (BaseModel ):
392+ """Control-flow successor edge (shared cross-language kind vocabulary)."""
393+
394+ source : int
395+ target : int
396+ kind : Literal [
397+ "fallthrough" ,
398+ "true" ,
399+ "false" ,
400+ "switch_case" ,
401+ "loop_back" ,
402+ "exception" ,
403+ "return" ,
404+ "break" ,
405+ "continue" ,
406+ "yield" ,
407+ "await_resume" ,
408+ ] = "fallthrough"
409+
410+
411+ @builder
412+ @msgpk
413+ class PyPDGEdge (BaseModel ):
414+ """Dependence edge: control (``CDG``) or data (``DDG``, labeled with the
415+ k-limited access path being read)."""
416+
417+ source : int
418+ target : int
419+ type : Literal ["CDG" , "DDG" ] = "DDG"
420+ var : Optional [str ] = None
421+
422+
423+ @builder
424+ @msgpk
425+ class PyParamNode (BaseModel ):
426+ """HRB parameter-passing node, sharing the owning callable's id space
427+ (allocated after EXIT). ``call_node`` is the owning callsite statement for
428+ actuals; ``var`` is the parameter name, ``<return>``, ``<capture>:name``,
429+ or ``<global>:module::name``."""
430+
431+ id : int
432+ kind : Literal ["formal_in" , "formal_out" , "actual_in" , "actual_out" ]
433+ var : str
434+ call_node : Optional [int ] = None
435+ start_line : int = - 1
436+ end_line : int = - 1
437+
438+
439+ @builder
440+ @msgpk
441+ class PyCFG (BaseModel ):
442+ """One callable's control-flow graph."""
443+
444+ nodes : List [PyGraphNode ] = []
445+ edges : List [PyCFGEdge ] = []
446+
447+
448+ @builder
449+ @msgpk
450+ class PyPDG (BaseModel ):
451+ """One callable's dependence edges (over the same node ids as the CFG
452+ plus its parameter nodes)."""
453+
454+ edges : List [PyPDGEdge ] = []
455+
456+
457+ @builder
458+ @msgpk
459+ class PyFunctionGraphs (BaseModel ):
460+ """The per-callable level-3 sections, keyed by signature."""
461+
462+ cfg : Optional [PyCFG ] = None
463+ pdg : Optional [PyPDG ] = None
464+ param_nodes : List [PyParamNode ] = []
465+
466+
467+ @builder
468+ @msgpk
469+ class PySDGEndpoint (BaseModel ):
470+ """A ``(signature, node)`` reference into a function's emitted graphs."""
471+
472+ signature : str
473+ node : int
474+
475+
476+ @builder
477+ @msgpk
478+ class PySDGEdge (BaseModel ):
479+ """Interprocedural dependence edge. ``CALL``/``PARAM_IN``/``PARAM_OUT``
480+ cross functions; ``SUMMARY`` connects a callsite's actual_in to its
481+ actual_out within the caller (the callee's transitive flow)."""
482+
483+ source : PySDGEndpoint
484+ target : PySDGEndpoint
485+ type : Literal ["CALL" , "PARAM_IN" , "PARAM_OUT" , "SUMMARY" ]
486+ var : Optional [str ] = None
487+
488+
489+ @builder
490+ @msgpk
491+ class PyProgramGraphs (BaseModel ):
492+ """The optional level-3 top-level section of ``analysis.json`` (present
493+ only at ``-a 3``), versioned independently of the application schema."""
494+
495+ schema_version : str = "1.0.0"
496+ k_limit : int = 3
497+ functions : Dict [str , PyFunctionGraphs ] = {}
498+ sdg_edges : List [PySDGEdge ] = []
499+
500+
372501@builder
373502@msgpk
374503class PyApplication (BaseModel ):
@@ -380,3 +509,5 @@ class PyApplication(BaseModel):
380509 # builtin members), keyed by signature. Populated by the analyzer so every
381510 # backend (JSON and Neo4j) shares one authoritative external-symbol set.
382511 external_symbols : Dict [str , PyExternalSymbol ] = {}
512+ # Level-3 native dataflow graphs (CFG/PDG/SDG); None below -a 3.
513+ program_graphs : Optional [PyProgramGraphs ] = None
0 commit comments