sourcecode 4.1.0__tar.gz → 4.2.0__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 (206) hide show
  1. {sourcecode-4.1.0 → sourcecode-4.2.0}/CHANGELOG.md +153 -0
  2. {sourcecode-4.1.0 → sourcecode-4.2.0}/PKG-INFO +15 -1
  3. {sourcecode-4.1.0 → sourcecode-4.2.0}/README.md +14 -0
  4. {sourcecode-4.1.0 → sourcecode-4.2.0}/pyproject.toml +1 -1
  5. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/__init__.py +1 -1
  6. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/caller_reach.py +16 -7
  7. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/canonical_ir.py +29 -0
  8. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/cli.py +235 -3
  9. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/contract_diff.py +5 -4
  10. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/environment_resolution.py +100 -6
  11. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/facts/registry.json +15 -0
  12. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/git_checkout.py +5 -2
  13. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/non_coverage.py +25 -0
  14. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/posture.py +393 -7
  15. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/remedies.py +18 -1
  16. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/risk.py +73 -15
  17. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_impact.py +14 -3
  18. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/verify_repo.py +5 -0
  19. {sourcecode-4.1.0 → sourcecode-4.2.0}/.github/workflows/build-windows.yml +0 -0
  20. {sourcecode-4.1.0 → sourcecode-4.2.0}/.gitignore +0 -0
  21. {sourcecode-4.1.0 → sourcecode-4.2.0}/.ruff.toml +0 -0
  22. {sourcecode-4.1.0 → sourcecode-4.2.0}/CONTRIBUTING.md +0 -0
  23. {sourcecode-4.1.0 → sourcecode-4.2.0}/LICENSE +0 -0
  24. {sourcecode-4.1.0 → sourcecode-4.2.0}/SECURITY.md +0 -0
  25. {sourcecode-4.1.0 → sourcecode-4.2.0}/raw +0 -0
  26. {sourcecode-4.1.0 → sourcecode-4.2.0}/scripts/compare_integration_engines.py +0 -0
  27. {sourcecode-4.1.0 → sourcecode-4.2.0}/scripts/customer_smoke_test.sh +0 -0
  28. {sourcecode-4.1.0 → sourcecode-4.2.0}/scripts/generate_jdk_exports.py +0 -0
  29. {sourcecode-4.1.0 → sourcecode-4.2.0}/scripts/perf_harness.py +0 -0
  30. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/adaptive_scanner.py +0 -0
  31. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/archetype.py +0 -0
  32. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/architectural_baseline.py +0 -0
  33. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/architectural_delta.py +0 -0
  34. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/architecture_analyzer.py +0 -0
  35. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/architecture_summary.py +0 -0
  36. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/ast_extractor.py +0 -0
  37. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/cache.py +0 -0
  38. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/cache_model.py +0 -0
  39. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/call_surface.py +0 -0
  40. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/caller_metrics.py +0 -0
  41. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/chain_rules.py +0 -0
  42. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/change_plan.py +0 -0
  43. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/cir_graphs.py +0 -0
  44. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/classifier.py +0 -0
  45. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/code_notes_analyzer.py +0 -0
  46. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/compare.py +0 -0
  47. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/confidence_analyzer.py +0 -0
  48. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/constraint_diff.py +0 -0
  49. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/context_cache.py +0 -0
  50. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/context_graph.py +0 -0
  51. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/context_scorer.py +0 -0
  52. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/context_summarizer.py +0 -0
  53. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/contract_init.py +0 -0
  54. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/contract_model.py +0 -0
  55. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/contract_pipeline.py +0 -0
  56. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/coverage_parser.py +0 -0
  57. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/defect_identity.py +0 -0
  58. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/degradation.py +0 -0
  59. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/dependency_analyzer.py +0 -0
  60. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/deployment_prefix.py +0 -0
  61. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/__init__.py +0 -0
  62. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/base.py +0 -0
  63. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
  64. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/dart.py +0 -0
  65. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/dotnet.py +0 -0
  66. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/elixir.py +0 -0
  67. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/go.py +0 -0
  68. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/heuristic.py +0 -0
  69. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/hybrid.py +0 -0
  70. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/java.py +0 -0
  71. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  72. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/nodejs.py +0 -0
  73. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/parsers.py +0 -0
  74. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/php.py +0 -0
  75. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/project.py +0 -0
  76. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/python.py +0 -0
  77. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/ruby.py +0 -0
  78. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/rust.py +0 -0
  79. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/systems.py +0 -0
  80. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/terraform.py +0 -0
  81. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/detectors/tooling.py +0 -0
  82. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/doc_analyzer.py +0 -0
  83. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
  84. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/endpoint_literals.py +0 -0
  85. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/endpoint_metrics.py +0 -0
  86. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/entrypoint_classifier.py +0 -0
  87. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/env_analyzer.py +0 -0
  88. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/envelope.py +0 -0
  89. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/error_schema.py +0 -0
  90. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/evidence_provider.py +0 -0
  91. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/explain.py +0 -0
  92. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/facts/__init__.py +0 -0
  93. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/file_chunker.py +0 -0
  94. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/file_classifier.py +0 -0
  95. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/filter_surface.py +0 -0
  96. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/format_contract.py +0 -0
  97. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/fqn_utils.py +0 -0
  98. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/git_analyzer.py +0 -0
  99. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/graph_analyzer.py +0 -0
  100. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/graph_evidence.py +0 -0
  101. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/hibernate_strat.py +0 -0
  102. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/identity_fallback.py +0 -0
  103. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/integration_coordinates.py +0 -0
  104. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/jdk_exports.py +0 -0
  105. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/license.py +0 -0
  106. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/__init__.py +0 -0
  107. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  108. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  109. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  110. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  111. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  112. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/orchestrator.py +0 -0
  113. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/registry.py +0 -0
  114. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/runner.py +0 -0
  115. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp/server.py +0 -0
  116. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/mcp_nudge.py +0 -0
  117. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/metrics_analyzer.py +0 -0
  118. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/migrate_check.py +0 -0
  119. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/migration_blast.py +0 -0
  120. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/openapi_surface.py +0 -0
  121. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/output_budget.py +0 -0
  122. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/parse_cache.py +0 -0
  123. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/path_admission.py +0 -0
  124. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/path_filters.py +0 -0
  125. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/perf.py +0 -0
  126. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/pipe_contract.py +0 -0
  127. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/pr_comment_renderer.py +0 -0
  128. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/pr_impact.py +0 -0
  129. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/prepare_context.py +0 -0
  130. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/progress.py +0 -0
  131. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/ranking_engine.py +0 -0
  132. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/readiness_timeline.py +0 -0
  133. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/reconciliation.py +0 -0
  134. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/redactor.py +0 -0
  135. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/reference_facts.py +0 -0
  136. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/release_info.py +0 -0
  137. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/relevance_scorer.py +0 -0
  138. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/rename_refactor.py +0 -0
  139. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/repo_classifier.py +0 -0
  140. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/repository_ir.py +0 -0
  141. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/__init__.py +0 -0
  142. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/context.py +0 -0
  143. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/errors.py +0 -0
  144. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/executor.py +0 -0
  145. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/planner.py +0 -0
  146. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/query.py +0 -0
  147. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/request.py +0 -0
  148. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/resolution.py +0 -0
  149. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/result.py +0 -0
  150. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/retriever.py +0 -0
  151. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/runtime.py +0 -0
  152. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps.py +0 -0
  153. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  154. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
  155. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
  156. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
  157. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
  158. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  159. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/ris.py +0 -0
  160. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/rule_catalog.py +0 -0
  161. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/runtime_classifier.py +0 -0
  162. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/scanner.py +0 -0
  163. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/schema.py +0 -0
  164. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
  165. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/security_config.py +0 -0
  166. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/security_config_scan.py +0 -0
  167. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/security_posture.py +0 -0
  168. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/semantic_analyzer.py +0 -0
  169. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/semantic_impact_engine.py +0 -0
  170. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/semantic_integration_engine.py +0 -0
  171. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/semantic_services.py +0 -0
  172. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/serializer.py +0 -0
  173. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_event_topology.py +0 -0
  174. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_findings.py +0 -0
  175. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_model.py +0 -0
  176. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_profiles.py +0 -0
  177. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_properties.py +0 -0
  178. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_security_audit.py +0 -0
  179. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_semantic.py +0 -0
  180. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
  181. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/summarizer.py +0 -0
  182. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/target_admission.py +0 -0
  183. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/telemetry/__init__.py +0 -0
  184. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/telemetry/config.py +0 -0
  185. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/telemetry/consent.py +0 -0
  186. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/telemetry/events.py +0 -0
  187. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/telemetry/filters.py +0 -0
  188. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/telemetry/transport.py +0 -0
  189. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/test_gap_ranking.py +0 -0
  190. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/test_sources.py +0 -0
  191. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/token_estimate.py +0 -0
  192. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/tree_utils.py +0 -0
  193. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/type_usage_surface.py +0 -0
  194. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/validation_inference.py +0 -0
  195. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/validation_surface.py +0 -0
  196. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/verify_edit.py +0 -0
  197. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/verify_rules.py +0 -0
  198. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/version_check.py +0 -0
  199. {sourcecode-4.1.0 → sourcecode-4.2.0}/src/sourcecode/workspace.py +0 -0
  200. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/functions/README.md +0 -0
  201. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/functions/get-license/index.ts +0 -0
  202. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  203. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/functions/telemetry/index.ts +0 -0
  204. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/sql/license_event_ordering.sql +0 -0
  205. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/sql/licensing_schema.sql +0 -0
  206. {sourcecode-4.1.0 → sourcecode-4.2.0}/supabase/sql/telemetry_events.sql +0 -0
@@ -2,6 +2,159 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [4.2.0] — 2026-08-03
6
+
7
+ Minor, not a patch, by this project's own criterion: two published figures move
8
+ and a verdict changes, so a pipeline reading either can change colour.
9
+ `posture --resolve-environments` answers `NOT DECIDED IN THIS REPOSITORY` where
10
+ it answered `artefacts_disagree` on a repository whose build properties nothing
11
+ consumes (C1-22), and `ask risk` publishes defects where it published findings,
12
+ so `total_defects` and `by_band` move (C1-23) — 20 → 15 on BroadleafCommerce.
13
+ `risk` also drops `rule_id` for `rule_ids`: it is in the `experimental` tier,
14
+ whose published promise is exactly that its shape may change in a minor.
15
+
16
+ Field evaluation #9 (8/10, same 3 337-file monolith as #6–#8) opened nine rows
17
+ and this release closes seven of them. The two left open are open on purpose:
18
+ `C3-39` needs a Windows runner before it needs a fix, and `P-7` is a pricing
19
+ decision. Every complaint was re-measured against HEAD before a row was written
20
+ — five reproduced, one was half false, one was not reproducible here, and one
21
+ was a capability that already shipped.
22
+
23
+ ### Added
24
+
25
+ - **`ask posture --diff-ref <base>:<head>` and `--since <ref>` — one profile set,
26
+ two git refs** (roadmap M10.5 item 1). `--diff` holds the tree fixed and moves
27
+ the profile set; this holds the profile set fixed and moves the tree, which is
28
+ the question a pull request asks: *does this change what a client can reach
29
+ without authenticating?* `--since` compares a ref with the working tree,
30
+ uncommitted edits included. Both refs are read with `git archive`: nothing is
31
+ written to the repository, no worktree is created and the index is not touched.
32
+ `docs/posture.md` had declared this as the one requested extension with no
33
+ feature behind it.
34
+ - **`--fail-on opened|any|never` — the gate half.** Default `never`, so no
35
+ invocation that worked yesterday changes colour today; `opened` exits 1 when a
36
+ request a readable rule leaves reachable unauthenticated was not one before.
37
+ The payload is emitted before the exit code, because a red pipeline with no
38
+ statement of what opened is a gate nobody keeps. It requires a ref comparison —
39
+ gating a single run would gate on pre-existing debt, which is `spring-audit --ci`.
40
+ - **`endpoint_request_identity` registered as a fact** (ADR-0008 R11,
41
+ `sourcecode.canonical_ir:request_identity`). The comparison unit is the request
42
+ (`METHOD path`), not the endpoint id, which carries the controller FQN and the
43
+ handler symbol and therefore changes when a handler moves between classes
44
+ without the URL changing. `contract_diff` re-derived the same identity and now
45
+ binds to the authority. Path-variable patterns are deliberately **not**
46
+ normalised: `{id:.*}` and `{id:[^0-9].*}` are different URLs to a caller, and
47
+ one field repository moved 93 requests with exactly that edit in a single commit.
48
+
49
+ ### Added
50
+
51
+ - **`ask endpoints --compact` — the census instead of the rows** (C2-22, field
52
+ evaluation #9). Asked how exposed a repository was, the command answered with
53
+ 1.9 MB of JSON for 3 574 endpoints and no summary mode, and the evaluator
54
+ aggregated it by hand. Every answer now carries an `exposure` block — counts by
55
+ method, by security policy, by controller and by first path area — and
56
+ `--compact` returns it without the rows, declaring what it dropped. Two rules
57
+ it obeys against itself: the census is measured over the population the filters
58
+ chose and never over what `--limit` left rendered, and every ranked rollup
59
+ states its own total when it cuts. Measured on BroadleafCommerce: 95 KB → 11 KB,
60
+ every count unchanged. (The other half of the complaint is recorded as false:
61
+ `spring-audit` has shipped `--compact`, `--min-severity` and `--scope` for
62
+ releases.)
63
+
64
+ - **NC-007 — the endpoint population is declared** (CL-12, field evaluation #9).
65
+ `endpoints` projects Spring handler mappings; a servlet declared in `web.xml`
66
+ or registered as a `ServletRegistrationBean` is reachable over HTTP and is in
67
+ no part of that model. Six published non-coverage rows are exactly what let a
68
+ reader treat the list as the whole HTTP surface, and the evaluation lost a
69
+ monitoring console that way — at a path behind the credential the same run
70
+ reported as SEC-007. The row is published in the `endpoints` payload and inside
71
+ `posture.endpoints`, because the reader who counts open requests is reading
72
+ `posture`. Admission of a servlet surface is deliberately **not** in this
73
+ change: it is a second population and merging it into `endpoints.total` would
74
+ move a published count and every ratio keyed on it.
75
+
76
+ ### Fixed
77
+
78
+ - **A reach figure that did not name its scope** (C2-23, field evaluation #9).
79
+ `risk` reported `endpoints_reached: 1` for a symbol whose class `impact-chain`
80
+ said reached 8 — both correct, both documented, in two payloads, so reconciling
81
+ them cost the reader three unit notes. Each row now carries
82
+ `endpoints_reached_basis`: what the figure is a reach *of* (a defect sits at the
83
+ symbol that carries the remedy, so a method-level defect walks from the method)
84
+ and, where that is narrower than a class, the command that answers the wider
85
+ question. The relationship is asserted by measurement rather than stated in
86
+ prose.
87
+
88
+ - **The remedy registry now follows the status, not only the limitation** (C4-13,
89
+ field evaluation #9 — the sixth appearance of the C4 shape). The evaluation met
90
+ `verify`'s `contract_count: 0` → `unverified` → exit 2 under a read-only
91
+ constraint, concluded the command was unusable and asked for a `--dry-run` that
92
+ shipped in 3.7.0. The state named one next move and the reader could not take
93
+ it. `Remedy` gained `also` (the further options an answer needs — a remedy is an
94
+ invocation, not a flag), the new entry is `ask verify . --init --dry-run`, and
95
+ the `unverified` reason names both forms. The guard grew with it: every option
96
+ of an invocation must be accepted by the command it names, and the README check
97
+ matches a line carrying the command with all of its options, so a front page
98
+ that lists `--init` and omits `--dry-run` fails the build.
99
+
100
+ - **The hub-class guard contradicted the payload beside it** (C2-21, field
101
+ evaluation #9). It printed *"symbol has > 500 direct callers"* while the same
102
+ run published 215 of them on openmrs-core's `Context`: the guard trips on
103
+ caller **reference sites** (method-level keys included) and the payload
104
+ publishes caller **classes**, so the stated reason was checkably false while
105
+ the decision was right. `caller_reach.bfs_callers` now returns the population it
106
+ read, and the warning names it with its unit next to the class count it takes
107
+ from `caller_metrics.caller_classes` — *"792 caller reference sites … exceed the
108
+ cap of 500 … The 215 direct caller classes this run publishes stay exact"*.
109
+
110
+ - **`ask risk` ranked findings under the label `spring-audit` deduplicates**
111
+ (C1-23, field evaluation #9). One SEC-004 appeared three times for three call
112
+ sites in one class and `by_band` was an observation census under a defect
113
+ label — measured on BroadleafCommerce, 20 rows over 15 distinct `defect_id`
114
+ beside `spring-audit`'s own 15 defects / 20 findings. `build_risk` now iterates
115
+ `defect_identity.group_by_defect`, so one row is one thing to fix and both
116
+ commands report the same count (asserted against each other, not against a
117
+ literal). Nothing is dropped: `witness_count` and `witness_sites` carry where
118
+ each observation was seen, `total_findings` publishes the census under its own
119
+ name, and `rule_id` becomes **`rule_ids`** because one defect can be witnessed
120
+ by TX-001 and TX-006 at once and a singular field would have to pick one.
121
+ `severity` is the strongest across the witnesses, and
122
+ `factors.defect_severity.basis` says so.
123
+
124
+ - **A Maven build property was published as a runtime activation** (C1-22, field
125
+ evaluation #9 — the row it called the most expensive in its report). Two
126
+ `<properties>` entries setting `spring.profiles.active` made
127
+ `posture --resolve-environments` answer `artefacts_disagree` — *"different
128
+ deployments, pick one"* — on a repository where **nothing activates a profile at
129
+ run time**. The honest verdict, which the command already implements, is
130
+ `NOT DECIDED IN THIS REPOSITORY`: the default set applies and the permissive
131
+ profile wins, which is exactly where that audit's most severe finding lived. The
132
+ command turned a fail-open into a deployment ambiguity, in the scenario it is
133
+ sold for. A build property is now admitted as an activation only when a resource
134
+ in the repository consumes it (`@spring.profiles.active@`, or
135
+ `${spring.profiles.active}` where the build declares its resources filtered).
136
+ Unconsumed, the value is kept — it is still the profile set a build of it would
137
+ produce, so the worst case keeps ranking it — and carries the reason it decides
138
+ nothing, beside a `build_properties_not_consumed` count. The positive control is
139
+ half the battery: before this, the case where the property genuinely does decide
140
+ produced the identical verdict, which is how the defect stayed invisible. No
141
+ movement on the field repositories.
142
+
143
+ - **A rule that disappeared was reported as protection gained.** Found by the
144
+ negative control, not in the field: delete a security configuration and every
145
+ request it decided goes `permit_all` → undecided, which a two-bucket
146
+ opened/closed split published as *"2 requests no longer reachable
147
+ unauthenticated"*. Four buckets now: `opened` and `closed` (attributable to the
148
+ change), `no_longer_decided` (coverage lost) and `now_open_previously_undecided`
149
+ (our reading moved, not necessarily the system — it never turns a gate red on
150
+ its own). Requests undecided on either side are counted in
151
+ `access_not_decided_either_side`, the delta publishes `direction`, and
152
+ `gate.reading` states the floor (I-8).
153
+ - **`git_checkout` no longer offers a remedy half its callers do not have.** The
154
+ not-a-repository message told every caller to "pass two checkouts positionally";
155
+ `posture` takes none. The message states the fact and each command supplies its
156
+ own hint.
157
+
5
158
  ## [4.1.0] — 2026-08-03
6
159
 
7
160
  Minor, not a patch, and the criterion is this project's own: a new rule can trip
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 4.1.0
3
+ Version: 4.2.0
4
4
  Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
5
  License-File: LICENSE
6
6
  Keywords: agents,ai,codebase,context,developer-tools,llm
@@ -156,6 +156,10 @@ ask posture /path/to/repo --resolve-environments
156
156
  # writing it, and populate .ask/contracts.yml from the measurement instead of by hand.
157
157
  ask verify /path/to/repo --init
158
158
 
159
+ # Same derivation under a read-only constraint: prints what it would declare and
160
+ # writes nothing — the form an audit of somebody else's repository can run.
161
+ ask verify /path/to/repo --init --dry-run
162
+
159
163
  # What each defect actually costs once reach, access and write effect are in it:
160
164
  # severity × reachability × auth_verdict × write_effect, ordered, every factor traceable.
161
165
  ask risk /path/to/repo
@@ -230,6 +234,9 @@ What a profile set **actually wires**: which conditional beans register, which d
230
234
  `ask posture` · `ask posture --diff dev:prod` · `ask posture --property k=v`
231
235
  → [posture.md](docs/posture.md)
232
236
 
237
+ **`--diff-ref` makes it a gate instead of a report.** `--diff` moves the profile set; `--diff-ref origin/main:HEAD` (or `--since origin/main`, which compares a ref with the working tree) moves the *tree* under one profile set and answers *did this branch open an endpoint*. `--fail-on opened` exits 1 when it did. Both refs are read with `git archive` — nothing is written to the repository. The comparison is keyed on the request (`METHOD path`), counts requests only one side serves, and never reports a rule that disappeared as protection gained.
238
+ `ask posture . --since origin/main --fail-on opened`
239
+
233
240
  **`--resolve-environments` carries it past the edge of the repository.** Every answer above
234
241
  is conditional on a profile set, and which set runs is decided by the deployment. This flag
235
242
  reads every artefact in the tree that can set `spring.profiles.active` — Maven/Gradle,
@@ -354,6 +361,13 @@ Two more boundaries worth stating in the same voice:
354
361
  | **Applying a migration — nothing here edits source.** | This is the diagnosis layer: it measures what must change and what each change would reach. Rewriting code is an execution problem with an established executor, and duplicating it would mean maintaining a second, worse one. | OpenRewrite. `migrate-check` publishes the recipe each finding carries (`recipes[]`), which is the input that executor takes. |
355
362
  | **What the process environment sets at start-up — the profile set, properties and secrets a container is given.** | Nothing in a repository can observe the environment of a process that has not started. A value read from a file here is the default the repository ships, never a guarantee of what runs. | `ask posture --resolve-environments` reads every artefact in the repository that names the profile set, says when none of them decides it, and ranks the admissible sets by what each leaves open. |
356
363
 
364
+
365
+ And one about the endpoint surface itself:
366
+
367
+ | Not covered | Why | What answers it |
368
+ |---|---|---|
369
+ | **HTTP surface that is not a Spring handler mapping — a servlet declared in `web.xml` or registered as a `ServletRegistrationBean`, a container-level mapping, a static console mounted by a library.** | The endpoint population is projected from the Spring route model: one entry per handler mapping. A servlet is reachable over HTTP and is not in that model, so it is absent from `endpoints`, from the access verdicts derived from it, and from every ratio keyed on the total. Merging a second population into that count would move a published figure and every ratio with it, so the population is declared before it is widened. | Read the deployment descriptors for `<servlet-mapping>` entries and the Spring configuration for `ServletRegistrationBean` beans. Field evaluation #9 found a monitoring console mounted this way, behind a credential `ask spring-audit` did report (SEC-007) at a path nothing here listed. |
370
+
357
371
  **Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
358
372
  must change, what each change reaches, and what a gate should block — and it removes none of
359
373
  it. Field evaluation scored it 7/10 as a report generator and 5.5/10 as a development tool,
@@ -118,6 +118,10 @@ ask posture /path/to/repo --resolve-environments
118
118
  # writing it, and populate .ask/contracts.yml from the measurement instead of by hand.
119
119
  ask verify /path/to/repo --init
120
120
 
121
+ # Same derivation under a read-only constraint: prints what it would declare and
122
+ # writes nothing — the form an audit of somebody else's repository can run.
123
+ ask verify /path/to/repo --init --dry-run
124
+
121
125
  # What each defect actually costs once reach, access and write effect are in it:
122
126
  # severity × reachability × auth_verdict × write_effect, ordered, every factor traceable.
123
127
  ask risk /path/to/repo
@@ -192,6 +196,9 @@ What a profile set **actually wires**: which conditional beans register, which d
192
196
  `ask posture` · `ask posture --diff dev:prod` · `ask posture --property k=v`
193
197
  → [posture.md](docs/posture.md)
194
198
 
199
+ **`--diff-ref` makes it a gate instead of a report.** `--diff` moves the profile set; `--diff-ref origin/main:HEAD` (or `--since origin/main`, which compares a ref with the working tree) moves the *tree* under one profile set and answers *did this branch open an endpoint*. `--fail-on opened` exits 1 when it did. Both refs are read with `git archive` — nothing is written to the repository. The comparison is keyed on the request (`METHOD path`), counts requests only one side serves, and never reports a rule that disappeared as protection gained.
200
+ `ask posture . --since origin/main --fail-on opened`
201
+
195
202
  **`--resolve-environments` carries it past the edge of the repository.** Every answer above
196
203
  is conditional on a profile set, and which set runs is decided by the deployment. This flag
197
204
  reads every artefact in the tree that can set `spring.profiles.active` — Maven/Gradle,
@@ -316,6 +323,13 @@ Two more boundaries worth stating in the same voice:
316
323
  | **Applying a migration — nothing here edits source.** | This is the diagnosis layer: it measures what must change and what each change would reach. Rewriting code is an execution problem with an established executor, and duplicating it would mean maintaining a second, worse one. | OpenRewrite. `migrate-check` publishes the recipe each finding carries (`recipes[]`), which is the input that executor takes. |
317
324
  | **What the process environment sets at start-up — the profile set, properties and secrets a container is given.** | Nothing in a repository can observe the environment of a process that has not started. A value read from a file here is the default the repository ships, never a guarantee of what runs. | `ask posture --resolve-environments` reads every artefact in the repository that names the profile set, says when none of them decides it, and ranks the admissible sets by what each leaves open. |
318
325
 
326
+
327
+ And one about the endpoint surface itself:
328
+
329
+ | Not covered | Why | What answers it |
330
+ |---|---|---|
331
+ | **HTTP surface that is not a Spring handler mapping — a servlet declared in `web.xml` or registered as a `ServletRegistrationBean`, a container-level mapping, a static console mounted by a library.** | The endpoint population is projected from the Spring route model: one entry per handler mapping. A servlet is reachable over HTTP and is not in that model, so it is absent from `endpoints`, from the access verdicts derived from it, and from every ratio keyed on the total. Merging a second population into that count would move a published figure and every ratio with it, so the population is declared before it is widened. | Read the deployment descriptors for `<servlet-mapping>` entries and the Spring configuration for `ServletRegistrationBean` beans. Field evaluation #9 found a monitoring console mounted this way, behind a credential `ask spring-audit` did report (SEC-007) at a path nothing here listed. |
332
+
319
333
  **Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
320
334
  must change, what each change reaches, and what a gate should block — and it removes none of
321
335
  it. Field evaluation scored it 7/10 as a report generator and 5.5/10 as a development tool,
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "4.1.0"
7
+ version = "4.2.0"
8
8
  description = "Persistent structural context and ultra-fast repeated analysis for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -4,4 +4,4 @@ ASK Engine is the product. ``ask`` is the canonical CLI command; ``sourcecode``
4
4
  the legacy compatibility alias and the Python/PyPI package name. See
5
5
  docs/PRODUCT_IDENTITY.md (normative)."""
6
6
 
7
- __version__ = "4.1.0"
7
+ __version__ = "4.2.0"
@@ -127,13 +127,21 @@ def bfs_callers(
127
127
  max_depth: int,
128
128
  impl_graph: object | None = None,
129
129
  method_scoped: bool = False,
130
- ) -> tuple[list[str], list[str], bool, int]:
130
+ ) -> tuple[list[str], list[str], bool, int, int]:
131
131
  """Walk the reverse graph from *seed_fqns*.
132
132
 
133
- Returns ``(direct, indirect, was_truncated, self_excluded)``. ``direct`` is
134
- depth 1 — the callers of the seeds themselves; ``indirect`` is depth 2 and
135
- beyond, up to *max_depth*. ``was_truncated`` says the hub-class guard capped
136
- the walk, which makes the result a floor.
133
+ Returns ``(direct, indirect, was_truncated, self_excluded, guard_population)``.
134
+ ``direct`` is depth 1 — the callers of the seeds themselves; ``indirect`` is
135
+ depth 2 and beyond, up to *max_depth*. ``was_truncated`` says the hub-class
136
+ guard capped the walk, which makes the result a floor.
137
+
138
+ ``guard_population`` is the number the guard actually read: unique caller
139
+ **reference sites**, method-level keys included, before anything is
140
+ normalised to a class. It is returned rather than left implicit because the
141
+ figure the payload publishes is the class count, and a message that names
142
+ the cap without naming its own population contradicts the payload beside it —
143
+ measured on openmrs-core, *"symbol has > 500 direct callers"* printed next to
144
+ `direct_caller_count: 215` (C2-21).
137
145
 
138
146
  A class's own members are members, not external callers, so they are dropped
139
147
  and counted (BUG #2 — leaving them in inflated a blast radius ~12×). For a
@@ -170,7 +178,8 @@ def bfs_callers(
170
178
  if etype not in SKIP_EDGE_TYPES:
171
179
  unique_direct.update(c for c in fqn_list if not _is_self_reference(c))
172
180
 
173
- effective_depth = 1 if len(unique_direct) > CALLER_CAP else max_depth
181
+ guard_population = len(unique_direct)
182
+ effective_depth = 1 if guard_population > CALLER_CAP else max_depth
174
183
  if effective_depth < max_depth:
175
184
  was_truncated = True
176
185
 
@@ -202,4 +211,4 @@ def bfs_callers(
202
211
  else:
203
212
  _add_caller(caller, depth)
204
213
 
205
- return direct, indirect, was_truncated, self_excluded
214
+ return direct, indirect, was_truncated, self_excluded, guard_population
@@ -115,6 +115,30 @@ class CanonicalSecurity:
115
115
  # CanonicalEndpoint
116
116
  # ---------------------------------------------------------------------------
117
117
 
118
+ def request_identity(method: str, path: str) -> str:
119
+ """The identity of the **request**, not of the handler that serves it.
120
+
121
+ An endpoint `id` identifies a handler: it carries the controller FQN and the
122
+ handler symbol, so moving a mapping to another class produces a different
123
+ `id` for the same URL. That is the right identity inside one tree and the
124
+ wrong one across two — a comparison keyed on it reports every refactored
125
+ handler as one endpoint removed and another added, and the reader asking
126
+ "did this change what a caller can reach" has to subtract the noise by hand.
127
+
128
+ Two states of one repository — `contract-diff` between refs, `posture
129
+ --diff-ref` — compare what a client can call, which is METHOD + path. One
130
+ authority for it, because two spellings of one identity is how two commands
131
+ come to disagree about the same endpoint (ADR-0008 R11).
132
+
133
+ Note what this deliberately does *not* do: it does not normalise path
134
+ variable names or inline regexes. `/{id:.*}` and `/{id:[^0-9].*}` are
135
+ different URLs to a client, and equating them would hide a real change in
136
+ the surface — measured on a fleet repository where exactly that edit moved
137
+ 93 requests.
138
+ """
139
+ return f"{str(method).upper()} {path}"
140
+
141
+
118
142
  @dataclass
119
143
  class CanonicalEndpoint:
120
144
  """Canonical endpoint entity — single source of truth for REST endpoint data.
@@ -159,6 +183,11 @@ class CanonicalEndpoint:
159
183
  """Deterministic endpoint ID — stable across formatting/body changes."""
160
184
  return f"{method}:{path}:{controller_class}:{handler_symbol}"
161
185
 
186
+ @property
187
+ def request_key(self) -> str:
188
+ """This endpoint's request identity — see `request_identity`."""
189
+ return request_identity(self.method, self.path)
190
+
162
191
 
163
192
  # ---------------------------------------------------------------------------
164
193
  # CanonicalRepositoryIR