sourcecode 4.18.0__tar.gz → 5.0.1__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 (233) hide show
  1. {sourcecode-4.18.0 → sourcecode-5.0.1}/.github/workflows/perf-gate.yml +6 -1
  2. {sourcecode-4.18.0 → sourcecode-5.0.1}/CHANGELOG.md +121 -0
  3. {sourcecode-4.18.0 → sourcecode-5.0.1}/PKG-INFO +5 -5
  4. {sourcecode-4.18.0 → sourcecode-5.0.1}/README.md +4 -4
  5. {sourcecode-4.18.0 → sourcecode-5.0.1}/pyproject.toml +1 -1
  6. {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/perf_gate.py +19 -0
  7. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/__init__.py +1 -1
  8. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cache_model.py +329 -43
  9. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cli.py +20 -4
  10. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detach.py +7 -3
  11. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/execution_plan.py +76 -21
  12. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/perf.py +4 -2
  13. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/phased_run.py +10 -8
  14. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/posture.py +13 -26
  15. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/release_info.py +1 -1
  16. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/repository_ir.py +21 -31
  17. sourcecode-5.0.1/src/sourcecode/security_chain.py +148 -0
  18. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/security_config_scan.py +54 -4
  19. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/source_text.py +18 -0
  20. {sourcecode-4.18.0 → sourcecode-5.0.1}/.github/workflows/build-windows.yml +0 -0
  21. {sourcecode-4.18.0 → sourcecode-5.0.1}/.gitignore +0 -0
  22. {sourcecode-4.18.0 → sourcecode-5.0.1}/.ruff.toml +0 -0
  23. {sourcecode-4.18.0 → sourcecode-5.0.1}/CLAUDE.md +0 -0
  24. {sourcecode-4.18.0 → sourcecode-5.0.1}/CONTRIBUTING.md +0 -0
  25. {sourcecode-4.18.0 → sourcecode-5.0.1}/LICENSE +0 -0
  26. {sourcecode-4.18.0 → sourcecode-5.0.1}/SECURITY.md +0 -0
  27. {sourcecode-4.18.0 → sourcecode-5.0.1}/raw +0 -0
  28. {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/compare_integration_engines.py +0 -0
  29. {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/customer_smoke_test.sh +0 -0
  30. {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/generate_jdk_exports.py +0 -0
  31. {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/perf_harness.py +0 -0
  32. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/adaptive_scanner.py +0 -0
  33. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/archetype.py +0 -0
  34. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architectural_baseline.py +0 -0
  35. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architectural_delta.py +0 -0
  36. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architecture_analyzer.py +0 -0
  37. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architecture_summary.py +0 -0
  38. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/ast_extractor.py +0 -0
  39. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/audit_report.py +0 -0
  40. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/baseline_autocapture.py +0 -0
  41. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cache.py +0 -0
  42. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/call_surface.py +0 -0
  43. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/caller_metrics.py +0 -0
  44. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/caller_reach.py +0 -0
  45. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/canonical_ir.py +0 -0
  46. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/chain_rules.py +0 -0
  47. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/change_plan.py +0 -0
  48. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cir_graphs.py +0 -0
  49. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/classifier.py +0 -0
  50. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/client_calls.py +0 -0
  51. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/code_notes_analyzer.py +0 -0
  52. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/compare.py +0 -0
  53. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/confidence_analyzer.py +0 -0
  54. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/constraint_diff.py +0 -0
  55. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/container_wiring.py +0 -0
  56. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_cache.py +0 -0
  57. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_graph.py +0 -0
  58. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_scorer.py +0 -0
  59. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_summarizer.py +0 -0
  60. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_diff.py +0 -0
  61. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_init.py +0 -0
  62. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_model.py +0 -0
  63. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_pipeline.py +0 -0
  64. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/coverage_parser.py +0 -0
  65. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/data_exposure.py +0 -0
  66. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/data_labels.py +0 -0
  67. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/declarations.py +0 -0
  68. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/defect_identity.py +0 -0
  69. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/degradation.py +0 -0
  70. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/dependency_analyzer.py +0 -0
  71. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/deployment_prefix.py +0 -0
  72. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/__init__.py +0 -0
  73. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/base.py +0 -0
  74. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/csproj_parser.py +0 -0
  75. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/dart.py +0 -0
  76. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/dotnet.py +0 -0
  77. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/elixir.py +0 -0
  78. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/go.py +0 -0
  79. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/heuristic.py +0 -0
  80. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/hybrid.py +0 -0
  81. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/java.py +0 -0
  82. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/jvm_ext.py +0 -0
  83. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/nodejs.py +0 -0
  84. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/parsers.py +0 -0
  85. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/php.py +0 -0
  86. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/project.py +0 -0
  87. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/python.py +0 -0
  88. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/ruby.py +0 -0
  89. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/rust.py +0 -0
  90. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/systems.py +0 -0
  91. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/terraform.py +0 -0
  92. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/tooling.py +0 -0
  93. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/doc_analyzer.py +0 -0
  94. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/dynamic_argument_surface.py +0 -0
  95. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/endpoint_literals.py +0 -0
  96. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/endpoint_metrics.py +0 -0
  97. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/entrypoint_classifier.py +0 -0
  98. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/env_analyzer.py +0 -0
  99. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/envelope.py +0 -0
  100. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/environment_resolution.py +0 -0
  101. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/error_schema.py +0 -0
  102. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/evidence_provider.py +0 -0
  103. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/explain.py +0 -0
  104. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/facts/__init__.py +0 -0
  105. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/facts/registry.json +0 -0
  106. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/file_chunker.py +0 -0
  107. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/file_classifier.py +0 -0
  108. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/filter_surface.py +0 -0
  109. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/format_contract.py +0 -0
  110. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/fqn_utils.py +0 -0
  111. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/git_analyzer.py +0 -0
  112. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/git_checkout.py +0 -0
  113. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/graph_analyzer.py +0 -0
  114. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/graph_evidence.py +0 -0
  115. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/hibernate_strat.py +0 -0
  116. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/identity_fallback.py +0 -0
  117. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/integration_coordinates.py +0 -0
  118. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/jdk_exports.py +0 -0
  119. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/license.py +0 -0
  120. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/__init__.py +0 -0
  121. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/dependency_import.py +0 -0
  122. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  123. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  124. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  125. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  126. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  127. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/orchestrator.py +0 -0
  128. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/registry.py +0 -0
  129. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/runner.py +0 -0
  130. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/server.py +0 -0
  131. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp_nudge.py +0 -0
  132. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/metrics_analyzer.py +0 -0
  133. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/migrate_check.py +0 -0
  134. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/migration_blast.py +0 -0
  135. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/non_coverage.py +0 -0
  136. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/openapi_surface.py +0 -0
  137. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/openrewrite_recipe.py +0 -0
  138. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/output_budget.py +0 -0
  139. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/output_encoding.py +0 -0
  140. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/parallel.py +0 -0
  141. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/parse_cache.py +0 -0
  142. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/partial_contract.py +0 -0
  143. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/path_admission.py +0 -0
  144. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/path_filters.py +0 -0
  145. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/pipe_contract.py +0 -0
  146. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/pr_comment_renderer.py +0 -0
  147. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/pr_impact.py +0 -0
  148. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/prepare_context.py +0 -0
  149. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/progress.py +0 -0
  150. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/provenance.py +0 -0
  151. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/ranking_engine.py +0 -0
  152. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/readiness_timeline.py +0 -0
  153. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/readonly.py +0 -0
  154. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/reconciliation.py +0 -0
  155. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/redactor.py +0 -0
  156. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/reference_facts.py +0 -0
  157. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/relevance_scorer.py +0 -0
  158. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/remedies.py +0 -0
  159. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/rename_refactor.py +0 -0
  160. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/repo_classifier.py +0 -0
  161. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/__init__.py +0 -0
  162. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/context.py +0 -0
  163. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/errors.py +0 -0
  164. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/executor.py +0 -0
  165. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/planner.py +0 -0
  166. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/query.py +0 -0
  167. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/request.py +0 -0
  168. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/resolution.py +0 -0
  169. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/result.py +0 -0
  170. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/retriever.py +0 -0
  171. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/runtime.py +0 -0
  172. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps.py +0 -0
  173. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  174. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_graph.py +0 -0
  175. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_impact.py +0 -0
  176. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_intf.py +0 -0
  177. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_struct.py +0 -0
  178. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  179. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/ris.py +0 -0
  180. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/risk.py +0 -0
  181. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/rule_catalog.py +0 -0
  182. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/rule_pass.py +0 -0
  183. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/runs.py +0 -0
  184. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/runtime_classifier.py +0 -0
  185. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/sarif.py +0 -0
  186. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/scanner.py +0 -0
  187. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/schema.py +0 -0
  188. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
  189. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/security_config.py +0 -0
  190. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/security_posture.py +0 -0
  191. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_analyzer.py +0 -0
  192. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_impact_engine.py +0 -0
  193. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_integration_engine.py +0 -0
  194. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_services.py +0 -0
  195. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/serializer.py +0 -0
  196. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/servlet_surface.py +0 -0
  197. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_event_topology.py +0 -0
  198. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_findings.py +0 -0
  199. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_impact.py +0 -0
  200. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_model.py +0 -0
  201. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_profiles.py +0 -0
  202. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_properties.py +0 -0
  203. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_security_audit.py +0 -0
  204. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_semantic.py +0 -0
  205. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_tx_analyzer.py +0 -0
  206. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/summarizer.py +0 -0
  207. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/target_admission.py +0 -0
  208. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/__init__.py +0 -0
  209. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/config.py +0 -0
  210. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/consent.py +0 -0
  211. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/events.py +0 -0
  212. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/filters.py +0 -0
  213. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/transport.py +0 -0
  214. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/test_gap_ranking.py +0 -0
  215. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/test_sources.py +0 -0
  216. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/text_input.py +0 -0
  217. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/token_estimate.py +0 -0
  218. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/tree_utils.py +0 -0
  219. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/type_usage_surface.py +0 -0
  220. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/validation_inference.py +0 -0
  221. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/validation_surface.py +0 -0
  222. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/verify_edit.py +0 -0
  223. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/verify_repo.py +0 -0
  224. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/verify_rules.py +0 -0
  225. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/version_check.py +0 -0
  226. {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/workspace.py +0 -0
  227. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/README.md +0 -0
  228. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/get-license/index.ts +0 -0
  229. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  230. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/telemetry/index.ts +0 -0
  231. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/sql/license_event_ordering.sql +0 -0
  232. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/sql/licensing_schema.sql +0 -0
  233. {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/sql/telemetry_events.sql +0 -0
@@ -59,14 +59,18 @@ jobs:
59
59
  python3 scripts/perf_gate.py --print-config | tee gate-config.json
60
60
  echo "repo_url=$(python3 -c "import json;print(json.load(open('gate-config.json'))['repository_url'])")" >> "$GITHUB_OUTPUT"
61
61
  echo "repo=$(python3 -c "import json;print(json.load(open('gate-config.json'))['repository'])")" >> "$GITHUB_OUTPUT"
62
+ echo "fleet_subdir=$(python3 -c "import json;print(json.load(open('gate-config.json'))['fleet_subdir'])")" >> "$GITHUB_OUTPUT"
62
63
  echo "mode=$(python3 -c "import json;print(json.load(open('gate-config.json'))['mode'])")" >> "$GITHUB_OUTPUT"
63
64
  echo "runs=$(python3 -c "import json;print(json.load(open('gate-config.json'))['min_runs'])")" >> "$GITHUB_OUTPUT"
64
65
  echo "commands=$(python3 -c "import json;print(' '.join(repr(c) for c in json.load(open('gate-config.json'))['commands']))")" >> "$GITHUB_OUTPUT"
65
66
 
66
67
  - name: Clone the gate repository
68
+ # Into the directory the harness resolves the gate repository to, which
69
+ # `--print-config` publishes. Naming it here instead cost three nightlies
70
+ # that measured nothing.
67
71
  run: |
68
72
  mkdir -p fleet
69
- git clone --depth 1 "${{ steps.cfg.outputs.repo_url }}" "fleet/${{ steps.cfg.outputs.repo }}"
73
+ git clone --depth 1 "${{ steps.cfg.outputs.repo_url }}" "fleet/${{ steps.cfg.outputs.fleet_subdir }}"
70
74
 
71
75
  - name: Measure
72
76
  env:
@@ -84,6 +88,7 @@ jobs:
84
88
  run: |
85
89
  python3 scripts/perf_gate.py \
86
90
  --baseline "$BASELINE_DIR" \
91
+ --require-baseline \
87
92
  --current perf-run \
88
93
  --report perf-run/gate.json \
89
94
  --table perf-run/RELEASE-TABLE.md
@@ -2,6 +2,127 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.0.1] — 2026-08-11
6
+
7
+ **A patch on the release that made the product's own cost figures honest, for the
8
+ four cells that refresh did not reach.** No analysis changes: `onboard` payloads
9
+ on spring-petclinic and jobrunr are byte-identical against 5.0.0. What moves is
10
+ the operational advice on two commands — `repo-ir` and `baseline capture` are
11
+ foreground work at field scale, where 5.0.0 still sent them to a nightly job on a
12
+ 4.10.4 outcome.
13
+
14
+ ### Fixed
15
+
16
+ - **Four cost cells the 5.0.0 refresh did not reach, and two of them said the
17
+ field could not run a command it has since run twice (C3-100).** C3-97 gave
18
+ every field figure the build it was taken on and re-measured what evaluation
19
+ #22 had run; what #22 had not run kept its 4.10.4 cell. `ask` (root) published
20
+ 115 s, `baseline` 11 s, and — worse, because the claim is categorical rather
21
+ than numeric — `repo-ir` and `verify-edit` published `field_blocked`, which the
22
+ model renders as *"did not finish in an interactive session"*. Evaluation #23
23
+ ran all four from a purged cache on the same repository: root **72,3 s**,
24
+ `repo-ir` **9,8 s**, `baseline capture` **2,2 s**, `verify-edit` **76,6 s**.
25
+ `repo-ir` and `baseline` are foreground work at field scale where the product
26
+ was sending them to a nightly job.
27
+ - **An outcome is a measurement, so it expires like one.** `field_blocked` was the
28
+ strongest claim in the table and the only one that could be written without a
29
+ build behind it. It is dated now wherever it is published (*"did not finish in
30
+ an interactive session on 4.10.4 … and nothing has re-measured it since"*), and
31
+ the battery rejects an undated one.
32
+ - **A figure now states the cache state it was taken in.** The root analysis is
33
+ 72,3 s from a purged cache and 0,3 s from a warm one; publishing one number
34
+ without saying which invites a reader to compare two different facts. Every
35
+ field figure carries `warm`/`cold`/`mixed`, in the `here:` line, the `cache
36
+ model` rows and the JSON.
37
+ - **The headline anchor is read off the table instead of copied beside it.**
38
+ `FIELD_ANCHOR`, `FIELD_ANCHOR_SECONDS` and `FIELD_ANCHOR_MEASURED_VERSION` are
39
+ derived from the `spring-audit` row — the missed copy is what C3-100 was — and
40
+ `field_currency()` now also names every row measured before the newest figure in
41
+ the same table (`rows_behind_the_newest_field_measurement`), which is the
42
+ staleness that hid for three releases: not *"older than the build you are
43
+ running"* but *"older than the refresh that reached the row next to it"*.
44
+ - **The root row was invisible to the surface its measurement exists for.**
45
+ `cost_row("ask (root)")` resolved to no row, so `cache model`'s `here:` line for
46
+ the root analysis was published from the command's *class*, with no figure in
47
+ it, on every repository. Found while checking the refresh on a real one.
48
+
49
+ ## [5.0.0] — 2026-08-11
50
+
51
+ **The engine got 280× faster in 4.18.0 and every number the product quoted about
52
+ its own cost still described the build before it.** This release changes no
53
+ analysis: it makes what ASK says about itself true again, and makes the way it
54
+ went stale impossible to repeat silently. Field evaluation #22 — eighth
55
+ measurement of the same 3 342-file repository at the same commit — scored the
56
+ build **9,2/10** and named this as the one place the product states something
57
+ false with confidence.
58
+
59
+ **Why a major.** No API breaks. What changes is an answer thousands of readers
60
+ act on: commands that were published as *"not a foreground run here — `--output
61
+ <file> --detach`, or a nightly job"* are now published as foreground work, and
62
+ the operational advice in `--help`, `cache model`, the budget warning and the
63
+ remedies moves with them. A recommendation that reverses is a contract change
64
+ whatever the surface, so it is versioned like one.
65
+
66
+ **Fixed in this release:**
67
+
68
+ - **The cost anchors described a build that no longer exists (C3-97).** `spring-audit`'s
69
+ field anchor was **2 351 s**, measured on 4.11.0; the same command, on the same
70
+ repository at the same commit, takes **8,4 s** on 4.18.0 — the two
71
+ catastrophic-backtracking patterns behind that figure were deleted in C3-95 and
72
+ C3-96. Four surfaces read the anchors and none could tell they were old:
73
+ `execution_plan`'s `here:` verdict, the budget warning, the `cache model`
74
+ header, and the front page. The product therefore recommended a nightly job for
75
+ an eight-second command, and an operator sizing `ASK_MAX_ANALYSIS_SECONDS` from
76
+ it would set the budget ~280× too high. Anchors refreshed from evaluation #22
77
+ (`spring-audit` 2 351 → 8,4 s · `risk` 3 232 → 73,3 s · `posture` 38 → 8,0 s ·
78
+ `migrate-check` 26,7 → 10,2 s · `endpoints` 5,0 → 3,8 s), first anchors recorded
79
+ for `impact-chain` 5,5 s, `validation` 17,4 s, `pr-impact` 12,5 s, `impact`
80
+ 7,7 s and `explain` 4,4 s — and `modernize`, carried as *did not finish* since
81
+ 4.10.4, is a measurement again at **9,1 s**.
82
+ - **And they cannot go stale silently again.** Every field figure now carries
83
+ `field_measured_version`, the build it was taken on. A figure from an earlier
84
+ release is still published — a measurement at that size beats silence — but it
85
+ arrives labelled *"measured on 4.10.4, not re-measured on 5.0.0"* wherever it is
86
+ read, and `ask cache model --json` publishes `field_currency` naming every row
87
+ in that state. This is the mechanism `REFERENCE_MEASURED_VERSION` already gave
88
+ the reference figures; the field anchors, which are the ones that decide how a
89
+ command is offered, had none.
90
+ - **The front page paraphrased the table instead of deriving it (CL-21).** *"Repo-wide/deep
91
+ compositions can take minutes … use deep jobs nightly"* was written in `cli`
92
+ beside the model it described, so it aged separately from the anchors it
93
+ paraphrased. It is generated from `cache_model.cost_sentence()` now: refreshing
94
+ a measurement refreshes the prose, and a battery asserts the front page contains
95
+ exactly what the model generates.
96
+ - **The performance gate had no baseline to compare against (C3-98).** F-AP shipped
97
+ the detector in 4.13.0 and it has run nightly since, self-testing that a
98
+ synthetic 3× regression would fail — against `docs/perf/baselines/gate-latest`,
99
+ a directory that was never created. Every run ended in the gate refusing to
100
+ report green (*"a gate that cannot be red is not evidence"*), which is why eight
101
+ consecutive field evaluations found no evidence that any benchmark gates a
102
+ release. The baseline is committed: six cells on BroadleafCommerce, warm, five
103
+ runs each, captured on the runner at 4.18.0, with provenance and a refresh
104
+ procedure beside them. First real comparison passed with `regressions: []`, and
105
+ the observed runner noise floor — ±5 %, widest on the shortest cell — is
106
+ published next to the 20 % threshold it has to be read against.
107
+ - **The gate's exclusion list quoted a deleted cost (C3-99).** `risk` was excluded
108
+ because it took *54 minutes* on the gate repository. Since C3-96 it takes
109
+ **68 s** there. The reason now says so, and names the only thing still keeping
110
+ it out: no baseline cell exists for it yet.
111
+ - **Stale cost claims elsewhere in the documentation.** README (the proof table's
112
+ caveat and the problem statement), `USER_GUIDE` (the "Start here" framing and
113
+ the spinner paragraph), `docs/CACHE.md` (regenerated), `docs/perf/REGRESSION-GATE.md`
114
+ §3, and the module docstrings of `execution_plan`, `phased_run` and `detach`,
115
+ where a 408 s / 2 351 s cost was narrated in the present tense.
116
+
117
+ **Deliberately not in this release:** the `chunk-file -c` remap. The guide says the
118
+ short form moves from `--chunk` to `--copy` "at the next major"; this major
119
+ changes no invocation, and breaking a working command line as a side effect of a
120
+ documentation-truth release would be the wrong trade. It waits for a major that
121
+ changes the command surface on purpose.
122
+
123
+ **Not changed:** any analysis, any payload, any schema. Every rule, every count and
124
+ every verdict this build produces is byte-identical to 4.18.0's.
125
+
5
126
  ## [4.18.0] — 2026-08-10
6
127
 
7
128
  **A field battery over the test repositories, run against 4.17.0 and aimed first
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 4.18.0
3
+ Version: 5.0.1
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
@@ -42,7 +42,7 @@ Description-Content-Type: text/markdown
42
42
 
43
43
  **Context · Impact · Migration · Architecture · Review — everything from one structural model.**
44
44
 
45
- ![Version](https://img.shields.io/badge/version-4.18.0-blue)
45
+ ![Version](https://img.shields.io/badge/version-5.0.1-blue)
46
46
  ![Python](https://img.shields.io/badge/python-3.9%2B-green)
47
47
 
48
48
  > **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
@@ -54,7 +54,7 @@ Description-Content-Type: text/markdown
54
54
 
55
55
  ## The problem
56
56
 
57
- Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On small and mid-sized repos that cost is seconds; on large Java/Spring monoliths, repo-wide semantic composition can be minutes. Multiply that by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
57
+ Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On a large Java/Spring monolith that is thousands of files of parsing per turn, repeated for every question asked about the same unchanged tree. Multiply it by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
58
58
 
59
59
  ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, later invocations reuse pre-built context whenever their command can consume the warmed layers. The repo doesn't change? The cache doesn't expire.
60
60
 
@@ -69,7 +69,7 @@ ASK Engine solves this with a persistent structural cache keyed on file content
69
69
  | Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
70
70
  | BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
71
71
 
72
- These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most. Inventory commands scale with file count. Repo-wide/deep compositions such as `risk`, `audit-report` and large `spring-audit` runs can take minutes on multi-thousand-endpoint repositories and belong in a supervised or nightly job unless CI sets an explicit budget.
72
+ These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most, and inventory commands scale with file count. What a repository-wide analysis costs tracks the build more than the file count: on one 3,342-file monolith, at one commit, `spring-audit` measured 2,351s on 4.11.0 and **8.4s on 4.18.0** with a byte-identical payload — so ASK publishes measured anchors and the release each was taken on, and never projects a duration for your repository. `ask cache model` prints both anchors per command, and `risk` — the one composition still measured in the tens of seconds at that size — is the one to give a budget or a detached run.
73
73
 
74
74
  With the right command class, ASK Engine becomes **constant infrastructure** inside agent loops — call the fast/context surfaces before edits and reserve deep compositions for the points where their evidence is worth the runtime.
75
75
 
@@ -126,7 +126,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
126
126
  # pip / pipx
127
127
  pipx install sourcecode # or: pip install sourcecode
128
128
 
129
- ask version # ask 4.18.0 — and, on a build that has aged,
129
+ ask version # ask 5.0.1 — and, on a build that has aged,
130
130
  # how many releases have probably shipped since
131
131
  ```
132
132
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Context · Impact · Migration · Architecture · Review — everything from one structural model.**
6
6
 
7
- ![Version](https://img.shields.io/badge/version-4.18.0-blue)
7
+ ![Version](https://img.shields.io/badge/version-5.0.1-blue)
8
8
  ![Python](https://img.shields.io/badge/python-3.9%2B-green)
9
9
 
10
10
  > **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
@@ -16,7 +16,7 @@
16
16
 
17
17
  ## The problem
18
18
 
19
- Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On small and mid-sized repos that cost is seconds; on large Java/Spring monoliths, repo-wide semantic composition can be minutes. Multiply that by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
19
+ Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On a large Java/Spring monolith that is thousands of files of parsing per turn, repeated for every question asked about the same unchanged tree. Multiply it by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
20
20
 
21
21
  ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, later invocations reuse pre-built context whenever their command can consume the warmed layers. The repo doesn't change? The cache doesn't expire.
22
22
 
@@ -31,7 +31,7 @@ ASK Engine solves this with a persistent structural cache keyed on file content
31
31
  | Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
32
32
  | BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
33
33
 
34
- These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most. Inventory commands scale with file count. Repo-wide/deep compositions such as `risk`, `audit-report` and large `spring-audit` runs can take minutes on multi-thousand-endpoint repositories and belong in a supervised or nightly job unless CI sets an explicit budget.
34
+ These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most, and inventory commands scale with file count. What a repository-wide analysis costs tracks the build more than the file count: on one 3,342-file monolith, at one commit, `spring-audit` measured 2,351s on 4.11.0 and **8.4s on 4.18.0** with a byte-identical payload — so ASK publishes measured anchors and the release each was taken on, and never projects a duration for your repository. `ask cache model` prints both anchors per command, and `risk` — the one composition still measured in the tens of seconds at that size — is the one to give a budget or a detached run.
35
35
 
36
36
  With the right command class, ASK Engine becomes **constant infrastructure** inside agent loops — call the fast/context surfaces before edits and reserve deep compositions for the points where their evidence is worth the runtime.
37
37
 
@@ -88,7 +88,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
88
88
  # pip / pipx
89
89
  pipx install sourcecode # or: pip install sourcecode
90
90
 
91
- ask version # ask 4.18.0 — and, on a build that has aged,
91
+ ask version # ask 5.0.1 — and, on a build that has aged,
92
92
  # how many releases have probably shipped since
93
93
  ```
94
94
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "4.18.0"
7
+ version = "5.0.1"
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"
@@ -33,7 +33,13 @@ import sys
33
33
  from pathlib import Path
34
34
 
35
35
  sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
36
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
36
37
  from sourcecode import perf # noqa: E402
38
+ # The directory a repository is checked out under is the harness's fact, not a
39
+ # second one this script or a workflow may restate: CI cloned the gate repo into
40
+ # `fleet/broadleaf` while the harness looked for `fleet/BroadleafCommerce`, so
41
+ # every nightly measured zero cells. `--print-config` now publishes the one name.
42
+ from perf_harness import FLEET # noqa: E402
37
43
 
38
44
 
39
45
  def load_cells(directory: Path) -> dict[str, dict]:
@@ -98,6 +104,8 @@ def _print_config() -> int:
98
104
  "threshold": perf.RELEASE_GATE_THRESHOLD,
99
105
  "repository": perf.RELEASE_GATE_REPO,
100
106
  "repository_url": perf.RELEASE_GATE_REPO_URL,
107
+ # Where the harness will look for that checkout, under the fleet root.
108
+ "fleet_subdir": FLEET.get(perf.RELEASE_GATE_REPO, perf.RELEASE_GATE_REPO),
101
109
  "repository_scale": perf.RELEASE_GATE_REPO_SCALE,
102
110
  "mode": perf.RELEASE_GATE_MODE,
103
111
  "min_runs": perf.RELEASE_GATE_MIN_RUNS,
@@ -122,6 +130,11 @@ def main() -> int:
122
130
  ap.add_argument("--allow-incomparable", action="store_true",
123
131
  help="Do not fail cells whose env/host differ. Off by default: "
124
132
  "an incomparable cell is an unmeasured one.")
133
+ ap.add_argument("--require-baseline", action="store_true",
134
+ help="Fail when the baseline holds no cells. A run with nothing "
135
+ "to compare against records every cell as `new` and passes; "
136
+ "that is a recording, not a gate, and CI must not read it "
137
+ "as one.")
125
138
  ap.add_argument("--report", type=Path, help="Write the perf-gate-v1 report here.")
126
139
  ap.add_argument("--table", type=Path, help="Write the release-notes markdown table here.")
127
140
  ap.add_argument("--self-test", action="store_true",
@@ -143,6 +156,12 @@ def main() -> int:
143
156
  f"which the gate reads as a failure, not a pass.", file=sys.stderr)
144
157
  return 1
145
158
  baseline = load_cells(args.baseline) if args.baseline else {}
159
+ if args.require_baseline and not baseline:
160
+ where = args.baseline if args.baseline else "<no --baseline given>"
161
+ print(f"no baseline cells in {where} — every cell would be recorded as "
162
+ f"`new` and the run would pass without comparing anything. A gate "
163
+ f"that cannot be red is not evidence.", file=sys.stderr)
164
+ return 1
146
165
 
147
166
  report = perf.gate_report(
148
167
  baseline, current,
@@ -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.18.0"
7
+ __version__ = "5.0.1"