sourcecode 4.2.0__tar.gz → 4.3.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 (213) hide show
  1. {sourcecode-4.2.0 → sourcecode-4.3.0}/CHANGELOG.md +182 -0
  2. {sourcecode-4.2.0 → sourcecode-4.3.0}/PKG-INFO +27 -8
  3. {sourcecode-4.2.0 → sourcecode-4.3.0}/README.md +26 -7
  4. {sourcecode-4.2.0 → sourcecode-4.3.0}/pyproject.toml +1 -1
  5. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/__init__.py +1 -1
  6. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architectural_baseline.py +19 -0
  7. sourcecode-4.3.0/src/sourcecode/baseline_autocapture.py +375 -0
  8. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cache_model.py +19 -0
  9. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cli.py +552 -23
  10. sourcecode-4.3.0/src/sourcecode/client_calls.py +305 -0
  11. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_graph.py +11 -0
  12. sourcecode-4.3.0/src/sourcecode/data_exposure.py +353 -0
  13. sourcecode-4.3.0/src/sourcecode/data_labels.py +200 -0
  14. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/dynamic_argument_surface.py +12 -5
  15. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/format_contract.py +1 -0
  16. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/non_coverage.py +45 -0
  17. sourcecode-4.3.0/src/sourcecode/openrewrite_recipe.py +278 -0
  18. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/posture.py +32 -0
  19. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/repository_ir.py +24 -3
  20. sourcecode-4.3.0/src/sourcecode/risk.py +764 -0
  21. sourcecode-4.3.0/src/sourcecode/sarif.py +618 -0
  22. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/validation_inference.py +33 -4
  23. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/verify_repo.py +17 -2
  24. sourcecode-4.2.0/src/sourcecode/risk.py +0 -403
  25. {sourcecode-4.2.0 → sourcecode-4.3.0}/.github/workflows/build-windows.yml +0 -0
  26. {sourcecode-4.2.0 → sourcecode-4.3.0}/.gitignore +0 -0
  27. {sourcecode-4.2.0 → sourcecode-4.3.0}/.ruff.toml +0 -0
  28. {sourcecode-4.2.0 → sourcecode-4.3.0}/CONTRIBUTING.md +0 -0
  29. {sourcecode-4.2.0 → sourcecode-4.3.0}/LICENSE +0 -0
  30. {sourcecode-4.2.0 → sourcecode-4.3.0}/SECURITY.md +0 -0
  31. {sourcecode-4.2.0 → sourcecode-4.3.0}/raw +0 -0
  32. {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/compare_integration_engines.py +0 -0
  33. {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/customer_smoke_test.sh +0 -0
  34. {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/generate_jdk_exports.py +0 -0
  35. {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/perf_harness.py +0 -0
  36. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/adaptive_scanner.py +0 -0
  37. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/archetype.py +0 -0
  38. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architectural_delta.py +0 -0
  39. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architecture_analyzer.py +0 -0
  40. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architecture_summary.py +0 -0
  41. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/ast_extractor.py +0 -0
  42. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cache.py +0 -0
  43. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/call_surface.py +0 -0
  44. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/caller_metrics.py +0 -0
  45. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/caller_reach.py +0 -0
  46. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/canonical_ir.py +0 -0
  47. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/chain_rules.py +0 -0
  48. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/change_plan.py +0 -0
  49. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cir_graphs.py +0 -0
  50. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/classifier.py +0 -0
  51. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/code_notes_analyzer.py +0 -0
  52. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/compare.py +0 -0
  53. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/confidence_analyzer.py +0 -0
  54. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/constraint_diff.py +0 -0
  55. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_cache.py +0 -0
  56. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_scorer.py +0 -0
  57. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_summarizer.py +0 -0
  58. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_diff.py +0 -0
  59. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_init.py +0 -0
  60. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_model.py +0 -0
  61. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_pipeline.py +0 -0
  62. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/coverage_parser.py +0 -0
  63. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/defect_identity.py +0 -0
  64. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/degradation.py +0 -0
  65. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/dependency_analyzer.py +0 -0
  66. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/deployment_prefix.py +0 -0
  67. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/__init__.py +0 -0
  68. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/base.py +0 -0
  69. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
  70. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/dart.py +0 -0
  71. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/dotnet.py +0 -0
  72. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/elixir.py +0 -0
  73. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/go.py +0 -0
  74. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/heuristic.py +0 -0
  75. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/hybrid.py +0 -0
  76. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/java.py +0 -0
  77. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  78. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/nodejs.py +0 -0
  79. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/parsers.py +0 -0
  80. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/php.py +0 -0
  81. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/project.py +0 -0
  82. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/python.py +0 -0
  83. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/ruby.py +0 -0
  84. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/rust.py +0 -0
  85. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/systems.py +0 -0
  86. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/terraform.py +0 -0
  87. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/tooling.py +0 -0
  88. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/doc_analyzer.py +0 -0
  89. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/endpoint_literals.py +0 -0
  90. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/endpoint_metrics.py +0 -0
  91. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/entrypoint_classifier.py +0 -0
  92. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/env_analyzer.py +0 -0
  93. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/envelope.py +0 -0
  94. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/environment_resolution.py +0 -0
  95. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/error_schema.py +0 -0
  96. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/evidence_provider.py +0 -0
  97. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/explain.py +0 -0
  98. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/facts/__init__.py +0 -0
  99. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/facts/registry.json +0 -0
  100. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/file_chunker.py +0 -0
  101. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/file_classifier.py +0 -0
  102. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/filter_surface.py +0 -0
  103. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/fqn_utils.py +0 -0
  104. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/git_analyzer.py +0 -0
  105. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/git_checkout.py +0 -0
  106. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/graph_analyzer.py +0 -0
  107. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/graph_evidence.py +0 -0
  108. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/hibernate_strat.py +0 -0
  109. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/identity_fallback.py +0 -0
  110. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/integration_coordinates.py +0 -0
  111. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/jdk_exports.py +0 -0
  112. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/license.py +0 -0
  113. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/__init__.py +0 -0
  114. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  115. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  116. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  117. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  118. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  119. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/orchestrator.py +0 -0
  120. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/registry.py +0 -0
  121. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/runner.py +0 -0
  122. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/server.py +0 -0
  123. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp_nudge.py +0 -0
  124. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/metrics_analyzer.py +0 -0
  125. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/migrate_check.py +0 -0
  126. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/migration_blast.py +0 -0
  127. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/openapi_surface.py +0 -0
  128. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/output_budget.py +0 -0
  129. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/parse_cache.py +0 -0
  130. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/path_admission.py +0 -0
  131. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/path_filters.py +0 -0
  132. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/perf.py +0 -0
  133. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/pipe_contract.py +0 -0
  134. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/pr_comment_renderer.py +0 -0
  135. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/pr_impact.py +0 -0
  136. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/prepare_context.py +0 -0
  137. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/progress.py +0 -0
  138. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/ranking_engine.py +0 -0
  139. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/readiness_timeline.py +0 -0
  140. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/reconciliation.py +0 -0
  141. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/redactor.py +0 -0
  142. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/reference_facts.py +0 -0
  143. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/release_info.py +0 -0
  144. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/relevance_scorer.py +0 -0
  145. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/remedies.py +0 -0
  146. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/rename_refactor.py +0 -0
  147. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/repo_classifier.py +0 -0
  148. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/__init__.py +0 -0
  149. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/context.py +0 -0
  150. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/errors.py +0 -0
  151. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/executor.py +0 -0
  152. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/planner.py +0 -0
  153. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/query.py +0 -0
  154. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/request.py +0 -0
  155. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/resolution.py +0 -0
  156. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/result.py +0 -0
  157. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/retriever.py +0 -0
  158. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/runtime.py +0 -0
  159. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps.py +0 -0
  160. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  161. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
  162. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
  163. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
  164. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
  165. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  166. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/ris.py +0 -0
  167. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/rule_catalog.py +0 -0
  168. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/runtime_classifier.py +0 -0
  169. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/scanner.py +0 -0
  170. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/schema.py +0 -0
  171. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
  172. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/security_config.py +0 -0
  173. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/security_config_scan.py +0 -0
  174. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/security_posture.py +0 -0
  175. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_analyzer.py +0 -0
  176. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_impact_engine.py +0 -0
  177. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_integration_engine.py +0 -0
  178. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_services.py +0 -0
  179. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/serializer.py +0 -0
  180. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_event_topology.py +0 -0
  181. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_findings.py +0 -0
  182. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_impact.py +0 -0
  183. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_model.py +0 -0
  184. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_profiles.py +0 -0
  185. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_properties.py +0 -0
  186. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_security_audit.py +0 -0
  187. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_semantic.py +0 -0
  188. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
  189. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/summarizer.py +0 -0
  190. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/target_admission.py +0 -0
  191. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/__init__.py +0 -0
  192. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/config.py +0 -0
  193. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/consent.py +0 -0
  194. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/events.py +0 -0
  195. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/filters.py +0 -0
  196. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/transport.py +0 -0
  197. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/test_gap_ranking.py +0 -0
  198. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/test_sources.py +0 -0
  199. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/token_estimate.py +0 -0
  200. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/tree_utils.py +0 -0
  201. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/type_usage_surface.py +0 -0
  202. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/validation_surface.py +0 -0
  203. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/verify_edit.py +0 -0
  204. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/verify_rules.py +0 -0
  205. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/version_check.py +0 -0
  206. {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/workspace.py +0 -0
  207. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/README.md +0 -0
  208. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/get-license/index.ts +0 -0
  209. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  210. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/telemetry/index.ts +0 -0
  211. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/sql/license_event_ordering.sql +0 -0
  212. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/sql/licensing_schema.sql +0 -0
  213. {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/sql/telemetry_events.sql +0 -0
@@ -2,6 +2,188 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ### Added
6
+
7
+ - **`ask migrate-recipe` — the migration report in the form the executor takes**
8
+ (roadmap M10.5 item 5 / M8.5, experimental). `migrate-check` already names the
9
+ OpenRewrite recipe each finding carries (296 of 309 on openmrs-core) and a reader
10
+ still had to copy them out of a JSON payload by hand — field evaluation #4's verdict
11
+ on that gap was *"el informe muere en un cajón; el codemod se convierte en PRs"*. The
12
+ command emits the declarative composite recipe naming exactly those recipes, the
13
+ artifact coordinates derived from their packages, and the invocation for the build the
14
+ repository declares (Maven or Gradle). It writes nothing without `--write`, so an audit
15
+ of somebody else's repository can run it; `--write` refuses to replace an existing
16
+ `rewrite.yml` without `--force`. **Nothing here edits source** — that is NC-005's
17
+ position, not a gap: OpenRewrite is the executor and this is its input.
18
+ - The recipe list comes from the findings, never from a catalogue of what OpenRewrite
19
+ can do: a recipe nobody's finding asked for would rewrite code nobody measured.
20
+ - Every finding with no recipe is published under `manual_remainder`. Measured on
21
+ BroadleafCommerce: **25 blocking findings in product code and not one automatable**,
22
+ which is an answer, not an empty result — and the reason an empty recipe list prints
23
+ *no* runnable command, because `mvn … rewrite:run` over nothing is a green executor
24
+ run that reads as "the migration is automated".
25
+ - Advisory hygiene is excluded by default (`--include-hygiene` opts in): on openmrs-core
26
+ it takes the population from 125 findings to 309 and adds `JavaTimeAPIs`, and a
27
+ migration diff that also modernises date handling cannot be reviewed as one change.
28
+ - The coverage block names **both** populations — its own and `migrate-check`'s narrower
29
+ `blocking_count` (125 against 114 on openmrs-core) — because two populations under one
30
+ name is the defect this project keeps finding in its own output.
31
+
32
+ ## [4.3.0] — 2026-08-03
33
+
34
+ Minor, not a patch: two commands are new (`ask enrich`, `ask data-exposure`), the
35
+ composed risk model gains two factors, and `ask verify` writes a file where it
36
+ wrote none — every one of them additive, none of them removing a published field
37
+ or moving an exit code. A pipeline that reads this release the way it read 4.2.0
38
+ gets the same answers, plus blocks it can ignore.
39
+
40
+ ### Added
41
+
42
+ - **`ask baseline capture --auto` — an architectural history that does not depend on
43
+ somebody remembering** (roadmap M10.5, head of the milestone). The snapshot has
44
+ shipped since D5; the *series* is the asset a competitor cannot backfill, and in
45
+ every repository measured so far its length is zero, because capture is a command a
46
+ human has to type. `--auto` is the form a pipeline can keep: it captures one baseline
47
+ per commit, keeps an already-captured commit instead of relabelling it, refuses to
48
+ file a tree with uncommitted changes under the commit it would be stored as, and
49
+ **exits 0 whatever happens** — a build never goes red because a snapshot could not be
50
+ taken. Every outcome names itself (`captured` / `skipped` with the reason and a
51
+ sentence of effect), so a pipeline log says which happened rather than going quiet.
52
+ A skip costs no analysis: the decision is taken before the IR is built, so the common
53
+ case in a per-push job is ~0.2 s against 1.8 s for a capture. New authority
54
+ `sourcecode/baseline_autocapture.py`; `docs/baseline-ci.yml` now captures per merge
55
+ as well as per tag.
56
+ - **`ask data-exposure` — which routes can carry the data you labelled, and who
57
+ reaches them** (roadmap M10.5 item 3, experimental). Nothing here detects sensitive
58
+ data: a label is a judgement about a domain, a field named `dni` is a national
59
+ identifier in one repository and a column name in another, and the engine never
60
+ branches on a name (VAI). It is declared once under `dataLabels` in
61
+ `sourcecode.config.json`; everything after that is measured over authorities that
62
+ already exist — the call reach `impact-chain` walks, the endpoint security surface
63
+ `risk` weighs, the profile resolution `posture` publishes (`--profile`). Two evidence
64
+ classes, published apart and never added together: `signature` (the handler names the
65
+ labelled type in its own signature) and `call_reach` (the chain reaches it — a
66
+ supremum, not a proof, because the mapping in between is not modelled: NC-008).
67
+ Measured: petclinic labelling `Owner#telephone` → **7 routes by signature**;
68
+ BroadleafCommerce labelling `Customer` → **6 by call reach and none by signature**,
69
+ because those controllers return view names. A repository that declared nothing is
70
+ `answered: false`, never zero exposed routes, and a declared type the graph never
71
+ resolved is named with the note that this is not evidence it is unexposed.
72
+ - **A request handler declares types too.** `_extract_class_type_refs` enumerated
73
+ `symbol_kind == "method"`, and a handler is classified `endpoint` at emission (a
74
+ factory method `bean`), so the class-scope type surface contained **no controller
75
+ signature anywhere in a repository**: `structural_references_to_type("Owner")` on
76
+ petclinic returned 3 atoms, none of them a route that takes an `Owner` as its request
77
+ body, and "which routes accept or return this type" answered nothing while looking
78
+ like an answer. Now 10 atoms, 7 of them handler signatures. Same shape as the F.4-1
79
+ body-surface seam, one scope up; `member_kind` still publishes the kind the symbol was
80
+ classified with.
81
+ - **The history answers from the repository path.** `ask trend .` and
82
+ `ask baseline trend .` now take either a repository or a directory of baselines, and
83
+ `ask baseline diff .` defaults to the newest point in that repository's own history
84
+ instead of requiring `--baseline <file>`. Capture writes to `<repo>/.ask/baselines`,
85
+ so making the reader name the storage directory was the same friction that kept the
86
+ series empty. An explicit directory (the `--dir` case) is unchanged, and a repository
87
+ with no history gets an error that names how to start one. New
88
+ `architectural_baseline.latest_baseline_path`, ordered exactly as the trend series is
89
+ ordered so "the last point" and "the base of a default diff" cannot disagree.
90
+ - **`ask verify` carries the history for free.** The gate is the run that already happens
91
+ on every push and already builds the IR a baseline is extracted from, so where a
92
+ repository keeps `.ask/baselines` the gate adds the current commit to it and publishes
93
+ what it did under `architectural_history` — on every run, including the ones that
94
+ captured nothing, because a series that silently stopped growing is invisible until the
95
+ day somebody needs it (I-8). Measured on BroadleafCommerce: 3.9 s with the capture
96
+ against 4.0 s without, i.e. inside the noise; eureka 1.8 s against 0.8 s (its IR is
97
+ smaller, the extraction is not). The passenger cannot move the gate: the verdict, the
98
+ exit code and every other field are identical with and without it, and an exception
99
+ inside it is swallowed. `ASK_BASELINE_AUTOCAPTURE=0/1` overrides in both directions.
100
+ - ⚠One measured cost stated rather than hidden: a baseline is ~730 KB on a 3 300-file
101
+ monolith, because it stores the full endpoint surface and fan-in map so a later
102
+ `baseline diff` is faithful. A point per merge is a megabyte-scale history; a point
103
+ per release is not. `--dir` sends them outside the repository.
104
+ - ⚠Found by the battery, not by the field: the first capture writes an untracked file
105
+ **inside the repository**, so a plain `git status --porcelain` check would have
106
+ reported a dirty tree from then on and every later run would have skipped — a
107
+ history of exactly one. The dirtiness question excludes this tool's own footprint
108
+ (`.ask/`) and nothing else, because everything else is what the baseline measures —
109
+ and the second half of that came from eureka, where `verify --init` writes
110
+ `.ask/contracts.yml` and, counted as a modification, would stop the history from
111
+ ever starting.
112
+ - **`ask enrich --sarif <log>` — somebody else's detection, ranked by what this
113
+ repository does with it** (roadmap M10, first deliverable). This product does not
114
+ detect injection, CVEs or secrets and says so in every security payload (NC-001,
115
+ NC-002); the scanners that do have no bean graph, no profile model and no endpoint
116
+ id they share with anything, so their output is a list nobody can order. `enrich`
117
+ reads a SARIF 2.1.0 log from Semgrep, CodeQL or Trivy and runs the **same
118
+ composition** `ask risk` runs over each finding — same axes, same weights, same
119
+ `RiskComposer` — with one difference: `defect_severity` is the scanner's own
120
+ verdict (`security-severity` when the tool published one, `level` otherwise),
121
+ carried through with the scanner named as its authority. Nothing re-rates,
122
+ confirms or contradicts a finding. Results sharing (tool, rule, symbol) are one
123
+ defect with several witnesses; a result the join could not place — a file outside
124
+ the population this build read, a line with no declaration above it — is published
125
+ under `unresolved` with the reason, never dropped.
126
+ - **The CVE half of the same command: a dependency finding is joined through the
127
+ coordinate, not through a line.** A result located on `pom.xml` or
128
+ `build.gradle` is about a library, so the coordinate is read back out of the
129
+ manifest the scanner named and the reach is the worst of the types that import
130
+ it — *of forty vulnerable dependencies, which ones does an unauthenticated route
131
+ actually reach?* Importers are found from the IR's existing `imports` edges, by
132
+ the coordinate's group id or by its artifact id as a package segment, and each
133
+ row publishes which basis found them. A library nothing imports is `unresolved`
134
+ and never "unreachable": reflection, a service loader and use through another
135
+ dependency all leave no import edge. Both kinds rank in one list, because a CVE
136
+ in a reachable library and an injection finding in a handler are the same
137
+ question to whoever decides what to fix first.
138
+ - **`--profile <set>` on `ask risk` and `ask enrich` — profile context per finding**
139
+ (M10 exit criterion). The access axis stops answering for *the repository as
140
+ configured* and answers for *that deployment*: `posture` resolves the conditional
141
+ bean graph and the request chain under the named set, through a new published
142
+ seam (`posture.endpoint_access_under`, `posture.access_verdict`), so a composed
143
+ row and a `posture` run can never disagree about the same profile set. A decision
144
+ resolves an endpoint the repository-wide surface left at `coverage_unknown`, in
145
+ either direction — measured on a fixture, one defect scores 11.52/`open` under
146
+ `dev`, 8.06/`unknown` with no set named, and 5.76/`protected` under `prod`. When
147
+ both authorities decided, the worse of them wins, per endpoint.
148
+ - **`ask risk` gains a fifth factor: `query_construction`** (roadmap F.4-1). The
149
+ field asked the question this answers the structural half of — *"con 618 HQL
150
+ concatenados, ¿alguno concatena entrada de request?"* Following request input to
151
+ a query is dataflow, is declared out of scope in NC-001, and stays there. What
152
+ is publishable without it is the adjacency: this defect's own code assembles a
153
+ query string by concatenation, and the four factors beside it already say whether
154
+ that code is reachable, unauthenticated and writing. Read from the α
155
+ argument-shape atoms the IR already carries (`dynamic_argument_surface`) — no new
156
+ analysis, one pass, joined per defect. `not_observed` means the shape was absent
157
+ from the body facts; it is never a claim that a query is safely parameterised.
158
+ - **…and a sixth: `input_constraints`** — the other half of the same field question
159
+ (*"1 201 bodies sin validación"*). Joined by route against `validation`'s gap
160
+ list: `absent` means one of the endpoints reaching this defect accepts a request
161
+ body with no declared constraint, taking the worst of the reached routes for the
162
+ reason the auth axis does. `ask risk` now publishes the `non_coverage` block too,
163
+ because two axes describing the input path, composed with an open access verdict,
164
+ read as *injection* unless the payload states that no dataflow was followed.
165
+
166
+ ### Fixed
167
+
168
+ - **`validation` counted handlers that take no argument as body endpoints.** The
169
+ body surface was the verb alone (POST/PUT/PATCH) and the declared limitation said
170
+ the parameter list was not captured. It is now captured (`_handler_params`) and
171
+ read in the negative direction only: an empty parameter list proves no body can
172
+ bind. A handler whose parameters are all path or query values still counts, and
173
+ the limitation says so.
174
+
175
+ - **The α argument-shape surface was blind to every controller body.**
176
+ `dynamic_argument_surface` walked `kind="method"` and `kind="constructor"` symbol
177
+ nodes; a request handler is a `kind="endpoint"` node. The owner population is now
178
+ the body-fact layer's own (`ContextGraph.body_owners()`).
179
+
180
+ ### Changed
181
+
182
+ - `severity_effective` in `ask risk` can now be larger for a row whose code
183
+ concatenates a query. Every factor's neutral value is 1.0, so a new axis only
184
+ ever moves a row **up**: no band a reader has already acted on is demoted by
185
+ this release.
186
+
5
187
  ## [4.2.0] — 2026-08-03
6
188
 
7
189
  Minor, not a patch, by this project's own criterion: two published figures move
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 4.2.0
3
+ Version: 4.3.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
@@ -160,8 +160,8 @@ ask verify /path/to/repo --init
160
160
  # writes nothing — the form an audit of somebody else's repository can run.
161
161
  ask verify /path/to/repo --init --dry-run
162
162
 
163
- # What each defect actually costs once reach, access and write effect are in it:
164
- # severity × reachability × auth_verdict × write_effect, ordered, every factor traceable.
163
+ # What each defect actually costs once reach, access, write effect and the shape of
164
+ # the input path are in it ordered, every factor traceable to the command that owns it.
165
165
  ask risk /path/to/repo
166
166
  ```
167
167
 
@@ -254,12 +254,16 @@ guesses is a confident security falsehood — the worst failure mode this tool h
254
254
  ### 5c · Composed Risk *(experimental)*
255
255
  Every command above answers one axis, and a reader composes them by hand. `ask risk` does the
256
256
  join over the endpoint and symbol ids these commands already share with each other:
257
- `severity_effective = defect_severity × reachability × auth_verdict × write_effect`. The
258
- product of the published factors **is** the published score — decomposable to the four
257
+ `severity_effective = defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`. The
258
+ product of the published factors **is** the published score — decomposable to the six
259
259
  figures and the authority behind each — and an axis this build cannot measure is `unknown`,
260
260
  weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
261
261
  field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
262
262
  **high (8.06)** once *reachable unauthenticated* and *writes to the database* are in it.
263
+ The last two factors describe the input path — a query assembled by concatenation, a route
264
+ accepting a body with no declared constraint. They are **adjacencies, not dataflow**: no
265
+ value is followed from a request to a sink, which is `NC-001` and is published in the
266
+ payload's own `non_coverage` block.
263
267
  `ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
264
268
  → [reference](docs/USER_GUIDE.md)
265
269
 
@@ -285,7 +289,7 @@ experimental: both are true, and they are two different facts.
285
289
  |---|---|---|
286
290
  | **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
287
291
  | **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
288
- | **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `posture` · `archetype` |
292
+ | **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
289
293
  | **parked** | kept working, no longer developed | `retrieve` |
290
294
 
291
295
  The same table is printed by `ask --help`, and both are generated from one authority
@@ -302,7 +306,10 @@ from it.
302
306
  | Command | Tier | Answers | Note |
303
307
  |---|---|---|---|
304
308
  | `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
305
- | `risk` | experimental | what each defect actually costs, once reach, access and write effect are in it | `defect_severity × reachability × auth_verdict × write_effect`; every factor names its authority |
309
+ | `risk` | experimental | what each defect actually costs, once reach, access, write effect and the shape of the input path are in it | `defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`; every factor names its authority |
310
+ | `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`; the same composition as `risk`, with the scanner as the severity authority |
311
+ | `migrate-recipe` | experimental | the migration report as the OpenRewrite recipe that applies it | only recipes a finding named; the manual remainder published beside them; writes nothing without `--write`, and never a runnable command for an empty recipe list |
312
+ | `data-exposure` | experimental | which routes can carry the data you labelled, and who reaches them | labels declared in `sourcecode.config.json` — never inferred from a name; `signature` and `call_reach` evidence published apart, field-level flow out of scope (NC-008) |
306
313
  | `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators) |
307
314
  | `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment` |
308
315
  | `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan |
@@ -317,7 +324,7 @@ from it.
317
324
  | `review-pr` / `fix-bug` / `prepare-context` | supported | diff review, symptom triage, task-shaped context | |
318
325
  | `plan` / `compare` / `delta` / `contract-diff` | supported | what to review for a change; candidates by measured cost; outcome of a change; public-contract break | no verdicts, measured cost only |
319
326
  | `validation` | supported | request-body validation coverage and gaps | |
320
- | `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend <dir>` reads the series | trend reporting, not gating. Baselines land in `.ask/baselines` **inside the repository** — the history travels with the code, not with a vendor; an audit that must not write passes `--dir`. Automate it: [baseline-ci.yml](docs/baseline-ci.yml) |
327
+ | `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend .` reads the series (a repository path or a baselines directory), `ask baseline diff .` compares the tree against its newest point | trend reporting, not gating. Baselines land in `.ask/baselines` **inside the repository** — the history travels with the code, not with a vendor; an audit that must not write passes `--dir`. `capture --auto` is the unattended form (one baseline per commit, never rewrites one, never fails the build) — automate it: [baseline-ci.yml](docs/baseline-ci.yml) |
321
328
  | `retrieve` | parked | typed knowledge queries over the model | |
322
329
  | `archetype` | experimental | evidence-based architectural archetype | |
323
330
  | `rename-class` / `chunk-file` | supported | word-boundary Java rename; split a large file for an agent | |
@@ -368,6 +375,18 @@ And one about the endpoint surface itself:
368
375
  |---|---|---|
369
376
  | **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
377
 
378
+ And one about labelled data:
379
+
380
+ | Not covered | Why | What answers it |
381
+ |---|---|---|
382
+ | **Whether a labelled member actually leaves the process on a given route — field-level dataflow through mappers, DTOs, serializers and projections.** | Exposure here is measured at TYPE granularity over the same call reach every other command walks: a route reaches the labelled type, or its signature names it. Whether the mapping in between keeps the labelled member is a dataflow question, and answering it by approximation would put a confident `no` on a route that does leak. So `call_reach` is published as a supremum and says so. | Read the mapping on the routes this answer ranks first — they are the ones worth a human — and label the DTO too if it carries the member, which makes the route `signature` instead of `call_reach`. |
383
+
384
+ And one about who calls a route:
385
+
386
+ | Not covered | Why | What answers it |
387
+ |---|---|---|
388
+ | **Whether a route is called from outside this repository — another service, a mobile app, a partner, a cron job, or a client whose URL is assembled at run time.** | The join reads the TypeScript/JavaScript checked in beside the server and only the call shapes whose verb and path are written at the call site. That is a floor on who calls a route and can never be a ceiling: the repository cannot observe consumers it does not contain. So a route with no call site here is published as a candidate for deletion, never as dead API. | Access logs or an API gateway answer who really calls a route. The opposite direction is decisive without them: a client call matching no route is a request this repository's own front end makes and its server does not serve. |
389
+
371
390
  **Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
372
391
  must change, what each change reaches, and what a gate should block — and it removes none of
373
392
  it. Field evaluation scored it 7/10 as a report generator and 5.5/10 as a development tool,
@@ -122,8 +122,8 @@ ask verify /path/to/repo --init
122
122
  # writes nothing — the form an audit of somebody else's repository can run.
123
123
  ask verify /path/to/repo --init --dry-run
124
124
 
125
- # What each defect actually costs once reach, access and write effect are in it:
126
- # severity × reachability × auth_verdict × write_effect, ordered, every factor traceable.
125
+ # What each defect actually costs once reach, access, write effect and the shape of
126
+ # the input path are in it ordered, every factor traceable to the command that owns it.
127
127
  ask risk /path/to/repo
128
128
  ```
129
129
 
@@ -216,12 +216,16 @@ guesses is a confident security falsehood — the worst failure mode this tool h
216
216
  ### 5c · Composed Risk *(experimental)*
217
217
  Every command above answers one axis, and a reader composes them by hand. `ask risk` does the
218
218
  join over the endpoint and symbol ids these commands already share with each other:
219
- `severity_effective = defect_severity × reachability × auth_verdict × write_effect`. The
220
- product of the published factors **is** the published score — decomposable to the four
219
+ `severity_effective = defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`. The
220
+ product of the published factors **is** the published score — decomposable to the six
221
221
  figures and the authority behind each — and an axis this build cannot measure is `unknown`,
222
222
  weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
223
223
  field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
224
224
  **high (8.06)** once *reachable unauthenticated* and *writes to the database* are in it.
225
+ The last two factors describe the input path — a query assembled by concatenation, a route
226
+ accepting a body with no declared constraint. They are **adjacencies, not dataflow**: no
227
+ value is followed from a request to a sink, which is `NC-001` and is published in the
228
+ payload's own `non_coverage` block.
225
229
  `ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
226
230
  → [reference](docs/USER_GUIDE.md)
227
231
 
@@ -247,7 +251,7 @@ experimental: both are true, and they are two different facts.
247
251
  |---|---|---|
248
252
  | **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
249
253
  | **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
250
- | **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `posture` · `archetype` |
254
+ | **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
251
255
  | **parked** | kept working, no longer developed | `retrieve` |
252
256
 
253
257
  The same table is printed by `ask --help`, and both are generated from one authority
@@ -264,7 +268,10 @@ from it.
264
268
  | Command | Tier | Answers | Note |
265
269
  |---|---|---|---|
266
270
  | `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
267
- | `risk` | experimental | what each defect actually costs, once reach, access and write effect are in it | `defect_severity × reachability × auth_verdict × write_effect`; every factor names its authority |
271
+ | `risk` | experimental | what each defect actually costs, once reach, access, write effect and the shape of the input path are in it | `defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`; every factor names its authority |
272
+ | `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`; the same composition as `risk`, with the scanner as the severity authority |
273
+ | `migrate-recipe` | experimental | the migration report as the OpenRewrite recipe that applies it | only recipes a finding named; the manual remainder published beside them; writes nothing without `--write`, and never a runnable command for an empty recipe list |
274
+ | `data-exposure` | experimental | which routes can carry the data you labelled, and who reaches them | labels declared in `sourcecode.config.json` — never inferred from a name; `signature` and `call_reach` evidence published apart, field-level flow out of scope (NC-008) |
268
275
  | `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators) |
269
276
  | `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment` |
270
277
  | `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan |
@@ -279,7 +286,7 @@ from it.
279
286
  | `review-pr` / `fix-bug` / `prepare-context` | supported | diff review, symptom triage, task-shaped context | |
280
287
  | `plan` / `compare` / `delta` / `contract-diff` | supported | what to review for a change; candidates by measured cost; outcome of a change; public-contract break | no verdicts, measured cost only |
281
288
  | `validation` | supported | request-body validation coverage and gaps | |
282
- | `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend <dir>` reads the series | trend reporting, not gating. Baselines land in `.ask/baselines` **inside the repository** — the history travels with the code, not with a vendor; an audit that must not write passes `--dir`. Automate it: [baseline-ci.yml](docs/baseline-ci.yml) |
289
+ | `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend .` reads the series (a repository path or a baselines directory), `ask baseline diff .` compares the tree against its newest point | trend reporting, not gating. Baselines land in `.ask/baselines` **inside the repository** — the history travels with the code, not with a vendor; an audit that must not write passes `--dir`. `capture --auto` is the unattended form (one baseline per commit, never rewrites one, never fails the build) — automate it: [baseline-ci.yml](docs/baseline-ci.yml) |
283
290
  | `retrieve` | parked | typed knowledge queries over the model | |
284
291
  | `archetype` | experimental | evidence-based architectural archetype | |
285
292
  | `rename-class` / `chunk-file` | supported | word-boundary Java rename; split a large file for an agent | |
@@ -330,6 +337,18 @@ And one about the endpoint surface itself:
330
337
  |---|---|---|
331
338
  | **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
339
 
340
+ And one about labelled data:
341
+
342
+ | Not covered | Why | What answers it |
343
+ |---|---|---|
344
+ | **Whether a labelled member actually leaves the process on a given route — field-level dataflow through mappers, DTOs, serializers and projections.** | Exposure here is measured at TYPE granularity over the same call reach every other command walks: a route reaches the labelled type, or its signature names it. Whether the mapping in between keeps the labelled member is a dataflow question, and answering it by approximation would put a confident `no` on a route that does leak. So `call_reach` is published as a supremum and says so. | Read the mapping on the routes this answer ranks first — they are the ones worth a human — and label the DTO too if it carries the member, which makes the route `signature` instead of `call_reach`. |
345
+
346
+ And one about who calls a route:
347
+
348
+ | Not covered | Why | What answers it |
349
+ |---|---|---|
350
+ | **Whether a route is called from outside this repository — another service, a mobile app, a partner, a cron job, or a client whose URL is assembled at run time.** | The join reads the TypeScript/JavaScript checked in beside the server and only the call shapes whose verb and path are written at the call site. That is a floor on who calls a route and can never be a ceiling: the repository cannot observe consumers it does not contain. So a route with no call site here is published as a candidate for deletion, never as dead API. | Access logs or an API gateway answer who really calls a route. The opposite direction is decisive without them: a client call matching no route is a request this repository's own front end makes and its server does not serve. |
351
+
333
352
  **Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
334
353
  must change, what each change reaches, and what a gate should block — and it removes none of
335
354
  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.2.0"
7
+ version = "4.3.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.2.0"
7
+ __version__ = "4.3.0"
@@ -312,6 +312,25 @@ def load_baseline(path: Path) -> dict:
312
312
  return data
313
313
 
314
314
 
315
+ def latest_baseline_path(directory: Path) -> "Path | None":
316
+ """The most recently captured baseline in `directory`, or None if there is none.
317
+
318
+ Ordered exactly as `load_baselines_dir` orders its series (capture time, commit
319
+ as the tie-break), so "the last point in the trend" and "the base a diff uses by
320
+ default" can never disagree about which artifact that is.
321
+ """
322
+ dated: list[tuple[str, str, Path]] = []
323
+ for p in sorted(Path(directory).glob("*.json")):
324
+ try:
325
+ b = load_baseline(p)
326
+ except (OSError, ValueError, json.JSONDecodeError):
327
+ continue
328
+ dated.append((str(b.get("captured_at", "")), str(b.get("commit", "")), p))
329
+ if not dated:
330
+ return None
331
+ return max(dated, key=lambda t: (t[0], t[1]))[2]
332
+
333
+
315
334
  def load_baselines_dir(directory: Path) -> list[dict]:
316
335
  """Load every architectural baseline in `directory`, sorted by capture time."""
317
336
  out: list[dict] = []