sourcecode 4.1.0__tar.gz → 4.5.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 (214) hide show
  1. {sourcecode-4.1.0 → sourcecode-4.5.0}/CHANGELOG.md +409 -0
  2. {sourcecode-4.1.0 → sourcecode-4.5.0}/PKG-INFO +48 -8
  3. {sourcecode-4.1.0 → sourcecode-4.5.0}/README.md +47 -7
  4. {sourcecode-4.1.0 → sourcecode-4.5.0}/pyproject.toml +1 -1
  5. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/__init__.py +1 -1
  6. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/architectural_baseline.py +19 -0
  7. sourcecode-4.5.0/src/sourcecode/baseline_autocapture.py +375 -0
  8. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/cache_model.py +19 -0
  9. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/caller_reach.py +16 -7
  10. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/canonical_ir.py +29 -0
  11. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/cli.py +801 -26
  12. sourcecode-4.5.0/src/sourcecode/client_calls.py +305 -0
  13. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/context_graph.py +11 -0
  14. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/contract_diff.py +5 -4
  15. sourcecode-4.5.0/src/sourcecode/data_exposure.py +353 -0
  16. sourcecode-4.5.0/src/sourcecode/data_labels.py +200 -0
  17. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/dynamic_argument_surface.py +12 -5
  18. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/envelope.py +35 -0
  19. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/environment_resolution.py +100 -6
  20. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/facts/registry.json +15 -0
  21. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/format_contract.py +1 -0
  22. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/git_checkout.py +5 -2
  23. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/non_coverage.py +71 -0
  24. sourcecode-4.5.0/src/sourcecode/openrewrite_recipe.py +278 -0
  25. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/path_filters.py +13 -0
  26. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/posture.py +425 -7
  27. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/remedies.py +30 -1
  28. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/repository_ir.py +24 -3
  29. sourcecode-4.5.0/src/sourcecode/risk.py +764 -0
  30. sourcecode-4.5.0/src/sourcecode/sarif.py +618 -0
  31. sourcecode-4.5.0/src/sourcecode/servlet_surface.py +194 -0
  32. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_impact.py +14 -3
  33. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/test_sources.py +15 -2
  34. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/validation_inference.py +33 -4
  35. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/verify_repo.py +22 -2
  36. sourcecode-4.1.0/src/sourcecode/risk.py +0 -345
  37. {sourcecode-4.1.0 → sourcecode-4.5.0}/.github/workflows/build-windows.yml +0 -0
  38. {sourcecode-4.1.0 → sourcecode-4.5.0}/.gitignore +0 -0
  39. {sourcecode-4.1.0 → sourcecode-4.5.0}/.ruff.toml +0 -0
  40. {sourcecode-4.1.0 → sourcecode-4.5.0}/CONTRIBUTING.md +0 -0
  41. {sourcecode-4.1.0 → sourcecode-4.5.0}/LICENSE +0 -0
  42. {sourcecode-4.1.0 → sourcecode-4.5.0}/SECURITY.md +0 -0
  43. {sourcecode-4.1.0 → sourcecode-4.5.0}/raw +0 -0
  44. {sourcecode-4.1.0 → sourcecode-4.5.0}/scripts/compare_integration_engines.py +0 -0
  45. {sourcecode-4.1.0 → sourcecode-4.5.0}/scripts/customer_smoke_test.sh +0 -0
  46. {sourcecode-4.1.0 → sourcecode-4.5.0}/scripts/generate_jdk_exports.py +0 -0
  47. {sourcecode-4.1.0 → sourcecode-4.5.0}/scripts/perf_harness.py +0 -0
  48. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/adaptive_scanner.py +0 -0
  49. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/archetype.py +0 -0
  50. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/architectural_delta.py +0 -0
  51. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/architecture_analyzer.py +0 -0
  52. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/architecture_summary.py +0 -0
  53. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/ast_extractor.py +0 -0
  54. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/cache.py +0 -0
  55. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/call_surface.py +0 -0
  56. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/caller_metrics.py +0 -0
  57. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/chain_rules.py +0 -0
  58. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/change_plan.py +0 -0
  59. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/cir_graphs.py +0 -0
  60. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/classifier.py +0 -0
  61. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/code_notes_analyzer.py +0 -0
  62. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/compare.py +0 -0
  63. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/confidence_analyzer.py +0 -0
  64. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/constraint_diff.py +0 -0
  65. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/context_cache.py +0 -0
  66. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/context_scorer.py +0 -0
  67. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/context_summarizer.py +0 -0
  68. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/contract_init.py +0 -0
  69. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/contract_model.py +0 -0
  70. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/contract_pipeline.py +0 -0
  71. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/coverage_parser.py +0 -0
  72. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/defect_identity.py +0 -0
  73. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/degradation.py +0 -0
  74. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/dependency_analyzer.py +0 -0
  75. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/deployment_prefix.py +0 -0
  76. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/__init__.py +0 -0
  77. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/base.py +0 -0
  78. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
  79. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/dart.py +0 -0
  80. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/dotnet.py +0 -0
  81. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/elixir.py +0 -0
  82. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/go.py +0 -0
  83. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/heuristic.py +0 -0
  84. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/hybrid.py +0 -0
  85. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/java.py +0 -0
  86. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  87. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/nodejs.py +0 -0
  88. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/parsers.py +0 -0
  89. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/php.py +0 -0
  90. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/project.py +0 -0
  91. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/python.py +0 -0
  92. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/ruby.py +0 -0
  93. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/rust.py +0 -0
  94. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/systems.py +0 -0
  95. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/terraform.py +0 -0
  96. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/detectors/tooling.py +0 -0
  97. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/doc_analyzer.py +0 -0
  98. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/endpoint_literals.py +0 -0
  99. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/endpoint_metrics.py +0 -0
  100. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/entrypoint_classifier.py +0 -0
  101. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/env_analyzer.py +0 -0
  102. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/error_schema.py +0 -0
  103. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/evidence_provider.py +0 -0
  104. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/explain.py +0 -0
  105. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/facts/__init__.py +0 -0
  106. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/file_chunker.py +0 -0
  107. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/file_classifier.py +0 -0
  108. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/filter_surface.py +0 -0
  109. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/fqn_utils.py +0 -0
  110. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/git_analyzer.py +0 -0
  111. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/graph_analyzer.py +0 -0
  112. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/graph_evidence.py +0 -0
  113. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/hibernate_strat.py +0 -0
  114. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/identity_fallback.py +0 -0
  115. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/integration_coordinates.py +0 -0
  116. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/jdk_exports.py +0 -0
  117. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/license.py +0 -0
  118. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/__init__.py +0 -0
  119. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  120. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  121. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  122. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  123. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  124. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/orchestrator.py +0 -0
  125. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/registry.py +0 -0
  126. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/runner.py +0 -0
  127. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp/server.py +0 -0
  128. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/mcp_nudge.py +0 -0
  129. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/metrics_analyzer.py +0 -0
  130. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/migrate_check.py +0 -0
  131. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/migration_blast.py +0 -0
  132. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/openapi_surface.py +0 -0
  133. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/output_budget.py +0 -0
  134. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/parse_cache.py +0 -0
  135. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/path_admission.py +0 -0
  136. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/perf.py +0 -0
  137. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/pipe_contract.py +0 -0
  138. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/pr_comment_renderer.py +0 -0
  139. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/pr_impact.py +0 -0
  140. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/prepare_context.py +0 -0
  141. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/progress.py +0 -0
  142. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/ranking_engine.py +0 -0
  143. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/readiness_timeline.py +0 -0
  144. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/reconciliation.py +0 -0
  145. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/redactor.py +0 -0
  146. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/reference_facts.py +0 -0
  147. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/release_info.py +0 -0
  148. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/relevance_scorer.py +0 -0
  149. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/rename_refactor.py +0 -0
  150. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/repo_classifier.py +0 -0
  151. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/__init__.py +0 -0
  152. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/context.py +0 -0
  153. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/errors.py +0 -0
  154. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/executor.py +0 -0
  155. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/planner.py +0 -0
  156. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/query.py +0 -0
  157. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/request.py +0 -0
  158. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/resolution.py +0 -0
  159. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/result.py +0 -0
  160. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/retriever.py +0 -0
  161. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/runtime.py +0 -0
  162. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps.py +0 -0
  163. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  164. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
  165. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
  166. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
  167. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
  168. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  169. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/ris.py +0 -0
  170. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/rule_catalog.py +0 -0
  171. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/runtime_classifier.py +0 -0
  172. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/scanner.py +0 -0
  173. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/schema.py +0 -0
  174. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
  175. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/security_config.py +0 -0
  176. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/security_config_scan.py +0 -0
  177. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/security_posture.py +0 -0
  178. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/semantic_analyzer.py +0 -0
  179. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/semantic_impact_engine.py +0 -0
  180. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/semantic_integration_engine.py +0 -0
  181. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/semantic_services.py +0 -0
  182. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/serializer.py +0 -0
  183. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_event_topology.py +0 -0
  184. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_findings.py +0 -0
  185. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_model.py +0 -0
  186. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_profiles.py +0 -0
  187. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_properties.py +0 -0
  188. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_security_audit.py +0 -0
  189. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_semantic.py +0 -0
  190. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
  191. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/summarizer.py +0 -0
  192. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/target_admission.py +0 -0
  193. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/telemetry/__init__.py +0 -0
  194. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/telemetry/config.py +0 -0
  195. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/telemetry/consent.py +0 -0
  196. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/telemetry/events.py +0 -0
  197. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/telemetry/filters.py +0 -0
  198. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/telemetry/transport.py +0 -0
  199. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/test_gap_ranking.py +0 -0
  200. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/token_estimate.py +0 -0
  201. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/tree_utils.py +0 -0
  202. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/type_usage_surface.py +0 -0
  203. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/validation_surface.py +0 -0
  204. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/verify_edit.py +0 -0
  205. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/verify_rules.py +0 -0
  206. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/version_check.py +0 -0
  207. {sourcecode-4.1.0 → sourcecode-4.5.0}/src/sourcecode/workspace.py +0 -0
  208. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/functions/README.md +0 -0
  209. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/functions/get-license/index.ts +0 -0
  210. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  211. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/functions/telemetry/index.ts +0 -0
  212. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/sql/license_event_ordering.sql +0 -0
  213. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/sql/licensing_schema.sql +0 -0
  214. {sourcecode-4.1.0 → sourcecode-4.5.0}/supabase/sql/telemetry_events.sql +0 -0
@@ -2,6 +2,415 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [4.5.0] — 2026-08-03
6
+
7
+ Minor: the servlet-mounted HTTP surface is admitted as a population of its own
8
+ (CL-12's remaining half), the output envelope is published as an open
9
+ specification (M11's first deliverable), and a specification under `docs/` stops
10
+ being counted as a test source. Nothing published is removed and no exit code
11
+ moves; `--servlets` is opt-in and `endpoints.total` is byte-identical with and
12
+ without it.
13
+
14
+ ### Fixed
15
+
16
+ - **A specification under `docs/` was classified as a test source.** `spec/` means a
17
+ test suite in the RSpec/Jasmine sense and the opposite under a documentation root,
18
+ where a *specification* lives — and the file that exposed it is this release's own
19
+ `docs/spec/envelope-v1.md`, which landed in the test population of the tool's own
20
+ metrics the moment it was published. Fixed in the authority (`test_sources`) and in
21
+ the shared helper (`path_filters`); the segment keeps its meaning everywhere else, and
22
+ `docs/tests/` is still tests. Found by the suite, not by the field.
23
+
24
+ ### Added
25
+
26
+ - **`envelope-v1` published as an open specification** (`docs/spec/envelope-v1.md`,
27
+ roadmap M11). Audit #8 named the output envelope the product's most underrated
28
+ strategic asset, and the argument is asymmetric: a format that makes `basis`,
29
+ `limitations`, `unit` and `denominator` mandatory is one an incumbent cannot adopt
30
+ without confessing what its own output leaves out. The document specifies the four
31
+ properties an answer must have — provenance, a named unit, a stated basis with
32
+ `unknown` never spelled `0`, and declared non-coverage — plus the compatibility
33
+ promise (within `envelope_version: 1`, fields are only ever added). **The field table
34
+ is generated from the same JSON Schema `ask schema envelope-v1` prints**, and the
35
+ battery fails when the two disagree: a specification that has drifted from the
36
+ implementation is worth less than none, because the people asked to adopt it check.
37
+
38
+ ### Added
39
+
40
+ - **`ask endpoints --servlets` — the admission half of CL-12 / NC-007.** 4.2.0 declared
41
+ that the endpoint population is Spring handler mappings and that a servlet mapped in
42
+ `web.xml` or registered as a `ServletRegistrationBean` is reachable HTTP surface in
43
+ none of those counts; this lists it, as a population of its own with the URL pattern,
44
+ the servlet class and the declaring file. **It is never merged into
45
+ `endpoints.total`** — the two count different things, and widening a published figure
46
+ moves every ratio keyed on it. Measured: openmrs-core **7 patterns against 1 Spring
47
+ endpoint**, alfresco-community-repo **11**, including `/api/*` served by a WebScript
48
+ servlet. The flag is what NC-007 now names, through the remedy registry, so a rename
49
+ breaks the build rather than the reader. Nothing here resolves what guards those
50
+ patterns and the block says so.
51
+
52
+ ## [4.4.0] — 2026-08-03
53
+
54
+ Minor: M10.5 closes except for the one item blocked on a population nobody in the
55
+ battery has. Two additions, both additive — a new experimental command
56
+ (`ask migrate-recipe`) and a new opt-in block on `endpoints` (`--client-usage`).
57
+ No published field is removed, no default moves, and neither runs unless asked
58
+ for.
59
+
60
+ ### Added
61
+
62
+ - **`ask endpoints --client-usage` — which of these routes anything in this repository
63
+ actually calls** (roadmap M10.5 item 4). On a large surface the cheapest reduction of
64
+ exposure is deleting API nobody calls, and in a monorepo the caller is checked in
65
+ beside the callee. The join reads the TypeScript/JavaScript client, extracts the calls
66
+ whose verb and path are written at the call site, neutralises variable segments on both
67
+ sides (`${bankId}` and `{bank-id}` are one position with two naming conventions) and
68
+ reports three counts: routes called here, routes nothing here calls, and **client calls
69
+ matching no route** — the decisive direction, a request this repository's own front end
70
+ makes and its server does not serve. Measured on open-banking-gateway: 268 client files,
71
+ 31 calls, **30 of 39 routes called, 9 not, 11 calls matching nothing**.
72
+ - It is a **floor** and says so (`direction: under_reports`, new row `NC-009`): a route
73
+ with no call site here is a candidate for deletion, never dead API, because nothing in
74
+ a repository can observe the consumers it does not contain.
75
+ - A URL built at run time is published under `unresolved_call_sites` with its file and
76
+ line, never passed over — it is precisely the call that would make a live route look
77
+ dead, and a call the extractor could not even *see* would shrink the census silently.
78
+ - `--client-dir` points at the client when it is not the whole repository. The join runs
79
+ over the population the filters chose, for the same reason the exposure census does.
80
+
81
+ - **`ask migrate-recipe` — the migration report in the form the executor takes**
82
+ (roadmap M10.5 item 5 / M8.5, experimental). `migrate-check` already names the
83
+ OpenRewrite recipe each finding carries (296 of 309 on openmrs-core) and a reader
84
+ still had to copy them out of a JSON payload by hand — field evaluation #4's verdict
85
+ on that gap was *"el informe muere en un cajón; el codemod se convierte en PRs"*. The
86
+ command emits the declarative composite recipe naming exactly those recipes, the
87
+ artifact coordinates derived from their packages, and the invocation for the build the
88
+ repository declares (Maven or Gradle). It writes nothing without `--write`, so an audit
89
+ of somebody else's repository can run it; `--write` refuses to replace an existing
90
+ `rewrite.yml` without `--force`. **Nothing here edits source** — that is NC-005's
91
+ position, not a gap: OpenRewrite is the executor and this is its input.
92
+ - The recipe list comes from the findings, never from a catalogue of what OpenRewrite
93
+ can do: a recipe nobody's finding asked for would rewrite code nobody measured.
94
+ - Every finding with no recipe is published under `manual_remainder`. Measured on
95
+ BroadleafCommerce: **25 blocking findings in product code and not one automatable**,
96
+ which is an answer, not an empty result — and the reason an empty recipe list prints
97
+ *no* runnable command, because `mvn … rewrite:run` over nothing is a green executor
98
+ run that reads as "the migration is automated".
99
+ - Advisory hygiene is excluded by default (`--include-hygiene` opts in): on openmrs-core
100
+ it takes the population from 125 findings to 309 and adds `JavaTimeAPIs`, and a
101
+ migration diff that also modernises date handling cannot be reviewed as one change.
102
+ - The coverage block names **both** populations — its own and `migrate-check`'s narrower
103
+ `blocking_count` (125 against 114 on openmrs-core) — because two populations under one
104
+ name is the defect this project keeps finding in its own output.
105
+
106
+ ## [4.3.0] — 2026-08-03
107
+
108
+ Minor, not a patch: two commands are new (`ask enrich`, `ask data-exposure`), the
109
+ composed risk model gains two factors, and `ask verify` writes a file where it
110
+ wrote none — every one of them additive, none of them removing a published field
111
+ or moving an exit code. A pipeline that reads this release the way it read 4.2.0
112
+ gets the same answers, plus blocks it can ignore.
113
+
114
+ ### Added
115
+
116
+ - **`ask baseline capture --auto` — an architectural history that does not depend on
117
+ somebody remembering** (roadmap M10.5, head of the milestone). The snapshot has
118
+ shipped since D5; the *series* is the asset a competitor cannot backfill, and in
119
+ every repository measured so far its length is zero, because capture is a command a
120
+ human has to type. `--auto` is the form a pipeline can keep: it captures one baseline
121
+ per commit, keeps an already-captured commit instead of relabelling it, refuses to
122
+ file a tree with uncommitted changes under the commit it would be stored as, and
123
+ **exits 0 whatever happens** — a build never goes red because a snapshot could not be
124
+ taken. Every outcome names itself (`captured` / `skipped` with the reason and a
125
+ sentence of effect), so a pipeline log says which happened rather than going quiet.
126
+ A skip costs no analysis: the decision is taken before the IR is built, so the common
127
+ case in a per-push job is ~0.2 s against 1.8 s for a capture. New authority
128
+ `sourcecode/baseline_autocapture.py`; `docs/baseline-ci.yml` now captures per merge
129
+ as well as per tag.
130
+ - **`ask data-exposure` — which routes can carry the data you labelled, and who
131
+ reaches them** (roadmap M10.5 item 3, experimental). Nothing here detects sensitive
132
+ data: a label is a judgement about a domain, a field named `dni` is a national
133
+ identifier in one repository and a column name in another, and the engine never
134
+ branches on a name (VAI). It is declared once under `dataLabels` in
135
+ `sourcecode.config.json`; everything after that is measured over authorities that
136
+ already exist — the call reach `impact-chain` walks, the endpoint security surface
137
+ `risk` weighs, the profile resolution `posture` publishes (`--profile`). Two evidence
138
+ classes, published apart and never added together: `signature` (the handler names the
139
+ labelled type in its own signature) and `call_reach` (the chain reaches it — a
140
+ supremum, not a proof, because the mapping in between is not modelled: NC-008).
141
+ Measured: petclinic labelling `Owner#telephone` → **7 routes by signature**;
142
+ BroadleafCommerce labelling `Customer` → **6 by call reach and none by signature**,
143
+ because those controllers return view names. A repository that declared nothing is
144
+ `answered: false`, never zero exposed routes, and a declared type the graph never
145
+ resolved is named with the note that this is not evidence it is unexposed.
146
+ - **A request handler declares types too.** `_extract_class_type_refs` enumerated
147
+ `symbol_kind == "method"`, and a handler is classified `endpoint` at emission (a
148
+ factory method `bean`), so the class-scope type surface contained **no controller
149
+ signature anywhere in a repository**: `structural_references_to_type("Owner")` on
150
+ petclinic returned 3 atoms, none of them a route that takes an `Owner` as its request
151
+ body, and "which routes accept or return this type" answered nothing while looking
152
+ like an answer. Now 10 atoms, 7 of them handler signatures. Same shape as the F.4-1
153
+ body-surface seam, one scope up; `member_kind` still publishes the kind the symbol was
154
+ classified with.
155
+ - **The history answers from the repository path.** `ask trend .` and
156
+ `ask baseline trend .` now take either a repository or a directory of baselines, and
157
+ `ask baseline diff .` defaults to the newest point in that repository's own history
158
+ instead of requiring `--baseline <file>`. Capture writes to `<repo>/.ask/baselines`,
159
+ so making the reader name the storage directory was the same friction that kept the
160
+ series empty. An explicit directory (the `--dir` case) is unchanged, and a repository
161
+ with no history gets an error that names how to start one. New
162
+ `architectural_baseline.latest_baseline_path`, ordered exactly as the trend series is
163
+ ordered so "the last point" and "the base of a default diff" cannot disagree.
164
+ - **`ask verify` carries the history for free.** The gate is the run that already happens
165
+ on every push and already builds the IR a baseline is extracted from, so where a
166
+ repository keeps `.ask/baselines` the gate adds the current commit to it and publishes
167
+ what it did under `architectural_history` — on every run, including the ones that
168
+ captured nothing, because a series that silently stopped growing is invisible until the
169
+ day somebody needs it (I-8). Measured on BroadleafCommerce: 3.9 s with the capture
170
+ against 4.0 s without, i.e. inside the noise; eureka 1.8 s against 0.8 s (its IR is
171
+ smaller, the extraction is not). The passenger cannot move the gate: the verdict, the
172
+ exit code and every other field are identical with and without it, and an exception
173
+ inside it is swallowed. `ASK_BASELINE_AUTOCAPTURE=0/1` overrides in both directions.
174
+ - ⚠One measured cost stated rather than hidden: a baseline is ~730 KB on a 3 300-file
175
+ monolith, because it stores the full endpoint surface and fan-in map so a later
176
+ `baseline diff` is faithful. A point per merge is a megabyte-scale history; a point
177
+ per release is not. `--dir` sends them outside the repository.
178
+ - ⚠Found by the battery, not by the field: the first capture writes an untracked file
179
+ **inside the repository**, so a plain `git status --porcelain` check would have
180
+ reported a dirty tree from then on and every later run would have skipped — a
181
+ history of exactly one. The dirtiness question excludes this tool's own footprint
182
+ (`.ask/`) and nothing else, because everything else is what the baseline measures —
183
+ and the second half of that came from eureka, where `verify --init` writes
184
+ `.ask/contracts.yml` and, counted as a modification, would stop the history from
185
+ ever starting.
186
+ - **`ask enrich --sarif <log>` — somebody else's detection, ranked by what this
187
+ repository does with it** (roadmap M10, first deliverable). This product does not
188
+ detect injection, CVEs or secrets and says so in every security payload (NC-001,
189
+ NC-002); the scanners that do have no bean graph, no profile model and no endpoint
190
+ id they share with anything, so their output is a list nobody can order. `enrich`
191
+ reads a SARIF 2.1.0 log from Semgrep, CodeQL or Trivy and runs the **same
192
+ composition** `ask risk` runs over each finding — same axes, same weights, same
193
+ `RiskComposer` — with one difference: `defect_severity` is the scanner's own
194
+ verdict (`security-severity` when the tool published one, `level` otherwise),
195
+ carried through with the scanner named as its authority. Nothing re-rates,
196
+ confirms or contradicts a finding. Results sharing (tool, rule, symbol) are one
197
+ defect with several witnesses; a result the join could not place — a file outside
198
+ the population this build read, a line with no declaration above it — is published
199
+ under `unresolved` with the reason, never dropped.
200
+ - **The CVE half of the same command: a dependency finding is joined through the
201
+ coordinate, not through a line.** A result located on `pom.xml` or
202
+ `build.gradle` is about a library, so the coordinate is read back out of the
203
+ manifest the scanner named and the reach is the worst of the types that import
204
+ it — *of forty vulnerable dependencies, which ones does an unauthenticated route
205
+ actually reach?* Importers are found from the IR's existing `imports` edges, by
206
+ the coordinate's group id or by its artifact id as a package segment, and each
207
+ row publishes which basis found them. A library nothing imports is `unresolved`
208
+ and never "unreachable": reflection, a service loader and use through another
209
+ dependency all leave no import edge. Both kinds rank in one list, because a CVE
210
+ in a reachable library and an injection finding in a handler are the same
211
+ question to whoever decides what to fix first.
212
+ - **`--profile <set>` on `ask risk` and `ask enrich` — profile context per finding**
213
+ (M10 exit criterion). The access axis stops answering for *the repository as
214
+ configured* and answers for *that deployment*: `posture` resolves the conditional
215
+ bean graph and the request chain under the named set, through a new published
216
+ seam (`posture.endpoint_access_under`, `posture.access_verdict`), so a composed
217
+ row and a `posture` run can never disagree about the same profile set. A decision
218
+ resolves an endpoint the repository-wide surface left at `coverage_unknown`, in
219
+ either direction — measured on a fixture, one defect scores 11.52/`open` under
220
+ `dev`, 8.06/`unknown` with no set named, and 5.76/`protected` under `prod`. When
221
+ both authorities decided, the worse of them wins, per endpoint.
222
+ - **`ask risk` gains a fifth factor: `query_construction`** (roadmap F.4-1). The
223
+ field asked the question this answers the structural half of — *"con 618 HQL
224
+ concatenados, ¿alguno concatena entrada de request?"* Following request input to
225
+ a query is dataflow, is declared out of scope in NC-001, and stays there. What
226
+ is publishable without it is the adjacency: this defect's own code assembles a
227
+ query string by concatenation, and the four factors beside it already say whether
228
+ that code is reachable, unauthenticated and writing. Read from the α
229
+ argument-shape atoms the IR already carries (`dynamic_argument_surface`) — no new
230
+ analysis, one pass, joined per defect. `not_observed` means the shape was absent
231
+ from the body facts; it is never a claim that a query is safely parameterised.
232
+ - **…and a sixth: `input_constraints`** — the other half of the same field question
233
+ (*"1 201 bodies sin validación"*). Joined by route against `validation`'s gap
234
+ list: `absent` means one of the endpoints reaching this defect accepts a request
235
+ body with no declared constraint, taking the worst of the reached routes for the
236
+ reason the auth axis does. `ask risk` now publishes the `non_coverage` block too,
237
+ because two axes describing the input path, composed with an open access verdict,
238
+ read as *injection* unless the payload states that no dataflow was followed.
239
+
240
+ ### Fixed
241
+
242
+ - **`validation` counted handlers that take no argument as body endpoints.** The
243
+ body surface was the verb alone (POST/PUT/PATCH) and the declared limitation said
244
+ the parameter list was not captured. It is now captured (`_handler_params`) and
245
+ read in the negative direction only: an empty parameter list proves no body can
246
+ bind. A handler whose parameters are all path or query values still counts, and
247
+ the limitation says so.
248
+
249
+ - **The α argument-shape surface was blind to every controller body.**
250
+ `dynamic_argument_surface` walked `kind="method"` and `kind="constructor"` symbol
251
+ nodes; a request handler is a `kind="endpoint"` node. The owner population is now
252
+ the body-fact layer's own (`ContextGraph.body_owners()`).
253
+
254
+ ### Changed
255
+
256
+ - `severity_effective` in `ask risk` can now be larger for a row whose code
257
+ concatenates a query. Every factor's neutral value is 1.0, so a new axis only
258
+ ever moves a row **up**: no band a reader has already acted on is demoted by
259
+ this release.
260
+
261
+ ## [4.2.0] — 2026-08-03
262
+
263
+ Minor, not a patch, by this project's own criterion: two published figures move
264
+ and a verdict changes, so a pipeline reading either can change colour.
265
+ `posture --resolve-environments` answers `NOT DECIDED IN THIS REPOSITORY` where
266
+ it answered `artefacts_disagree` on a repository whose build properties nothing
267
+ consumes (C1-22), and `ask risk` publishes defects where it published findings,
268
+ so `total_defects` and `by_band` move (C1-23) — 20 → 15 on BroadleafCommerce.
269
+ `risk` also drops `rule_id` for `rule_ids`: it is in the `experimental` tier,
270
+ whose published promise is exactly that its shape may change in a minor.
271
+
272
+ Field evaluation #9 (8/10, same 3 337-file monolith as #6–#8) opened nine rows
273
+ and this release closes seven of them. The two left open are open on purpose:
274
+ `C3-39` needs a Windows runner before it needs a fix, and `P-7` is a pricing
275
+ decision. Every complaint was re-measured against HEAD before a row was written
276
+ — five reproduced, one was half false, one was not reproducible here, and one
277
+ was a capability that already shipped.
278
+
279
+ ### Added
280
+
281
+ - **`ask posture --diff-ref <base>:<head>` and `--since <ref>` — one profile set,
282
+ two git refs** (roadmap M10.5 item 1). `--diff` holds the tree fixed and moves
283
+ the profile set; this holds the profile set fixed and moves the tree, which is
284
+ the question a pull request asks: *does this change what a client can reach
285
+ without authenticating?* `--since` compares a ref with the working tree,
286
+ uncommitted edits included. Both refs are read with `git archive`: nothing is
287
+ written to the repository, no worktree is created and the index is not touched.
288
+ `docs/posture.md` had declared this as the one requested extension with no
289
+ feature behind it.
290
+ - **`--fail-on opened|any|never` — the gate half.** Default `never`, so no
291
+ invocation that worked yesterday changes colour today; `opened` exits 1 when a
292
+ request a readable rule leaves reachable unauthenticated was not one before.
293
+ The payload is emitted before the exit code, because a red pipeline with no
294
+ statement of what opened is a gate nobody keeps. It requires a ref comparison —
295
+ gating a single run would gate on pre-existing debt, which is `spring-audit --ci`.
296
+ - **`endpoint_request_identity` registered as a fact** (ADR-0008 R11,
297
+ `sourcecode.canonical_ir:request_identity`). The comparison unit is the request
298
+ (`METHOD path`), not the endpoint id, which carries the controller FQN and the
299
+ handler symbol and therefore changes when a handler moves between classes
300
+ without the URL changing. `contract_diff` re-derived the same identity and now
301
+ binds to the authority. Path-variable patterns are deliberately **not**
302
+ normalised: `{id:.*}` and `{id:[^0-9].*}` are different URLs to a caller, and
303
+ one field repository moved 93 requests with exactly that edit in a single commit.
304
+
305
+ ### Added
306
+
307
+ - **`ask endpoints --compact` — the census instead of the rows** (C2-22, field
308
+ evaluation #9). Asked how exposed a repository was, the command answered with
309
+ 1.9 MB of JSON for 3 574 endpoints and no summary mode, and the evaluator
310
+ aggregated it by hand. Every answer now carries an `exposure` block — counts by
311
+ method, by security policy, by controller and by first path area — and
312
+ `--compact` returns it without the rows, declaring what it dropped. Two rules
313
+ it obeys against itself: the census is measured over the population the filters
314
+ chose and never over what `--limit` left rendered, and every ranked rollup
315
+ states its own total when it cuts. Measured on BroadleafCommerce: 95 KB → 11 KB,
316
+ every count unchanged. (The other half of the complaint is recorded as false:
317
+ `spring-audit` has shipped `--compact`, `--min-severity` and `--scope` for
318
+ releases.)
319
+
320
+ - **NC-007 — the endpoint population is declared** (CL-12, field evaluation #9).
321
+ `endpoints` projects Spring handler mappings; a servlet declared in `web.xml`
322
+ or registered as a `ServletRegistrationBean` is reachable over HTTP and is in
323
+ no part of that model. Six published non-coverage rows are exactly what let a
324
+ reader treat the list as the whole HTTP surface, and the evaluation lost a
325
+ monitoring console that way — at a path behind the credential the same run
326
+ reported as SEC-007. The row is published in the `endpoints` payload and inside
327
+ `posture.endpoints`, because the reader who counts open requests is reading
328
+ `posture`. Admission of a servlet surface is deliberately **not** in this
329
+ change: it is a second population and merging it into `endpoints.total` would
330
+ move a published count and every ratio keyed on it.
331
+
332
+ ### Fixed
333
+
334
+ - **A reach figure that did not name its scope** (C2-23, field evaluation #9).
335
+ `risk` reported `endpoints_reached: 1` for a symbol whose class `impact-chain`
336
+ said reached 8 — both correct, both documented, in two payloads, so reconciling
337
+ them cost the reader three unit notes. Each row now carries
338
+ `endpoints_reached_basis`: what the figure is a reach *of* (a defect sits at the
339
+ symbol that carries the remedy, so a method-level defect walks from the method)
340
+ and, where that is narrower than a class, the command that answers the wider
341
+ question. The relationship is asserted by measurement rather than stated in
342
+ prose.
343
+
344
+ - **The remedy registry now follows the status, not only the limitation** (C4-13,
345
+ field evaluation #9 — the sixth appearance of the C4 shape). The evaluation met
346
+ `verify`'s `contract_count: 0` → `unverified` → exit 2 under a read-only
347
+ constraint, concluded the command was unusable and asked for a `--dry-run` that
348
+ shipped in 3.7.0. The state named one next move and the reader could not take
349
+ it. `Remedy` gained `also` (the further options an answer needs — a remedy is an
350
+ invocation, not a flag), the new entry is `ask verify . --init --dry-run`, and
351
+ the `unverified` reason names both forms. The guard grew with it: every option
352
+ of an invocation must be accepted by the command it names, and the README check
353
+ matches a line carrying the command with all of its options, so a front page
354
+ that lists `--init` and omits `--dry-run` fails the build.
355
+
356
+ - **The hub-class guard contradicted the payload beside it** (C2-21, field
357
+ evaluation #9). It printed *"symbol has > 500 direct callers"* while the same
358
+ run published 215 of them on openmrs-core's `Context`: the guard trips on
359
+ caller **reference sites** (method-level keys included) and the payload
360
+ publishes caller **classes**, so the stated reason was checkably false while
361
+ the decision was right. `caller_reach.bfs_callers` now returns the population it
362
+ read, and the warning names it with its unit next to the class count it takes
363
+ from `caller_metrics.caller_classes` — *"792 caller reference sites … exceed the
364
+ cap of 500 … The 215 direct caller classes this run publishes stay exact"*.
365
+
366
+ - **`ask risk` ranked findings under the label `spring-audit` deduplicates**
367
+ (C1-23, field evaluation #9). One SEC-004 appeared three times for three call
368
+ sites in one class and `by_band` was an observation census under a defect
369
+ label — measured on BroadleafCommerce, 20 rows over 15 distinct `defect_id`
370
+ beside `spring-audit`'s own 15 defects / 20 findings. `build_risk` now iterates
371
+ `defect_identity.group_by_defect`, so one row is one thing to fix and both
372
+ commands report the same count (asserted against each other, not against a
373
+ literal). Nothing is dropped: `witness_count` and `witness_sites` carry where
374
+ each observation was seen, `total_findings` publishes the census under its own
375
+ name, and `rule_id` becomes **`rule_ids`** because one defect can be witnessed
376
+ by TX-001 and TX-006 at once and a singular field would have to pick one.
377
+ `severity` is the strongest across the witnesses, and
378
+ `factors.defect_severity.basis` says so.
379
+
380
+ - **A Maven build property was published as a runtime activation** (C1-22, field
381
+ evaluation #9 — the row it called the most expensive in its report). Two
382
+ `<properties>` entries setting `spring.profiles.active` made
383
+ `posture --resolve-environments` answer `artefacts_disagree` — *"different
384
+ deployments, pick one"* — on a repository where **nothing activates a profile at
385
+ run time**. The honest verdict, which the command already implements, is
386
+ `NOT DECIDED IN THIS REPOSITORY`: the default set applies and the permissive
387
+ profile wins, which is exactly where that audit's most severe finding lived. The
388
+ command turned a fail-open into a deployment ambiguity, in the scenario it is
389
+ sold for. A build property is now admitted as an activation only when a resource
390
+ in the repository consumes it (`@spring.profiles.active@`, or
391
+ `${spring.profiles.active}` where the build declares its resources filtered).
392
+ Unconsumed, the value is kept — it is still the profile set a build of it would
393
+ produce, so the worst case keeps ranking it — and carries the reason it decides
394
+ nothing, beside a `build_properties_not_consumed` count. The positive control is
395
+ half the battery: before this, the case where the property genuinely does decide
396
+ produced the identical verdict, which is how the defect stayed invisible. No
397
+ movement on the field repositories.
398
+
399
+ - **A rule that disappeared was reported as protection gained.** Found by the
400
+ negative control, not in the field: delete a security configuration and every
401
+ request it decided goes `permit_all` → undecided, which a two-bucket
402
+ opened/closed split published as *"2 requests no longer reachable
403
+ unauthenticated"*. Four buckets now: `opened` and `closed` (attributable to the
404
+ change), `no_longer_decided` (coverage lost) and `now_open_previously_undecided`
405
+ (our reading moved, not necessarily the system — it never turns a gate red on
406
+ its own). Requests undecided on either side are counted in
407
+ `access_not_decided_either_side`, the delta publishes `direction`, and
408
+ `gate.reading` states the floor (I-8).
409
+ - **`git_checkout` no longer offers a remedy half its callers do not have.** The
410
+ not-a-repository message told every caller to "pass two checkouts positionally";
411
+ `posture` takes none. The message states the fact and each command supplies its
412
+ own hint.
413
+
5
414
  ## [4.1.0] — 2026-08-03
6
415
 
7
416
  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.5.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,8 +156,12 @@ 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
- # What each defect actually costs once reach, access and write effect are in it:
160
- # severity × reachability × auth_verdict × write_effect, ordered, every factor traceable.
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
+
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.
161
165
  ask risk /path/to/repo
162
166
  ```
163
167
 
@@ -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,
@@ -247,12 +254,16 @@ guesses is a confident security falsehood — the worst failure mode this tool h
247
254
  ### 5c · Composed Risk *(experimental)*
248
255
  Every command above answers one axis, and a reader composes them by hand. `ask risk` does the
249
256
  join over the endpoint and symbol ids these commands already share with each other:
250
- `severity_effective = defect_severity × reachability × auth_verdict × write_effect`. The
251
- 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
252
259
  figures and the authority behind each — and an axis this build cannot measure is `unknown`,
253
260
  weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
254
261
  field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
255
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.
256
267
  `ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
257
268
  → [reference](docs/USER_GUIDE.md)
258
269
 
@@ -278,7 +289,7 @@ experimental: both are true, and they are two different facts.
278
289
  |---|---|---|
279
290
  | **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
280
291
  | **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
281
- | **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` |
282
293
  | **parked** | kept working, no longer developed | `retrieve` |
283
294
 
284
295
  The same table is printed by `ask --help`, and both are generated from one authority
@@ -295,7 +306,10 @@ from it.
295
306
  | Command | Tier | Answers | Note |
296
307
  |---|---|---|---|
297
308
  | `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
298
- | `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) |
299
313
  | `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators) |
300
314
  | `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment` |
301
315
  | `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan |
@@ -310,7 +324,7 @@ from it.
310
324
  | `review-pr` / `fix-bug` / `prepare-context` | supported | diff review, symptom triage, task-shaped context | |
311
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 |
312
326
  | `validation` | supported | request-body validation coverage and gaps | |
313
- | `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) |
314
328
  | `retrieve` | parked | typed knowledge queries over the model | |
315
329
  | `archetype` | experimental | evidence-based architectural archetype | |
316
330
  | `rename-class` / `chunk-file` | supported | word-boundary Java rename; split a large file for an agent | |
@@ -354,6 +368,31 @@ Two more boundaries worth stating in the same voice:
354
368
  | **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
369
  | **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
370
 
371
+
372
+ And one about the endpoint surface itself:
373
+
374
+ | Not covered | Why | What answers it |
375
+ |---|---|---|
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. |
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
+
390
+ The one row above with a remedy in this build: `ask endpoints /path/to/repo --servlets`
391
+ lists the servlet-mounted HTTP surface as a population of its own — `web.xml` mappings and
392
+ `ServletRegistrationBean` registrations, with the file that declares each — and never merges
393
+ it into `endpoints.total`. Measured: openmrs-core 7 patterns, alfresco-community-repo 11,
394
+ including `/api/*` served by a WebScript servlet.
395
+
357
396
  **Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
358
397
  must change, what each change reaches, and what a gate should block — and it removes none of
359
398
  it. Field evaluation scored it 7/10 as a report generator and 5.5/10 as a development tool,
@@ -446,3 +485,4 @@ Matching endpoints report `policy: "custom"` and drop out of the `no_security_si
446
485
  | [PRODUCT_IDENTITY.md](docs/PRODUCT_IDENTITY.md) | `ask` (command) vs `sourcecode` (package/alias) |
447
486
  | [privacy.md](docs/privacy.md) | Telemetry and data-handling policy |
448
487
  | [DEFECT-LEDGER.md](docs/DEFECT-LEDGER.md) | Every defect found in the field, its class, and which release closed it — published on purpose |
488
+ | [spec/envelope-v1.md](docs/spec/envelope-v1.md) | The output format as an **open specification** — provenance, a named unit, a stated basis, declared non-coverage. Implementable by tools that are not this one; the field table is generated from the schema `ask schema envelope-v1` prints |