sourcecode 3.6.0__tar.gz → 3.7.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 (194) hide show
  1. {sourcecode-3.6.0 → sourcecode-3.7.0}/CHANGELOG.md +139 -0
  2. {sourcecode-3.6.0 → sourcecode-3.7.0}/PKG-INFO +1 -1
  3. {sourcecode-3.6.0 → sourcecode-3.7.0}/pyproject.toml +1 -1
  4. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/change_plan.py +5 -1
  6. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cli.py +214 -79
  7. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/compare.py +5 -3
  8. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/explain.py +11 -0
  9. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/output_budget.py +7 -2
  10. sourcecode-3.7.0/src/sourcecode/pipe_contract.py +208 -0
  11. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/repository_ir.py +18 -0
  12. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/serializer.py +93 -61
  13. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_findings.py +86 -0
  14. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_impact.py +18 -1
  15. sourcecode-3.7.0/src/sourcecode/target_admission.py +168 -0
  16. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/verify_edit.py +32 -9
  17. {sourcecode-3.6.0 → sourcecode-3.7.0}/.github/workflows/build-windows.yml +0 -0
  18. {sourcecode-3.6.0 → sourcecode-3.7.0}/.gitignore +0 -0
  19. {sourcecode-3.6.0 → sourcecode-3.7.0}/.ruff.toml +0 -0
  20. {sourcecode-3.6.0 → sourcecode-3.7.0}/CONTRIBUTING.md +0 -0
  21. {sourcecode-3.6.0 → sourcecode-3.7.0}/LICENSE +0 -0
  22. {sourcecode-3.6.0 → sourcecode-3.7.0}/README.md +0 -0
  23. {sourcecode-3.6.0 → sourcecode-3.7.0}/SECURITY.md +0 -0
  24. {sourcecode-3.6.0 → sourcecode-3.7.0}/raw +0 -0
  25. {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/compare_integration_engines.py +0 -0
  26. {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/customer_smoke_test.sh +0 -0
  27. {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/generate_jdk_exports.py +0 -0
  28. {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/perf_harness.py +0 -0
  29. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/adaptive_scanner.py +0 -0
  30. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/archetype.py +0 -0
  31. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architectural_baseline.py +0 -0
  32. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architectural_delta.py +0 -0
  33. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architecture_analyzer.py +0 -0
  34. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architecture_summary.py +0 -0
  35. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/ast_extractor.py +0 -0
  36. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cache.py +0 -0
  37. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cache_model.py +0 -0
  38. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/call_surface.py +0 -0
  39. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/caller_metrics.py +0 -0
  40. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/caller_reach.py +0 -0
  41. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/canonical_ir.py +0 -0
  42. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/chain_rules.py +0 -0
  43. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cir_graphs.py +0 -0
  44. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/classifier.py +0 -0
  45. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/code_notes_analyzer.py +0 -0
  46. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/confidence_analyzer.py +0 -0
  47. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/constraint_diff.py +0 -0
  48. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_cache.py +0 -0
  49. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_graph.py +0 -0
  50. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_scorer.py +0 -0
  51. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_summarizer.py +0 -0
  52. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/contract_diff.py +0 -0
  53. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/contract_model.py +0 -0
  54. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/contract_pipeline.py +0 -0
  55. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/coverage_parser.py +0 -0
  56. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/degradation.py +0 -0
  57. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/dependency_analyzer.py +0 -0
  58. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/deployment_prefix.py +0 -0
  59. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/__init__.py +0 -0
  60. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/base.py +0 -0
  61. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
  62. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/dart.py +0 -0
  63. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/dotnet.py +0 -0
  64. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/elixir.py +0 -0
  65. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/go.py +0 -0
  66. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/heuristic.py +0 -0
  67. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/hybrid.py +0 -0
  68. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/java.py +0 -0
  69. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  70. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/nodejs.py +0 -0
  71. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/parsers.py +0 -0
  72. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/php.py +0 -0
  73. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/project.py +0 -0
  74. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/python.py +0 -0
  75. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/ruby.py +0 -0
  76. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/rust.py +0 -0
  77. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/systems.py +0 -0
  78. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/terraform.py +0 -0
  79. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/tooling.py +0 -0
  80. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/doc_analyzer.py +0 -0
  81. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
  82. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/endpoint_literals.py +0 -0
  83. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/endpoint_metrics.py +0 -0
  84. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/entrypoint_classifier.py +0 -0
  85. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/env_analyzer.py +0 -0
  86. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/envelope.py +0 -0
  87. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/error_schema.py +0 -0
  88. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/evidence_provider.py +0 -0
  89. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/facts/__init__.py +0 -0
  90. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/facts/registry.json +0 -0
  91. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/file_chunker.py +0 -0
  92. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/file_classifier.py +0 -0
  93. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/filter_surface.py +0 -0
  94. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/format_contract.py +0 -0
  95. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/fqn_utils.py +0 -0
  96. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/git_analyzer.py +0 -0
  97. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/graph_analyzer.py +0 -0
  98. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/graph_evidence.py +0 -0
  99. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/hibernate_strat.py +0 -0
  100. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/integration_coordinates.py +0 -0
  101. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/jdk_exports.py +0 -0
  102. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/license.py +0 -0
  103. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/__init__.py +0 -0
  104. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  105. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  106. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  107. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  108. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  109. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/orchestrator.py +0 -0
  110. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/registry.py +0 -0
  111. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/runner.py +0 -0
  112. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/server.py +0 -0
  113. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp_nudge.py +0 -0
  114. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/metrics_analyzer.py +0 -0
  115. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/migrate_check.py +0 -0
  116. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/migration_blast.py +0 -0
  117. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/openapi_surface.py +0 -0
  118. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/parse_cache.py +0 -0
  119. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/path_admission.py +0 -0
  120. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/path_filters.py +0 -0
  121. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/perf.py +0 -0
  122. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/posture.py +0 -0
  123. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/pr_comment_renderer.py +0 -0
  124. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/pr_impact.py +0 -0
  125. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/prepare_context.py +0 -0
  126. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/progress.py +0 -0
  127. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/ranking_engine.py +0 -0
  128. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/readiness_timeline.py +0 -0
  129. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/reconciliation.py +0 -0
  130. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/redactor.py +0 -0
  131. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/reference_facts.py +0 -0
  132. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/relevance_scorer.py +0 -0
  133. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/rename_refactor.py +0 -0
  134. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/repo_classifier.py +0 -0
  135. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/__init__.py +0 -0
  136. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/context.py +0 -0
  137. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/errors.py +0 -0
  138. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/executor.py +0 -0
  139. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/planner.py +0 -0
  140. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/query.py +0 -0
  141. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/request.py +0 -0
  142. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/resolution.py +0 -0
  143. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/result.py +0 -0
  144. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/retriever.py +0 -0
  145. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/runtime.py +0 -0
  146. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps.py +0 -0
  147. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  148. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
  149. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
  150. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
  151. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
  152. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  153. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/ris.py +0 -0
  154. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/runtime_classifier.py +0 -0
  155. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/scanner.py +0 -0
  156. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/schema.py +0 -0
  157. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
  158. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/security_config.py +0 -0
  159. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/security_posture.py +0 -0
  160. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_analyzer.py +0 -0
  161. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_impact_engine.py +0 -0
  162. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_integration_engine.py +0 -0
  163. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_services.py +0 -0
  164. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_event_topology.py +0 -0
  165. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_model.py +0 -0
  166. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_profiles.py +0 -0
  167. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_properties.py +0 -0
  168. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_security_audit.py +0 -0
  169. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_semantic.py +0 -0
  170. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
  171. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/summarizer.py +0 -0
  172. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/__init__.py +0 -0
  173. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/config.py +0 -0
  174. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/consent.py +0 -0
  175. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/events.py +0 -0
  176. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/filters.py +0 -0
  177. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/transport.py +0 -0
  178. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/test_sources.py +0 -0
  179. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/token_estimate.py +0 -0
  180. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/tree_utils.py +0 -0
  181. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/type_usage_surface.py +0 -0
  182. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/validation_inference.py +0 -0
  183. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/validation_surface.py +0 -0
  184. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/verify_repo.py +0 -0
  185. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/verify_rules.py +0 -0
  186. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/version_check.py +0 -0
  187. {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/workspace.py +0 -0
  188. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/README.md +0 -0
  189. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/get-license/index.ts +0 -0
  190. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  191. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/telemetry/index.ts +0 -0
  192. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/sql/license_event_ordering.sql +0 -0
  193. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/sql/licensing_schema.sql +0 -0
  194. {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/sql/telemetry_events.sql +0 -0
@@ -1,5 +1,144 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.7.0] — 2026-08-01
4
+
5
+ **The exit-code contract and the C3 surface block.** Seven rows closed: the two the field named
6
+ as blocking for CI (exit codes over correct answers), the fourth and fifth appearance of a
7
+ curated list beside real data, and three surfaces that published a promise the payload did not
8
+ keep.
9
+
10
+ Minor and not patch, because a pipeline can see the difference: `plan` exits 1 where it exited 0
11
+ over a target it never resolved (C3-29), `ask <cmd> | head` exits 0 where a correct run used to
12
+ exit non-zero (C3-28), `--output FILE` carries the whole answer where it was silently trimmed
13
+ (C3-17), `--agent` publishes sections it used to omit (C3-10), and a path-shaped target that was
14
+ refused as ambiguous now resolves (C3-35).
15
+
16
+ ### Fixed
17
+
18
+ - **A broken output pipe is no longer a failed run** (C3-28, **exit code changes for
19
+ `ask <cmd> | head`**). `ask repo-ir . --force | head -c 100` returned the correct bytes and
20
+ exit 1; under `set -e` that stops a pipeline with no error anywhere to explain it — the field
21
+ named it one of two blockers for CI. One authority now says what a closed stream means
22
+ (`pipe_contract.py`, installed at the entry point): **a broken output stream changes nothing
23
+ except where the remaining bytes go.** The descriptor is redirected to the null device on the
24
+ first broken write and the command finishes and exits on its own terms.
25
+ - **It does not overwrite the command's own verdict.** `ask impact <ambiguous target> | head`
26
+ still exits 1, because a consumer that stopped reading has no opinion about whether the
27
+ analysis resolved its target.
28
+ - Redirecting before the shutdown flush is what keeps Python from printing
29
+ `Exception ignored in: <_io.TextIOWrapper …>` and exiting 120 — the same defect wearing a
30
+ different number.
31
+ - **The wrapper covers `.buffer`, which is the whole fix**: payloads are written as bytes
32
+ through `sys.stdout.buffer` at the single emit seam, so a text-only wrapper sits beside the
33
+ one write this exists for. Measured: with the text wrapper alone, nothing changed.
34
+ - Only visible above a pipe buffer, which is why it looked intermittent: `endpoints` on a
35
+ small repository exits 0 either way, `repo-ir` on the same repository did not.
36
+
37
+ - **An unresolved target has one exit code across every command** (C3-29, **`plan` now exits 1
38
+ where it exited 0**). `plan <unknown> <repo>` ran to completion, emitted a plan-shaped payload
39
+ of zeros with `resolution: "not_found"` and exited **0**, while `impact` on the same input
40
+ exited 1 — so a gate could not tell "nothing to review" from "I never found what you asked
41
+ about". One authority (`target_admission.py`), four commands rebound (`impact`,
42
+ `impact-chain`, `plan`, `explain`), and the two other copies of the same literal set
43
+ (`compare`, `change_plan`) now read it instead of restating it.
44
+ - **Ambiguity is the same fact, and it was not in the field report.** A target matching
45
+ several classes returns `ambiguous_path`, empty results and a message asking for the full
46
+ FQN — the command declined to answer — and `impact` exited **0** on it. Measured on a
47
+ purpose-built two-class fixture, since no battery repository carries the shape.
48
+ - Unresolved is **1, not 2**: 2 is reserved by the `verify` family for a run that could not
49
+ look, and this run looked. Partial and expanded resolutions stay 0 — they are answers about
50
+ the target the caller named.
51
+ - `plan`'s `Note:` on stderr is gone with it: the payload already carries the statement, and
52
+ a successful-looking run should not be narrating on stderr (the `plan` half of C3-34).
53
+
54
+ - **`--help` reaches inside command groups** (C4-7). `ask cache model` — what a warm buys each
55
+ command, per layer, including the commands it buys nothing for — appeared in no help text at
56
+ all: the root catalogue was generated (C4-1/C4-2) but the Cache and Auth blocks under it were
57
+ three lines somebody typed by hand. The blocks are now built from the registered groups, so a
58
+ subcommand is listed the moment it is registered; a group too large to name in full (`retrieve`,
59
+ 29 parked intents) publishes its **exact count** and a pointer, never silence. The battery
60
+ fails if a subcommand of a listed group is missing, or if a collapsed group's count drifts.
61
+
62
+ - **A successful run says nothing on stderr — measured over the commands, not over a list**
63
+ (C3-34, the `repo-ir` half). `ask repo-ir . --force` wrote an 82-byte size advisory on a run
64
+ that exited 0 with the IR on stdout, which PowerShell 5.1 raises as a `NativeCommandError`.
65
+ The advisory is terminal-gated now, like every other notice, and so is the `--exclude`
66
+ directory warning and the output-budget trim warning found beside it.
67
+ - **The list was the defect.** `tests/test_stderr_purity_matrix.py` enumerated 13 commands by
68
+ hand for the fourth time in three releases; the rows are now **discovered from the CLI**,
69
+ with every command either driven or carrying a written reason it cannot be. Nine more
70
+ commands are driven as a result, `cache` subcommands included.
71
+ - The `repo-ir` row builds a repository large enough for the advisory to actually fire and
72
+ **asserts it fired**, because a row that never reaches the branch proves nothing.
73
+
74
+ - **`--output FILE` is no longer trimmed to an agent's context window** (C3-17). The payload
75
+ budget exists because a context window is finite — it is a constraint on **stdout**. Written
76
+ to a file it cut the answer anyway, dropped `key_dependencies` entirely, and the note
77
+ explaining the cut advised `--output`, the flag already in use. Two of six call sites had the
78
+ rule and four did not (`prepare-context`, `modernize`, the cached-view rebuild, and `impact`
79
+ in part), so it now lives in one seam (`cli._apply_budget`) and a battery fails if a seventh
80
+ call site decides for itself.
81
+ - **The cache had the same defect one layer down**, found while field-checking the seam:
82
+ `prepare-context` stored the document *after* trimming, so the first stdout run poisoned the
83
+ cache and every later `--output FILE` hit received a stdout-sized answer. The cache stores
84
+ the analysis now and the budget is applied per run — measured on alfresco-community-repo:
85
+ stdout 5 files, cache hit to a file 26.
86
+ - **`--full` says what it does.** It raises the caps (boundaries and DTO mappers in full,
87
+ `file_relevance` to 40); it never removed them — under `--agent --full` the file list stayed
88
+ capped at 40 of 710 while the flag's help promised "remove truncation limits".
89
+
90
+ - **`--agent` cannot publish less than `--compact`** (C3-10). `--compact` documents
91
+ `security_surface` "when custom security annotations detected" and closes with "use `--agent`
92
+ for maximum signal", while `--agent` was assembled from its own hand-written list of sections:
93
+ measured on BroadleafCommerce it omitted `deployment` and `language_version` outright, and
94
+ nothing stopped the security surface going the same way. Both views now read one authority
95
+ (`serializer.JAVA_SPRING_SECTIONS`), and the battery fails on any section `--compact` publishes
96
+ that `--agent` does not.
97
+
98
+ - **A path that names one file resolves to that file** (C3-35). Every resolver reduced a
99
+ path-shaped target to its basename before anything looked at it, so
100
+ `ask impact src/main/java/com/a/Service.java` answered `ambiguous_path` and offered
101
+ `com.a.Service` **and** `com.b.Service` — being more specific made the answer worse. A path is
102
+ matched against the `source_file` each symbol came from, strongest tier first (exact, then
103
+ module-relative, then parent-relative), and nested types collapse to the type the file is about
104
+ (on eureka, `DiscoveryClient.java` declares its outer class and five inner ones). One authority
105
+ in `target_admission`, because three graphs answer target questions — the repo IR, and the CIR
106
+ that `explain` and `impact-chain` read, both of which used to answer `not_found` for a path.
107
+ Parity checked on eureka: by path and by name give byte-identical `stats`.
108
+
109
+ - **`verify-edit` stops paying for a diff it has already proved empty** (C3-32). It computed the
110
+ change set and then built the HEAD CIR *and* the working CIR unconditionally — on a clean tree
111
+ the second is the first by construction. Measured on a clean ofbiz-framework: **5.9 s -> 1.7 s**
112
+ warm. The shortcut is taken only when git actually answered: a failed `git diff` also returns an
113
+ empty list, and reading that as "nothing changed" would trade dead cost for a false green.
114
+
115
+ - **`spring-audit --compact`** (C3-31). The one analysis command with no summary mode: 1.99 MB for
116
+ 14 findings in the field, *"a context overflow against an LLM with no filter in between"*. The
117
+ weight is not the findings — on BroadleafCommerce `security_posture.endpoints` is 113 KB of a
118
+ 178 KB report, and the counts it supports are published beside it. `--compact` caps that list and
119
+ `findings` to their top 5, ordered by what asks something of the reader (`probably_exposed`
120
+ first; most severe first), and recomputes nothing: **178 KB -> 25 KB with every count
121
+ identical**. A flag changes how much is emitted, never the shape (C2-10) — each list stays a list
122
+ and the totals live in a `*_cap` sibling that exists only when the cap bit.
123
+
124
+
125
+ ### Documentation
126
+
127
+ - **Field evaluation #6 of 3.5.0 recorded** (`.planning/FIELD-EVAL-6-2026-08-01.md`, defect
128
+ ledger, development roadmap). Full 27-command catalogue, repository left byte-identical,
129
+ scored 8/10. Every reported defect was re-measured on 3.6.0 before it was written down: two
130
+ do not reproduce (one closed here as C3-15, one by the 3.5.0 admission authority) and the
131
+ re-measurement found two the evaluation did not report.
132
+ - **New rows**: C1-18 (profile population differs per command, and the narrower one is what an
133
+ agent reads) · C3-28/C3-29 (**exit codes that lie over correct answers** — a broken pipe
134
+ exits non-zero on a successful run, `plan` exits 0 on a target it did not resolve while
135
+ `impact` exits 1) · C3-30 (`verify --init`) · C3-31…C3-34 · C4-7 (`cache model` in no help
136
+ panel) · P-4 (`baseline` history nobody automated) · CL-7 (non-coverage: no dataflow, no
137
+ secrets outside Java/YAML, filter order not reconstructed) · CL-8 (`posture --diff` answers
138
+ conditionally because the profile is decided outside the repository).
139
+ - **The executive roadmap gains what the product does *not* do**, published beside the
140
+ capabilities, and the evaluation table is current through eval #6.
141
+
3
142
  ## [3.6.0] — 2026-08-01
4
143
 
5
144
  **The P0 block and the C1/C2 backlog.** Nine rows closed, three closed by measurement alone
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 3.6.0
3
+ Version: 3.7.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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "3.6.0"
7
+ version = "3.7.0"
8
8
  description = "Persistent structural context and ultra-fast repeated analysis for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -4,4 +4,4 @@ ASK Engine is the product. ``ask`` is the canonical CLI command; ``sourcecode``
4
4
  the legacy compatibility alias and the Python/PyPI package name. See
5
5
  docs/PRODUCT_IDENTITY.md (normative)."""
6
6
 
7
- __version__ = "3.6.0"
7
+ __version__ = "3.7.0"
@@ -88,7 +88,11 @@ def build_change_plan(
88
88
  resolution = blast.get("resolution", "not_found")
89
89
 
90
90
  # Unresolvable target → return a plan-shaped resolution notice (never crash).
91
- if resolution in ("not_found", "ambiguous_path") or not blast.get("matched_fqns"):
91
+ # The set of resolutions that means "never found it" is one fact, and the CLI
92
+ # reads the same one to decide the exit code (C3-29).
93
+ from sourcecode.target_admission import is_unresolved
94
+
95
+ if is_unresolved(resolution) or not blast.get("matched_fqns"):
92
96
  return {
93
97
  "schema": CHANGE_PLAN_SCHEMA,
94
98
  "target": target,