a3-python 0.1.13__tar.gz → 0.1.15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (408) hide show
  1. a3_python-0.1.15/PKG-INFO +644 -0
  2. a3_python-0.1.15/README.md +629 -0
  3. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/agentic_triage.py +76 -24
  4. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/templates/a3-pr-scan.yml +10 -8
  5. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/templates/a3-scheduled-scan.yml +6 -4
  6. a3_python-0.1.15/a3_python.egg-info/PKG-INFO +644 -0
  7. {a3_python-0.1.13 → a3_python-0.1.15}/pyproject.toml +1 -1
  8. a3_python-0.1.13/PKG-INFO +0 -343
  9. a3_python-0.1.13/README.md +0 -328
  10. a3_python-0.1.13/a3_python.egg-info/PKG-INFO +0 -343
  11. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/__init__.py +0 -0
  12. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/__main__.py +0 -0
  13. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/analyzer.py +0 -0
  14. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/__init__.py +0 -0
  15. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/abstraction.py +0 -0
  16. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/advanced.py +0 -0
  17. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/assume_guarantee.py +0 -0
  18. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/bayesian_fp_scorer.py +0 -0
  19. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/boolean_programs.py +0 -0
  20. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/cegar_refinement.py +0 -0
  21. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/cegis.py +0 -0
  22. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/certificate_core.py +0 -0
  23. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/context_aware_verification.py +0 -0
  24. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/deep_barrier_theory.py +0 -0
  25. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/dsos_sdsos.py +0 -0
  26. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/enhanced_barrier_theory.py +0 -0
  27. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/extreme_verification.py +0 -0
  28. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/fast_barrier_filters.py +0 -0
  29. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/foundations.py +0 -0
  30. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/guard_to_barrier.py +0 -0
  31. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/houdini.py +0 -0
  32. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/hscc2004.py +0 -0
  33. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/hybrid_barrier.py +0 -0
  34. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/ic3_pdr.py +0 -0
  35. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/ice.py +0 -0
  36. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/ice_learning.py +0 -0
  37. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/impact_lazy.py +0 -0
  38. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/int_bmc.py +0 -0
  39. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/interpolation_imc.py +0 -0
  40. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/invariants.py +0 -0
  41. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/kitchensink_taxonomy.py +0 -0
  42. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/lasserre_hierarchy.py +0 -0
  43. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/learned_invariants.py +0 -0
  44. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/learning.py +0 -0
  45. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/papers_11_to_15_complete.py +0 -0
  46. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/papers_16_to_20_complete.py +0 -0
  47. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/papers_1_to_5_complete.py +0 -0
  48. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/papers_6_to_10_complete.py +0 -0
  49. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/parrilo_sos_sdp.py +0 -0
  50. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/path_validation.py +0 -0
  51. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/pdr_spacer.py +0 -0
  52. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/positivstellensatz.py +0 -0
  53. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/predicate_abstraction.py +0 -0
  54. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/program_analysis.py +0 -0
  55. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/quick_precheck.py +0 -0
  56. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/ranking.py +0 -0
  57. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/ranking_synthesis.py +0 -0
  58. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/sos_safety.py +0 -0
  59. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/sos_toolbox.py +0 -0
  60. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/sos_unified.py +0 -0
  61. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/sostools.py +0 -0
  62. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/spacer_chc.py +0 -0
  63. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/sparse_sos.py +0 -0
  64. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/step_relation.py +0 -0
  65. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/stochastic_barrier.py +0 -0
  66. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/sygus_synthesis.py +0 -0
  67. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/synthesis.py +0 -0
  68. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/synthesis_engine.py +0 -0
  69. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/templates.py +0 -0
  70. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/type_inference_verification.py +0 -0
  71. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/barriers/unified_sota_912.py +0 -0
  72. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cfg/__init__.py +0 -0
  73. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cfg/affine_loop_model.py +0 -0
  74. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cfg/call_graph.py +0 -0
  75. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cfg/control_flow.py +0 -0
  76. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cfg/dataflow.py +0 -0
  77. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cfg/loop_analysis.py +0 -0
  78. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/__init__.py +0 -0
  79. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/baseline.py +0 -0
  80. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/config.py +0 -0
  81. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/init_cmd.py +0 -0
  82. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/sarif.py +0 -0
  83. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/ci/triage.py +0 -0
  84. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/cli.py +0 -0
  85. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/confidence_interval.py +0 -0
  86. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/confidence_scoring.py +0 -0
  87. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/__init__.py +0 -0
  88. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/__init__.py +0 -0
  89. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/abstract_values.py +0 -0
  90. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/contracts.py +0 -0
  91. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/deferred.py +0 -0
  92. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/device_analyzer.py +0 -0
  93. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/intervals.py +0 -0
  94. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/test_barriers.py +0 -0
  95. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/__init__.py +0 -0
  96. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/accelerators.py +0 -0
  97. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/amp.py +0 -0
  98. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/autograd.py +0 -0
  99. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/backends.py +0 -0
  100. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/core.py +0 -0
  101. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/cuda.py +0 -0
  102. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/data.py +0 -0
  103. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/distributed.py +0 -0
  104. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/distributions.py +0 -0
  105. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/experimental.py +0 -0
  106. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/export_compile.py +0 -0
  107. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/fft.py +0 -0
  108. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/hub_package.py +0 -0
  109. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/jit.py +0 -0
  110. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/linalg.py +0 -0
  111. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/nn_functional.py +0 -0
  112. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/nn_modules.py +0 -0
  113. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/onnx.py +0 -0
  114. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/optim.py +0 -0
  115. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/profiler.py +0 -0
  116. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/quantization.py +0 -0
  117. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/registry.py +0 -0
  118. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/sparse.py +0 -0
  119. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/special.py +0 -0
  120. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/tensor.py +0 -0
  121. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/barriers/torch/utils.py +0 -0
  122. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/base.py +0 -0
  123. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/builtin_relations.py +0 -0
  124. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/checker.py +0 -0
  125. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/relations.py +0 -0
  126. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/schema.py +0 -0
  127. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/security.py +0 -0
  128. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/security_lattice.py +0 -0
  129. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/stdlib.py +0 -0
  130. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/stdlib_module_relations.py +0 -0
  131. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/stdlib_stubs.py +0 -0
  132. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/contracts/torch_contracts.py +0 -0
  133. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/__init__.py +0 -0
  134. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/concolic.py +0 -0
  135. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/constraint_solver.py +0 -0
  136. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/hybrid.py +0 -0
  137. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/lockstep.py +0 -0
  138. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/path_condition.py +0 -0
  139. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/selective_concolic.py +0 -0
  140. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/stochastic_replay.py +0 -0
  141. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/dse/value_flow.py +0 -0
  142. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/evaluation/__init__.py +0 -0
  143. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/evaluation/deduplication.py +0 -0
  144. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/evaluation/repo_list.py +0 -0
  145. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/evaluation/scanner.py +0 -0
  146. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/fp_context.py +0 -0
  147. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/frontend/__init__.py +0 -0
  148. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/frontend/entry_points.py +0 -0
  149. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/frontend/loader.py +0 -0
  150. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/__init__.py +0 -0
  151. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/ast_guard_analysis.py +0 -0
  152. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/bmc.py +0 -0
  153. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/bytecode_summaries.py +0 -0
  154. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/concrete_vm.py +0 -0
  155. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/crash_summaries.py +0 -0
  156. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/framework_mocks.py +0 -0
  157. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/intent_detector.py +0 -0
  158. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/interprocedural_barriers.py +0 -0
  159. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/interprocedural_bugs.py +0 -0
  160. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/interprocedural_guards.py +0 -0
  161. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/interprocedural_taint.py +0 -0
  162. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/intraprocedural_taint.py +0 -0
  163. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/invariant_integration.py +0 -0
  164. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/oracles.py +0 -0
  165. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/security_tracker.py +0 -0
  166. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/security_tracker_lattice.py +0 -0
  167. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/sota_interprocedural.py +0 -0
  168. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/sota_intraprocedural.py +0 -0
  169. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/state.py +0 -0
  170. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/summaries.py +0 -0
  171. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/symbolic_vm.py +0 -0
  172. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/semantics/termination_integration.py +0 -0
  173. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/stochastic_risk.py +0 -0
  174. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/__init__.py +0 -0
  175. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/assert_fail.py +0 -0
  176. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/bounds.py +0 -0
  177. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/collection_bugs.py +0 -0
  178. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/data_race.py +0 -0
  179. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/deadlock.py +0 -0
  180. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/div_zero.py +0 -0
  181. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/double_free.py +0 -0
  182. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/exception_bugs.py +0 -0
  183. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/fp_domain.py +0 -0
  184. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/info_leak.py +0 -0
  185. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/integer_overflow.py +0 -0
  186. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/iterator_invalid.py +0 -0
  187. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/memory_leak.py +0 -0
  188. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/non_termination.py +0 -0
  189. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/null_ptr.py +0 -0
  190. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/panic.py +0 -0
  191. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/registry.py +0 -0
  192. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/__init__.py +0 -0
  193. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/cleartext.py +0 -0
  194. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/code_injection.py +0 -0
  195. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/command_injection.py +0 -0
  196. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/config.py +0 -0
  197. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/crypto.py +0 -0
  198. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/deserialization.py +0 -0
  199. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/filesystem.py +0 -0
  200. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/injection.py +0 -0
  201. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/lattice_detectors.py +0 -0
  202. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/path_injection.py +0 -0
  203. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/regex.py +0 -0
  204. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/sql_injection.py +0 -0
  205. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/ssrf.py +0 -0
  206. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/webapp.py +0 -0
  207. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/xml.py +0 -0
  208. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/xss.py +0 -0
  209. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/security/xxe.py +0 -0
  210. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/send_sync.py +0 -0
  211. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/stack_overflow.py +0 -0
  212. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/timing_channel.py +0 -0
  213. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/type_confusion.py +0 -0
  214. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/uninit_memory.py +0 -0
  215. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/unsafe/use_after_free.py +0 -0
  216. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/z3model/__init__.py +0 -0
  217. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/z3model/heap.py +0 -0
  218. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/z3model/taint.py +0 -0
  219. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/z3model/taint_lattice.py +0 -0
  220. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/z3model/type_tracking.py +0 -0
  221. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python/z3model/values.py +0 -0
  222. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python.egg-info/SOURCES.txt +0 -0
  223. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python.egg-info/dependency_links.txt +0 -0
  224. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python.egg-info/entry_points.txt +0 -0
  225. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python.egg-info/requires.txt +0 -0
  226. {a3_python-0.1.13 → a3_python-0.1.15}/a3_python.egg-info/top_level.txt +0 -0
  227. {a3_python-0.1.13 → a3_python-0.1.15}/setup.cfg +0 -0
  228. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_all_security.py +0 -0
  229. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_analyzer_dse_integration.py +0 -0
  230. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_analyzer_hybrid_witness_integration.py +0 -0
  231. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_analyzer_safe_integration.py +0 -0
  232. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_auto_template_synthesis.py +0 -0
  233. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_barrier_analysis.py +0 -0
  234. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_barrier_on_qlib.py +0 -0
  235. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_barriers.py +0 -0
  236. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_barriers_ranking.py +0 -0
  237. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_binary_op_bitwise.py +0 -0
  238. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_binary_op_power.py +0 -0
  239. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_binary_ops_extended.py +0 -0
  240. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_build_list.py +0 -0
  241. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_build_map.py +0 -0
  242. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_build_set.py +0 -0
  243. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_build_string.py +0 -0
  244. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_call_intrinsic_1.py +0 -0
  245. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_call_kw.py +0 -0
  246. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cegis_counterexamples.py +0 -0
  247. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cegis_synthesis.py +0 -0
  248. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cli.py +0 -0
  249. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cli_termination.py +0 -0
  250. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_closures.py +0 -0
  251. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cmd_inj.py +0 -0
  252. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_collection_bugs.py +0 -0
  253. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_concrete_taint_path.py +0 -0
  254. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_confidence_null_ptr_bounds.py +0 -0
  255. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_connection_pool_taint.py +0 -0
  256. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_constraint_solver.py +0 -0
  257. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_contains_dict.py +0 -0
  258. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_contains_op.py +0 -0
  259. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_context_precision_demo.py +0 -0
  260. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_context_sensitivity.py +0 -0
  261. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_contract_matching_specificity.py +0 -0
  262. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_contracts.py +0 -0
  263. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_contracts_integration.py +0 -0
  264. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cookie_injection.py +0 -0
  265. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_crash_summaries_compact_proofs.py +0 -0
  266. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cross_module_taint.py +0 -0
  267. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_cursor_taint.py +0 -0
  268. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_deduplication.py +0 -0
  269. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_deepspeed.py +0 -0
  270. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_deserialization_detection.py +0 -0
  271. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_dict_merge.py +0 -0
  272. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_dict_methods.py +0 -0
  273. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_dict_taint_tracking.py +0 -0
  274. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_dict_update.py +0 -0
  275. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_django_render_sanitizer.py +0 -0
  276. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_django_template_sanitization.py +0 -0
  277. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_dse.py +0 -0
  278. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_dse_context.py +0 -0
  279. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_e2e_taint_path_filtering.py +0 -0
  280. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_ellipsis_slice.py +0 -0
  281. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_exception_bug_types.py +0 -0
  282. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_exception_handlers.py +0 -0
  283. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_exception_path_forking.py +0 -0
  284. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_extended_arg.py +0 -0
  285. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_file_object_taint.py +0 -0
  286. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_file_object_taint_vm.py +0 -0
  287. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_flaml.py +0 -0
  288. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_flask_debug.py +0 -0
  289. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_function_level_termination.py +0 -0
  290. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_heap_observers.py +0 -0
  291. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_hscc2004_barrier_certificates.py +0 -0
  292. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_hybrid_concolic_symbolic_unknown_libs.py +0 -0
  293. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_ide_precision.py +0 -0
  294. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_ide_return_propagation.py +0 -0
  295. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_implicit_flow_security.py +0 -0
  296. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_import_from.py +0 -0
  297. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_import_tracking.py +0 -0
  298. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_insecure_cookie.py +0 -0
  299. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_interprocedural.py +0 -0
  300. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_interprocedural_crash_analysis.py +0 -0
  301. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_interprocedural_security.py +0 -0
  302. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_interprocedural_sigma.py +0 -0
  303. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_intraprocedural_analysis.py +0 -0
  304. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_intraprocedural_integration.py +0 -0
  305. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_intraprocedural_phase2.py +0 -0
  306. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_intraprocedural_phase3.py +0 -0
  307. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_intraprocedural_taint.py +0 -0
  308. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_invariant_integration.py +0 -0
  309. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_is_op.py +0 -0
  310. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_iteration_601.py +0 -0
  311. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_jump_forward.py +0 -0
  312. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_kitchensink_sota.py +0 -0
  313. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_kitchensink_taxonomy.py +0 -0
  314. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_lexicographic_ranking.py +0 -0
  315. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_lightgbm.py +0 -0
  316. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_list_append.py +0 -0
  317. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_load_fast_and_clear.py +0 -0
  318. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_load_fast_borrow.py +0 -0
  319. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_lockstep_concolic_replay.py +0 -0
  320. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_loop_opcodes.py +0 -0
  321. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_map_add.py +0 -0
  322. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_module_init_detection.py +0 -0
  323. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_module_init_filtering.py +0 -0
  324. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_module_vs_function_level_detection.py +0 -0
  325. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_no_concolic_mode.py +0 -0
  326. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_opcodes_build_tuple_format.py +0 -0
  327. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_open_exception_handler.py +0 -0
  328. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_orm_taint.py +0 -0
  329. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_path_forking_unit.py +0 -0
  330. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_path_injection_detection.py +0 -0
  331. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_path_limit_soundness.py +0 -0
  332. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_path_validation.py +0 -0
  333. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_polynomial_barriers.py +0 -0
  334. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_pop_jump_if_none.py +0 -0
  335. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_program_analysis.py +0 -0
  336. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_qlib_full_analyzer.py +0 -0
  337. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_qlib_known_bugs.py +0 -0
  338. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_qlib_models.py +0 -0
  339. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_ranking_synthesis.py +0 -0
  340. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_ranking_synthesis_lexicographic_integration.py +0 -0
  341. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_receiver_taint_vm.py +0 -0
  342. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_redos_detection.py +0 -0
  343. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_regex_pattern_contracts.py +0 -0
  344. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_regex_validation_sanitizers.py +0 -0
  345. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_relational_summaries.py +0 -0
  346. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_safe_proofs_e2e.py +0 -0
  347. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_security_api.py +0 -0
  348. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_security_bugs.py +0 -0
  349. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_semantics_concrete.py +0 -0
  350. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_semantics_generators.py +0 -0
  351. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_semantics_symbolic.py +0 -0
  352. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sensitivity_inference.py +0 -0
  353. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_set_add.py +0 -0
  354. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_setup_annotations.py +0 -0
  355. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sigma_taint_regression.py +0 -0
  356. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_socket_taint.py +0 -0
  357. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sos_for_safety.py +0 -0
  358. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sos_guarded_divzero.py +0 -0
  359. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sos_toolbox.py +0 -0
  360. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sota_interprocedural.py +0 -0
  361. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sota_intraprocedural.py +0 -0
  362. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_sota_pdr_bmc_ice.py +0 -0
  363. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_ssrf_detection.py +0 -0
  364. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_star_import.py +0 -0
  365. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_stdlib_contracts_expansion.py +0 -0
  366. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_stdlib_module_relations.py +0 -0
  367. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_stdlib_stubs.py +0 -0
  368. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_step_relation.py +0 -0
  369. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_stochastic_precondition_risk.py +0 -0
  370. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_stochastic_replay.py +0 -0
  371. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_store_fast_load_fast.py +0 -0
  372. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_store_global.py +0 -0
  373. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_store_subscr.py +0 -0
  374. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_subprocess_shell_param.py +0 -0
  375. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_symbolic_violation_provenance.py +0 -0
  376. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_taint_lattice.py +0 -0
  377. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_tarslip_kwargs.py +0 -0
  378. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_termination_integration.py +0 -0
  379. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_type_annotations.py +0 -0
  380. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_type_based_sanitizers.py +0 -0
  381. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_type_tracking.py +0 -0
  382. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unary_operations.py +0 -0
  383. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unpack_sequence.py +0 -0
  384. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unpack_sequence_fix.py +0 -0
  385. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_assert_fail.py +0 -0
  386. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_bounds.py +0 -0
  387. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_data_race.py +0 -0
  388. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_deadlock.py +0 -0
  389. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_div_zero.py +0 -0
  390. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_double_free.py +0 -0
  391. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_fp_domain.py +0 -0
  392. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_info_leak.py +0 -0
  393. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_integer_overflow.py +0 -0
  394. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_iterator_invalid.py +0 -0
  395. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_memory_leak.py +0 -0
  396. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_non_termination.py +0 -0
  397. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_null_ptr.py +0 -0
  398. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_panic.py +0 -0
  399. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_send_sync.py +0 -0
  400. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_stack_overflow.py +0 -0
  401. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_timing_channel.py +0 -0
  402. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_type_confusion.py +0 -0
  403. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_unsafe_uninit_memory.py +0 -0
  404. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_user_function_detection.py +0 -0
  405. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_user_function_module_init.py +0 -0
  406. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_xml_bomb.py +0 -0
  407. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_xxe_detection.py +0 -0
  408. {a3_python-0.1.13 → a3_python-0.1.15}/tests/test_z3_variable_tracking.py +0 -0
@@ -0,0 +1,644 @@
1
+ Metadata-Version: 2.4
2
+ Name: a3-python
3
+ Version: 0.1.15
4
+ Summary: Catch real Python bugs before production — 99%+ accuracy, Z3 symbolic execution, LLM-powered false-positive filtering, zero-config GitHub CI
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: z3-solver>=4.12.0
8
+ Provides-Extra: dev
9
+ Requires-Dist: pytest>=7.0; extra == "dev"
10
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
11
+ Provides-Extra: ci
12
+ Requires-Dist: anthropic>=0.30.0; extra == "ci"
13
+ Requires-Dist: openai>=1.0.0; extra == "ci"
14
+ Requires-Dist: pyyaml>=6.0; extra == "ci"
15
+
16
+ # A3: Advanced Automated Analysis for Python
17
+
18
+ **Find real bugs in Python codebases — automatically.**
19
+
20
+ A3 combines **non-LLM static analysis** with **agentic LLM triage** for 99%+ accuracy:
21
+
22
+ 1. **Static analysis first**: Uses bytecode analysis, barrier-certificate proofs, and Z3-backed symbolic execution to automatically prove 99% of candidates as false positives
23
+ 2. **Agentic LLM triage second**: An LLM agent explores the codebase — reading files, searching for guard patterns, checking callers, inspecting tests — then classifies the remaining 1% as TP or FP
24
+
25
+ No overwhelming noise. No alert fatigue. Just real bugs that matter.
26
+
27
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
28
+ [![PyPI](https://img.shields.io/pypi/v/a3-python.svg)](https://pypi.org/project/a3-python/)
29
+
30
+ ## Quick Start
31
+
32
+ ### Install
33
+
34
+ ```bash
35
+ pip install a3-python
36
+ ```
37
+
38
+ Requires **Python ≥ 3.11**. The only core dependency is `z3-solver` (installed automatically).
39
+
40
+ For CI features (GitHub Actions workflows, LLM triage, SARIF output):
41
+
42
+ ```bash
43
+ pip install a3-python[ci]
44
+ ```
45
+
46
+ ### Scan a project
47
+
48
+ ```bash
49
+ a3 scan . --output-sarif results.sarif
50
+ ```
51
+
52
+ That's it. A3 runs a 7-step pipeline — call graph construction, crash summary computation, guard detection, barrier-certificate proofs, DSE confirmation — and reports the surviving true-positive candidates.
53
+
54
+ ### Scan + agentic triage (end-to-end, single command)
55
+
56
+ ```bash
57
+ a3 scan . --triage
58
+ ```
59
+
60
+ That's it — one command. A3 scans, writes SARIF, then auto-detects your API key (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `GITHUB_TOKEN`) and launches an **agentic triage** where the LLM explores the codebase using tools (reading files, searching for guards, checking callers and tests) before classifying each finding. Only confirmed true positives survive.
61
+
62
+ You can also specify the provider explicitly:
63
+
64
+ ```bash
65
+ a3 scan . --triage openai --output-sarif results.sarif
66
+ a3 scan . --triage github # uses GITHUB_TOKEN, free in CI
67
+ a3 scan . --triage anthropic # uses ANTHROPIC_API_KEY
68
+ ```
69
+
70
+ Or run scan and triage as separate steps:
71
+
72
+ ```bash
73
+ a3 scan . --output-sarif results.sarif
74
+ a3 triage --sarif results.sarif --provider openai --agentic --verbose
75
+ ```
76
+
77
+ ### Scan with all features enabled
78
+
79
+ ```bash
80
+ # Symbolic execution portfolio (kitchensink) is enabled by default
81
+ a3 scan /path/to/project \
82
+ --interprocedural \
83
+ --dse-verify \
84
+ --deduplicate \
85
+ --min-confidence 0.3
86
+
87
+ # To disable portfolio analysis (not recommended):
88
+ a3 scan /path/to/project --no-kitchensink
89
+ ```
90
+
91
+ ### Output SARIF for GitHub Code Scanning
92
+
93
+ ```bash
94
+ a3 scan /path/to/project --output-sarif results.sarif
95
+ ```
96
+
97
+ Upload the SARIF file to GitHub's [Code Scanning](https://docs.github.com/en/code-security/code-scanning) dashboard, or use the built-in CI integration (see below).
98
+
99
+ ---
100
+
101
+ ## Continuous CI with Agentic Triage
102
+
103
+ A3 ships with GitHub Actions workflows that **continuously scan every push and every PR** using a **two-phase approach**:
104
+
105
+ 1. **Non-LLM static analysis** scans only the changed `.py` files and automatically proves 99% as false positives
106
+ 2. **Agentic LLM triage** investigates the remaining 1% — the LLM reads source files, searches for guard patterns, checks callers and tests, then classifies each finding — zero API keys needed
107
+
108
+ Every GitHub Actions runner already has a `GITHUB_TOKEN`, which gives access to GitHub Models. That's all the agentic triage needs.
109
+
110
+ ### Add to any repo in 60 seconds
111
+
112
+ ```bash
113
+ cd your-repo/
114
+ pip install a3-python[ci]
115
+ a3 init . --copilot
116
+ git add .github/ .a3.yml .a3-baseline.json
117
+ git commit -m "ci: add a3 static analysis"
118
+ git push
119
+ ```
120
+
121
+ That's it. Every push to `main`/`master` and every PR that touches Python files will now be scanned, triaged by an agentic LLM, and checked against the baseline. Results appear in GitHub's **Code Scanning** dashboard (Security → Code scanning alerts).
122
+
123
+ ### What `a3 init --copilot` creates
124
+
125
+ | File | What it does |
126
+ |------|-------------|
127
+ | `.github/workflows/a3-pr-scan.yml` | **On every push & PR:** scans only the changed `.py` files → agentic LLM investigates each finding (reads files, searches patterns, checks callers) → blocks if new bugs found → uploads SARIF |
128
+ | `.github/workflows/a3-scheduled-scan.yml` | **Weekly (Monday 6 AM UTC):** full-repo scan → agentic triage → auto-files GitHub Issues for new TPs → updates baseline |
129
+ | `.a3.yml` | Analysis configuration (what to scan, confidence thresholds, etc.) |
130
+ | `.a3-baseline.json` | Known-findings baseline for the ratchet (starts empty) |
131
+
132
+ ### How it works end-to-end
133
+
134
+ ```
135
+ push to main/master — or — PR opened (touches .py files)
136
+
137
+ ├─ 1. Non-LLM static analysis scans changed files
138
+ │ • Bytecode analysis + Z3 symbolic execution
139
+ │ • Automatically proves 99% as false positives
140
+ │ • Outputs SARIF with remaining 1% of findings
141
+
142
+ ├─ 2. Agentic LLM triage (multi-turn tool-use)
143
+ │ • For each surviving finding, an LLM agent:
144
+ │ - Reads the flagged function's source code
145
+ │ - Searches for guard checks, callers, tests
146
+ │ - Follows imports and explores related files
147
+ │ - Calls 'classify' with verdict + rationale
148
+ │ • Uses GITHUB_TOKEN → GitHub Models (zero config)
149
+
150
+ ├─ 3. Baseline ratchet check
151
+ │ new bugs not in baseline → ❌ CI fails
152
+ │ all bugs already known → ✅ CI passes
153
+
154
+ └─ 4. SARIF uploaded to GitHub Code Scanning dashboard
155
+ findings appear under Security → Code scanning alerts
156
+ ```
157
+
158
+ ### Example: What the workflow file looks like
159
+
160
+ When you run `a3 init . --copilot`, it creates `.github/workflows/a3-pr-scan.yml`. Here's the key steps:
161
+
162
+ ```yaml
163
+ # .github/workflows/a3-pr-scan.yml
164
+ # Triggers on: push to main/master, all PRs touching .py files
165
+
166
+ - name: Get changed files
167
+ id: changed
168
+ run: |
169
+ git diff --name-only --diff-filter=ACMR "$BASE"...HEAD -- '*.py' > changed_files.txt
170
+
171
+ - name: Run a3
172
+ run: |
173
+ a3 scan $(cat changed_files.txt | tr '\n' ' ') \
174
+ --output-sarif a3-results.sarif
175
+
176
+ - name: Agentic triage # ← the magic step
177
+ env:
178
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # ← already exists, no setup
179
+ run: |
180
+ a3 triage \
181
+ --sarif a3-results.sarif \
182
+ --output-sarif a3-triaged.sarif \
183
+ --repo-root . \
184
+ --provider github \
185
+ --model gpt-4o \
186
+ --agentic \
187
+ --verbose
188
+ mv a3-triaged.sarif a3-results.sarif
189
+
190
+ - name: Check baseline
191
+ run: a3 baseline diff --sarif a3-results.sarif
192
+
193
+ - name: Upload SARIF
194
+ uses: github/codeql-action/upload-sarif@v3
195
+ with:
196
+ sarif_file: a3-results.sarif
197
+ ```
198
+
199
+ The agentic triage step gives the LLM tools to explore the repo — `read_file`, `search_codebase`, `get_function_source`, `get_imports`, `list_directory` — so it can check callers, find tests, verify guards, and understand context before classifying each finding.
200
+
201
+ ### The ratchet: incremental adoption for large codebases
202
+
203
+ The baseline file records all *accepted* findings. On each PR:
204
+
205
+ - **New findings not in baseline → CI fails.** The author must fix the bug or explicitly accept it.
206
+ - **Findings that disappear → auto-pruned.** The codebase is getting healthier.
207
+ - **Pre-existing issues → ignored.** You're never blocked on legacy debt.
208
+
209
+ ```bash
210
+ # Check for new findings (exits 1 if any are new)
211
+ a3 baseline diff --sarif results.sarif
212
+
213
+ # Accept current findings into baseline
214
+ a3 baseline accept --sarif results.sarif
215
+ ```
216
+
217
+ ### Using a different LLM provider (optional)
218
+
219
+ If you prefer Claude or GPT-5 via your own API key instead of GitHub Models:
220
+
221
+ ```bash
222
+ # Anthropic (Claude) — agentic by default
223
+ export ANTHROPIC_API_KEY=sk-...
224
+ a3 triage --sarif results.sarif --output-sarif triaged.sarif --agentic
225
+
226
+ # OpenAI (GPT-5)
227
+ a3 triage --sarif results.sarif --provider openai --model gpt-5 --agentic
228
+
229
+ # GitHub Models (via GITHUB_TOKEN — free in CI)
230
+ a3 triage --sarif results.sarif --provider github --agentic
231
+ ```
232
+
233
+ For third-party providers in GitHub Actions, add the API key as a [repository secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets):
234
+
235
+ ```yaml
236
+ - name: LLM triage (Anthropic)
237
+ env:
238
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
239
+ run: a3 triage --sarif a3-results.sarif --output-sarif a3-triaged.sarif --agentic
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Configuration
245
+
246
+ Create a `.a3.yml` in your repo root (or use `a3 init` to generate one):
247
+
248
+ ```yaml
249
+ analysis:
250
+ interprocedural: true
251
+ # kitchensink: true by default (symbolic execution portfolio)
252
+ dse-verify: true
253
+ min-confidence: 0.3
254
+ deduplicate: true
255
+
256
+ ci:
257
+ fail-on-new-bugs: true
258
+ baseline-file: .a3-baseline.json
259
+ llm-triage: true # enabled by default with --copilot
260
+ llm-provider: github # uses GITHUB_TOKEN — no extra API keys
261
+ llm-model: gpt-5
262
+ sarif-upload: true
263
+
264
+ scan:
265
+ exclude:
266
+ - "tests/**"
267
+ - "docs/**"
268
+ - "**/test_*.py"
269
+ ```
270
+
271
+ When a config file is present, `a3 scan` reads it automatically — no flags needed.
272
+
273
+ ---
274
+
275
+ ## CLI Reference
276
+
277
+ ### `a3 scan`
278
+
279
+ Run static analysis on a file or project.
280
+
281
+ ```
282
+ a3 scan <target> [options]
283
+ a3 <target> [options] # legacy syntax, same behavior
284
+ ```
285
+
286
+ **Analysis flags:**
287
+
288
+ | Flag | Description |
289
+ |------|-------------|
290
+ | `--interprocedural` | Cross-function analysis with call graph and summaries |
291
+ | `--no-kitchensink` | Disable symbolic execution portfolio (enabled by default) |
292
+ | `--dse-verify` | Verify bugs with Z3-backed symbolic execution |
293
+ | `--deduplicate` | Deduplicate findings by type + location |
294
+ | `--min-confidence N` | Filter by confidence score (0.0–1.0, default: 0.7) |
295
+ | `--no-intent-filter` | Report all bugs regardless of intent classification |
296
+ | `--functions` | Treat each function as a tainted entry point (security mode) |
297
+ | `--all-functions` | Analyze every function as an entry point |
298
+ | `--context-depth N` | k-CFA context sensitivity (0, 1, 2, …) |
299
+ | `--check-termination` | Detect non-terminating loops |
300
+ | `--synthesize-invariants` | Generate inductive loop invariants |
301
+
302
+ **Output flags:**
303
+
304
+ | Flag | Description |
305
+ |------|-------------|
306
+ | `--output-sarif PATH` | Write SARIF 2.1.0 JSON |
307
+ | `--triage [PROVIDER]` | Run agentic triage after scan (auto-detects API key, or specify: `openai`, `anthropic`, `github`) |
308
+ | `--triage-model MODEL` | LLM model for integrated triage (default: provider-appropriate) |
309
+ | `--save-results PATH` | Write results as pickle (default: `results/<name>_results.pkl`) |
310
+ | `--verbose` | Detailed step-by-step output |
311
+ | `--config PATH` | Path to `.a3.yml` |
312
+
313
+ **Exit codes:** `0` = no bugs, `1` = bugs found, `2` = unknown, `3` = error.
314
+
315
+ ### `a3 init`
316
+
317
+ Bootstrap a repository with CI workflows and config.
318
+
319
+ ```
320
+ a3 init [repo_path] # default: current directory
321
+ a3 init . --copilot # enable Copilot triage (recommended)
322
+ a3 init . --llm-triage # enable triage with Anthropic/OpenAI
323
+ a3 init . --overwrite # replace existing files
324
+ ```
325
+
326
+ ### `a3 triage`
327
+
328
+ Classify findings via agentic LLM investigation.
329
+
330
+ ```
331
+ a3 triage --sarif results.sarif --provider github --agentic # GitHub Models (recommended)
332
+ a3 triage --sarif results.sarif --output-sarif triaged.sarif --agentic # Anthropic (default provider)
333
+ a3 triage --sarif results.sarif --provider openai --model gpt-5 --agentic
334
+ a3 triage --sarif results.sarif --verbose --agentic
335
+ ```
336
+
337
+ The `--agentic` flag enables multi-turn tool-use: the LLM can read files, search for patterns, inspect callers, check tests, and explore the repo before classifying each finding. Without `--agentic`, a simpler one-shot prompt is used.
338
+
339
+ Providers: `github` (uses `GITHUB_TOKEN`), `anthropic` (uses `ANTHROPIC_API_KEY`), `openai` (uses `OPENAI_API_KEY`). Pass `--api-key` to override.
340
+
341
+ ### `a3 baseline`
342
+
343
+ Manage the findings baseline (ratchet).
344
+
345
+ ```
346
+ a3 baseline diff --sarif results.sarif # check for new bugs
347
+ a3 baseline accept --sarif results.sarif # update baseline
348
+ a3 baseline diff --sarif results.sarif --auto-issue # file GitHub issues
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Detected Bug Types
354
+
355
+ ### Correctness (20 types)
356
+
357
+ `DIV_ZERO` · `NULL_PTR` · `INDEX_OOB` · `KEY_ERROR` · `TYPE_ERROR` · `ASSERT_FAIL` · `UNBOUND_VAR` · `INTEGER_OVERFLOW` · `NON_TERMINATION` · `MEMORY_LEAK` · `USE_AFTER_FREE` · `DOUBLE_FREE` · `DATA_RACE` · `DEADLOCK` · `TIMING_CHANNEL` · `INFO_LEAK` · `BOUNDS` · `RUNTIME_ERROR` · `TYPE_CONFUSION` · `OVERFLOW`
358
+
359
+ ### Security (47 types)
360
+
361
+ **Injection:** `SQL_INJECTION` · `COMMAND_INJECTION` · `CODE_INJECTION` · `PATH_INJECTION` · `LDAP_INJECTION` · `XPATH_INJECTION` · `NOSQL_INJECTION` · `REGEX_INJECTION` · `HEADER_INJECTION` · `COOKIE_INJECTION`
362
+
363
+ **Web:** `REFLECTED_XSS` · `SSRF` · `PARTIAL_SSRF` · `URL_REDIRECT` · `CSRF_PROTECTION_DISABLED` · `FLASK_DEBUG` · `INSECURE_COOKIE` · `JINJA2_AUTOESCAPE_FALSE`
364
+
365
+ **Crypto:** `WEAK_CRYPTO` · `WEAK_CRYPTO_KEY` · `BROKEN_CRYPTO_ALGORITHM` · `INSECURE_PROTOCOL`
366
+
367
+ **Deserialization:** `UNSAFE_DESERIALIZATION` · `XXE` · `XML_BOMB`
368
+
369
+ **Secrets:** `CLEARTEXT_LOGGING` · `CLEARTEXT_STORAGE` · `HARDCODED_CREDENTIALS`
370
+
371
+ **Files/Network:** `TAR_SLIP` · `INSECURE_TEMPORARY_FILE` · `WEAK_FILE_PERMISSIONS` · `BIND_TO_ALL_INTERFACES` · `MISSING_HOST_KEY_VALIDATION` · `CERT_VALIDATION_DISABLED`
372
+
373
+ **Regex DoS:** `REDOS` · `POLYNOMIAL_REDOS` · `BAD_TAG_FILTER` · `INCOMPLETE_HOSTNAME_REGEXP`
374
+
375
+ ---
376
+
377
+ ## How It Works
378
+
379
+ ### Phase 1: Non-LLM Static Analysis (filters 99% of bugs)
380
+
381
+ A3 runs a **7-step symbolic execution pipeline** using formal methods — no AI, no heuristics:
382
+
383
+ 1. **Call Graph** — Builds a whole-program call graph from all `.py` files
384
+ 2. **Crash Summaries** — Disassembles bytecode to find divisions, None-dereferences, out-of-bounds accesses, taint flows, and 67 other bug patterns
385
+ 3. **Symbolic Model Construction** — Builds Z3 symbolic representations of Python code objects
386
+ 4. **Guard Detection** — Identifies bugs already protected by `if`, `try/except`, `assert`, `isinstance` checks using symbolic constraints
387
+ 5. **Z3 Symbolic Execution** — Uses Z3 SMT solver to prove whether bugs are reachable by constructing satisfying assignments
388
+ 6. **Staged Portfolio** — Runs multiple proof strategies in parallel (barrier certificates, inductive invariants, k-induction)
389
+ 7. **Classification** — Separates production code from test code
390
+
391
+ Each bug receives one of three verdicts:
392
+
393
+ | Verdict | Meaning |
394
+ |---------|---------|
395
+ | **FP (proven)** | Barrier certificate or DSE proves the bug is unreachable — **99% of findings** |
396
+ | **TP candidate** | No proof found; send to LLM for verification — **~1% of findings** |
397
+ | **DSE-confirmed TP** | Z3 found a satisfying input that triggers the crash — **Even more likely bug** |
398
+
399
+ ### Phase 2: Agentic LLM Triage (investigates the remaining 1%)
400
+
401
+ For findings that survive static analysis, A3 launches an **agentic investigation** — a multi-turn conversation where the LLM has access to tools:
402
+
403
+ | Tool | What it does |
404
+ |------|-------------|
405
+ | `read_file` | Read any source file (with optional line range) |
406
+ | `search_codebase` | Grep for regex patterns across the project |
407
+ | `get_function_source` | Look up any function by name |
408
+ | `get_imports` | See what a file imports |
409
+ | `list_directory` | Explore project structure |
410
+ | `classify` | Submit final TP/FP verdict with confidence + rationale |
411
+
412
+ The agent typically makes 2–6 tool calls per finding — reading callers, checking for guard patterns, looking at tests, following imports — then calls `classify` with its verdict.
413
+
414
+ This is **not** a one-shot prompt. The LLM decides what to investigate, gathers evidence iteratively, and only classifies when it has enough context. This produces significantly more accurate results than a single-pass LLM call.
415
+
416
+ ---
417
+
418
+ ## Examples
419
+
420
+ ### Quick Demo: Detecting Real Bugs
421
+
422
+ ```python
423
+ # examples.py
424
+
425
+ def authenticate_user(username, user_database):
426
+ """Look up user credentials from database."""
427
+ user_record = user_database.get(username)
428
+ return user_record['password_hash'] # NULL_PTR: user_record could be None
429
+
430
+ def calculate_completion_rate(completed, total):
431
+ """Calculate completion percentage."""
432
+ return (completed / total) * 100 # DIV_ZERO: total could be 0
433
+
434
+ def get_database_host(config):
435
+ """Extract database host from config."""
436
+ return config.database.host # NULL_PTR: config or database could be None
437
+
438
+ def get_latest_transaction(transactions):
439
+ """Get the most recent transaction."""
440
+ sorted_txns = sorted(transactions, key=lambda t: t.date, reverse=True)
441
+ return sorted_txns[0].amount # BOUNDS: sorted_txns could be empty
442
+
443
+ def extract_email_from_csv(csv_line):
444
+ """Parse email from third column of CSV."""
445
+ fields = csv_line.split(',')
446
+ return fields[2].strip() # BOUNDS: might not have 3 columns
447
+
448
+ def calculate_roi(profit, cost):
449
+ """Calculate return on investment."""
450
+ return (profit / cost) * 100 # DIV_ZERO: cost could be 0
451
+
452
+ def get_product_total_price(inventory, product_id):
453
+ """Calculate total price including tax."""
454
+ product = inventory.lookup(product_id)
455
+ return product.base_price * (1 + product.tax_rate) # NULL_PTR: product could be None
456
+ ```
457
+
458
+ Run a3:
459
+
460
+ ```bash
461
+ $ a3 scan examples.py --interprocedural
462
+
463
+ ============================================================
464
+ INTERPROCEDURAL ANALYSIS RESULTS
465
+ ============================================================
466
+ Total bugs found: 14
467
+
468
+ BOUNDS (3)
469
+ - examples.get_first_user_email
470
+ examples.py:41
471
+ Confidence: 0.19
472
+ - examples.get_latest_transaction
473
+ examples.py:52
474
+ Confidence: 0.19
475
+ - examples.extract_email_from_csv
476
+ examples.py:76
477
+ Confidence: 0.19
478
+
479
+ DIV_ZERO (3)
480
+ - examples.calculate_completion_rate
481
+ examples.py:19
482
+ Confidence: 0.21
483
+ - examples.calculate_average_score
484
+ examples.py:64
485
+ Confidence: 0.21
486
+ - examples.calculate_roi
487
+ examples.py:87
488
+ Confidence: 0.21
489
+
490
+ NULL_PTR (7)
491
+ - examples.get_from_cache
492
+ examples.py:110
493
+ Confidence: 0.19
494
+ - examples.get_database_host
495
+ examples.py:31
496
+ Confidence: 0.19
497
+ - examples.authenticate_user
498
+ examples.py:13
499
+ Confidence: 0.19
500
+ - examples.get_product_total_price
501
+ examples.py:98
502
+ Confidence: 0.19
503
+ - examples.calculate_average_score
504
+ examples.py:64
505
+ Confidence: 0.19
506
+ ... and 2 more
507
+
508
+ VALUE_ERROR (1)
509
+ - examples.get_first_user_email
510
+ examples.py:38
511
+ Confidence: 0.84
512
+ ```
513
+
514
+ ### Guard Detection: Safe vs Unsafe Code
515
+
516
+ A3 automatically recognizes when bugs are properly guarded:
517
+
518
+ ```python
519
+ # examples_safe.py
520
+
521
+ def authenticate_user(username, user_database):
522
+ """SAFE: Checks if user exists."""
523
+ user_record = user_database.get(username)
524
+ if user_record is not None:
525
+ return user_record['password_hash']
526
+ return None
527
+
528
+ def calculate_completion_rate(completed, total):
529
+ """SAFE: Checks for zero before division."""
530
+ if total != 0:
531
+ return (completed / total) * 100
532
+ return 0.0
533
+
534
+ def get_database_host(config):
535
+ """SAFE: Validates nested attributes."""
536
+ if config is not None and config.database is not None:
537
+ return config.database.host
538
+ return "localhost"
539
+
540
+ def get_latest_transaction(transactions):
541
+ """SAFE: Checks if list is empty."""
542
+ sorted_txns = sorted(transactions, key=lambda t: t.date, reverse=True)
543
+ if len(sorted_txns) > 0:
544
+ return sorted_txns[0].amount
545
+ return 0.0
546
+
547
+ def extract_email_from_csv(csv_line):
548
+ """SAFE: Validates column count with length guard."""
549
+ fields = csv_line.split(',')
550
+ if len(fields) >= 3:
551
+ return fields[2].strip() # SAFE: len(fields) >= 3 guards fields[2]
552
+ return None
553
+ ```
554
+
555
+ ```bash
556
+ $ a3 scan examples_safe.py --interprocedural
557
+
558
+ ============================================================
559
+ INTERPROCEDURAL ANALYSIS RESULTS
560
+ ============================================================
561
+ Total bugs found: 0
562
+ ```
563
+
564
+ **All guards successfully detected by Z3 symbolic execution!**
565
+
566
+ The key improvements:
567
+ - ✅ **BOUNDS bugs: 0** (down from 3) - Length guards like `len(fields) >= 3` now correctly protect `fields[2]`
568
+ - ✅ **NULL_PTR bugs: 0** (down from 7) - None-checks and nonnull guards detected
569
+ - ✅ **DIV_ZERO bugs: 0** (down from 3) - Zero-checks detected
570
+
571
+ For production use with legacy codebases, enable LLM triage to filter remaining false positives in unguarded code:
572
+
573
+ ```bash
574
+ a3 scan examples_safe.py --interprocedural --output-sarif results.sarif
575
+ a3 triage --sarif results.sarif --provider github --output-sarif filtered.sarif --agentic
576
+ ```
577
+
578
+ With agentic triage, the LLM explores the codebase to verify each finding, achieving 99%+ accuracy.
579
+
580
+
581
+ ### Finding Real Bugs in a Large Project
582
+
583
+ ```bash
584
+ # Full symbolic execution pipeline (kitchensink enabled by default)
585
+ a3 scan . --interprocedural --dse-verify --output-sarif results.sarif
586
+
587
+ # Agentic triage for remaining 1% after symbolic verification
588
+ a3 triage --sarif results.sarif --output-sarif triaged.sarif --provider github --agentic --verbose
589
+
590
+ # Baseline ratchet check
591
+ a3 baseline diff --sarif triaged.sarif --auto-issue
592
+ ```
593
+
594
+ ---
595
+
596
+ ## Docker
597
+
598
+ ```bash
599
+ docker build -t a3 .
600
+ docker run --rm -v $(pwd)/my_project:/target a3 /target
601
+ docker run --rm -v $(pwd):/code a3 /code/myfile.py --functions
602
+ ```
603
+
604
+ ---
605
+
606
+ ## Architecture
607
+
608
+ ```
609
+ a3_python/
610
+ ├── cli.py # CLI with subcommands (scan, init, triage, baseline)
611
+ ├── analyzer.py # Core analysis engine
612
+ ├── frontend/ # Python loading, bytecode compilation
613
+ ├── cfg/ # Control-flow graph + call graph construction
614
+ ├── semantics/ # Symbolic bytecode execution, crash summaries
615
+ ├── z3model/ # Z3 value/heap modeling
616
+ ├── unsafe/ # Bug type predicates (67 types)
617
+ ├── contracts/ # External call modeling, taint sources/sinks
618
+ ├── dse/ # Concolic execution (Z3-backed)
619
+ ├── barriers/ # Barrier certificate synthesis (10 patterns)
620
+ └── ci/ # CI integration
621
+ ├── sarif.py # SARIF 2.1.0 serializer
622
+ ├── baseline.py # Ratchet / baseline management
623
+ ├── triage.py # One-shot LLM classification
624
+ ├── agentic_triage.py # Multi-turn agentic triage with tool-use
625
+ ├── config.py # .a3.yml loader
626
+ ├── init_cmd.py # `a3 init` bootstrapper
627
+ └── templates/ # GitHub Actions workflow YAMLs
628
+ ```
629
+
630
+ ---
631
+
632
+ ## Development
633
+
634
+ ```bash
635
+ git clone https://github.com/thehalleyyoung/a3-python.git
636
+ cd a3-python
637
+ pip install -e ".[dev,ci]"
638
+ pytest
639
+ pytest --cov=a3_python
640
+ ```
641
+
642
+ ## License
643
+
644
+ See [LICENSE](LICENSE) file.