sourcecode 3.2.2__tar.gz → 3.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. {sourcecode-3.2.2 → sourcecode-3.3.0}/CHANGELOG.md +11 -0
  2. {sourcecode-3.2.2 → sourcecode-3.3.0}/PKG-INFO +1 -1
  3. {sourcecode-3.2.2 → sourcecode-3.3.0}/pyproject.toml +1 -1
  4. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cli.py +33 -36
  6. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/license.py +68 -6
  7. {sourcecode-3.2.2 → sourcecode-3.3.0}/.github/workflows/build-windows.yml +0 -0
  8. {sourcecode-3.2.2 → sourcecode-3.3.0}/.gitignore +0 -0
  9. {sourcecode-3.2.2 → sourcecode-3.3.0}/.ruff.toml +0 -0
  10. {sourcecode-3.2.2 → sourcecode-3.3.0}/CONTRIBUTING.md +0 -0
  11. {sourcecode-3.2.2 → sourcecode-3.3.0}/LICENSE +0 -0
  12. {sourcecode-3.2.2 → sourcecode-3.3.0}/README.md +0 -0
  13. {sourcecode-3.2.2 → sourcecode-3.3.0}/SECURITY.md +0 -0
  14. {sourcecode-3.2.2 → sourcecode-3.3.0}/raw +0 -0
  15. {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/compare_integration_engines.py +0 -0
  16. {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/customer_smoke_test.sh +0 -0
  17. {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/generate_jdk_exports.py +0 -0
  18. {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/perf_harness.py +0 -0
  19. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/adaptive_scanner.py +0 -0
  20. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/archetype.py +0 -0
  21. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architectural_baseline.py +0 -0
  22. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architectural_delta.py +0 -0
  23. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architecture_analyzer.py +0 -0
  24. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architecture_summary.py +0 -0
  25. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/ast_extractor.py +0 -0
  26. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cache.py +0 -0
  27. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cache_model.py +0 -0
  28. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/call_surface.py +0 -0
  29. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/caller_metrics.py +0 -0
  30. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/canonical_ir.py +0 -0
  31. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/chain_rules.py +0 -0
  32. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/change_plan.py +0 -0
  33. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cir_graphs.py +0 -0
  34. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/classifier.py +0 -0
  35. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/code_notes_analyzer.py +0 -0
  36. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/compare.py +0 -0
  37. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/confidence_analyzer.py +0 -0
  38. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/constraint_diff.py +0 -0
  39. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_cache.py +0 -0
  40. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_graph.py +0 -0
  41. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_scorer.py +0 -0
  42. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_summarizer.py +0 -0
  43. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/contract_diff.py +0 -0
  44. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/contract_model.py +0 -0
  45. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/contract_pipeline.py +0 -0
  46. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/coverage_parser.py +0 -0
  47. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/dependency_analyzer.py +0 -0
  48. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/deployment_prefix.py +0 -0
  49. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/__init__.py +0 -0
  50. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/base.py +0 -0
  51. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
  52. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/dart.py +0 -0
  53. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/dotnet.py +0 -0
  54. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/elixir.py +0 -0
  55. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/go.py +0 -0
  56. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/heuristic.py +0 -0
  57. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/hybrid.py +0 -0
  58. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/java.py +0 -0
  59. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  60. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/nodejs.py +0 -0
  61. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/parsers.py +0 -0
  62. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/php.py +0 -0
  63. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/project.py +0 -0
  64. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/python.py +0 -0
  65. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/ruby.py +0 -0
  66. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/rust.py +0 -0
  67. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/systems.py +0 -0
  68. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/terraform.py +0 -0
  69. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/tooling.py +0 -0
  70. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/doc_analyzer.py +0 -0
  71. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
  72. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/endpoint_literals.py +0 -0
  73. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/endpoint_metrics.py +0 -0
  74. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/entrypoint_classifier.py +0 -0
  75. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/env_analyzer.py +0 -0
  76. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/envelope.py +0 -0
  77. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/error_schema.py +0 -0
  78. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/evidence_provider.py +0 -0
  79. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/explain.py +0 -0
  80. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/facts/__init__.py +0 -0
  81. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/facts/registry.json +0 -0
  82. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/file_chunker.py +0 -0
  83. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/file_classifier.py +0 -0
  84. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/filter_surface.py +0 -0
  85. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/format_contract.py +0 -0
  86. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/fqn_utils.py +0 -0
  87. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/git_analyzer.py +0 -0
  88. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/graph_analyzer.py +0 -0
  89. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/graph_evidence.py +0 -0
  90. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/hibernate_strat.py +0 -0
  91. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/integration_coordinates.py +0 -0
  92. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/jdk_exports.py +0 -0
  93. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/__init__.py +0 -0
  94. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  95. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  96. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  97. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  98. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  99. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/orchestrator.py +0 -0
  100. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/registry.py +0 -0
  101. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/runner.py +0 -0
  102. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/server.py +0 -0
  103. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp_nudge.py +0 -0
  104. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/metrics_analyzer.py +0 -0
  105. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/migrate_check.py +0 -0
  106. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/migration_blast.py +0 -0
  107. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/openapi_surface.py +0 -0
  108. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/output_budget.py +0 -0
  109. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/parse_cache.py +0 -0
  110. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/path_filters.py +0 -0
  111. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/perf.py +0 -0
  112. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/posture.py +0 -0
  113. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/pr_comment_renderer.py +0 -0
  114. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/pr_impact.py +0 -0
  115. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/prepare_context.py +0 -0
  116. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/progress.py +0 -0
  117. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/ranking_engine.py +0 -0
  118. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/readiness_timeline.py +0 -0
  119. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/reconciliation.py +0 -0
  120. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/redactor.py +0 -0
  121. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/reference_facts.py +0 -0
  122. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/relevance_scorer.py +0 -0
  123. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/rename_refactor.py +0 -0
  124. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/repo_classifier.py +0 -0
  125. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/repository_ir.py +0 -0
  126. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/__init__.py +0 -0
  127. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/context.py +0 -0
  128. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/errors.py +0 -0
  129. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/executor.py +0 -0
  130. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/planner.py +0 -0
  131. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/query.py +0 -0
  132. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/request.py +0 -0
  133. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/resolution.py +0 -0
  134. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/result.py +0 -0
  135. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/retriever.py +0 -0
  136. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/runtime.py +0 -0
  137. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps.py +0 -0
  138. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  139. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
  140. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
  141. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
  142. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
  143. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  144. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/ris.py +0 -0
  145. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/runtime_classifier.py +0 -0
  146. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/scanner.py +0 -0
  147. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/schema.py +0 -0
  148. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
  149. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/security_config.py +0 -0
  150. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/security_posture.py +0 -0
  151. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_analyzer.py +0 -0
  152. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_impact_engine.py +0 -0
  153. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_integration_engine.py +0 -0
  154. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_services.py +0 -0
  155. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/serializer.py +0 -0
  156. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_event_topology.py +0 -0
  157. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_findings.py +0 -0
  158. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_impact.py +0 -0
  159. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_model.py +0 -0
  160. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_profiles.py +0 -0
  161. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_properties.py +0 -0
  162. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_security_audit.py +0 -0
  163. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_semantic.py +0 -0
  164. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
  165. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/summarizer.py +0 -0
  166. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/__init__.py +0 -0
  167. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/config.py +0 -0
  168. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/consent.py +0 -0
  169. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/events.py +0 -0
  170. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/filters.py +0 -0
  171. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/transport.py +0 -0
  172. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/test_sources.py +0 -0
  173. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/token_estimate.py +0 -0
  174. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/tree_utils.py +0 -0
  175. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/type_usage_surface.py +0 -0
  176. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/validation_inference.py +0 -0
  177. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/validation_surface.py +0 -0
  178. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/verify_edit.py +0 -0
  179. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/verify_repo.py +0 -0
  180. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/verify_rules.py +0 -0
  181. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/version_check.py +0 -0
  182. {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/workspace.py +0 -0
  183. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/README.md +0 -0
  184. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/get-license/index.ts +0 -0
  185. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  186. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/telemetry/index.ts +0 -0
  187. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/sql/license_event_ordering.sql +0 -0
  188. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/sql/licensing_schema.sql +0 -0
  189. {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/sql/telemetry_events.sql +0 -0
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.3.0] — 2026-07-29
6
+
7
+ **A default you must remember to disable is the wrong default for someone else's code.**
8
+ Telemetry moves from opt-out to opt-in. A minor and not a patch: no API changed, but a default
9
+ about data leaving the machine did, and that is a change a user must be told about rather than
10
+ discover.
11
+
12
+ **Upgrade note.** If you ever ran `ask telemetry enable` or `ask telemetry disable`, nothing
13
+ changes for you — your choice is on record and is honoured. If you never chose, telemetry is
14
+ now off and `ask telemetry enable` is how you turn it on.
15
+
5
16
  ### Changed
6
17
 
7
18
  - **Telemetry is opt-in** (P-1). It was opt-out; with no explicit choice on record, nothing is
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 3.2.2
3
+ Version: 3.3.0
4
4
  Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
5
  License-File: LICENSE
6
6
  Keywords: agents,ai,codebase,context,developer-tools,llm
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "3.2.2"
7
+ version = "3.3.0"
8
8
  description = "Persistent structural context and ultra-fast repeated analysis for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -4,4 +4,4 @@ ASK Engine is the product. ``ask`` is the canonical CLI command; ``sourcecode``
4
4
  the legacy compatibility alias and the Python/PyPI package name. See
5
5
  docs/PRODUCT_IDENTITY.md (normative)."""
6
6
 
7
- __version__ = "3.2.2"
7
+ __version__ = "3.3.0"
@@ -8105,47 +8105,44 @@ def auth_status_cmd() -> None:
8105
8105
  """Show current authentication and plan status."""
8106
8106
  import json as _json
8107
8107
  try:
8108
- from sourcecode.license import (
8109
- _PRO_UNLOCK_ALL as _unlock,
8110
- _license_data as _ld,
8111
- is_pro as _ip,
8112
- )
8108
+ from sourcecode.license import _license_data as _ld, entitlement as _entitlement
8109
+ _ent = _entitlement()
8113
8110
  except Exception:
8114
8111
  _ld = None
8115
- _ip = False
8116
- _unlock = False
8117
-
8118
- # While the early-adoption unlock is on, every Pro command runs. Reporting
8119
- # `pro: false` here contradicted the --help header and the commands' own
8120
- # behaviour: the status has to describe the gating that is actually in force,
8121
- # not the credential that happens to be absent.
8122
- _gating = {
8123
- "pro_gating": "disabled" if _unlock else "enabled",
8124
- "pro_effective": bool(_ip or _unlock),
8125
- }
8126
- if _unlock:
8127
- _gating["pro_reason"] = "early-adoption unlock: Pro commands run without a license"
8128
-
8129
- if not _ld:
8130
- out: dict = {
8131
- "status": "unauthenticated",
8132
- "pro": bool(_unlock),
8133
- **_gating,
8112
+ _ent = {
8113
+ "entitlement": "free", "source": "free_tier", "authenticated": False,
8114
+ "paywall_active": True, "when_it_changes": "", "free_repo_java_file_limit": None,
8134
8115
  }
8135
- sys.stdout.write(_json.dumps(out, ensure_ascii=False) + "\n")
8136
- sys.stdout.flush()
8137
- return
8138
8116
 
8139
- out = {
8140
- "status": "authenticated",
8141
- "auth_method": _ld.get("auth_method", "license_key"),
8142
- "email": _ld.get("email", ""),
8143
- "plan": _ld.get("plan", "unknown"),
8144
- "plan_status": _ld.get("status", "unknown"),
8145
- "pro": _ip,
8146
- "validated_at": _ld.get("validated_at") or _ld.get("activated_at") or "",
8147
- **_gating,
8117
+ # P-2: one authority (`license.entitlement`) answers "what runs here, and why".
8118
+ # The legacy keys below are *derived* from it rather than computed a second
8119
+ # time — that is what stops `{"status": "unauthenticated", "pro": true}` from
8120
+ # reappearing. They are deprecated and will be removed in a future major.
8121
+ _pro = _ent["entitlement"] == "pro"
8122
+ _legacy = {
8123
+ "pro": _pro,
8124
+ "pro_effective": _pro,
8125
+ "pro_gating": "enabled" if _ent["paywall_active"] else "disabled",
8148
8126
  }
8127
+ if _ent["source"] == "early_adoption_unlock":
8128
+ _legacy["pro_reason"] = "early-adoption unlock: Pro commands run without a license"
8129
+
8130
+ out: dict = {
8131
+ "status": "authenticated" if _ent["authenticated"] else "unauthenticated",
8132
+ **_ent,
8133
+ **_legacy,
8134
+ "deprecated_fields": ["pro", "pro_effective", "pro_gating", "pro_reason"],
8135
+ }
8136
+ if _ld:
8137
+ out.update({
8138
+ "auth_method": _ld.get("auth_method", "license_key"),
8139
+ "email": _ld.get("email", ""),
8140
+ "plan": _ld.get("plan", "unknown"),
8141
+ # The authority reads a missing status as active, so reporting
8142
+ # "unknown" here would contradict the entitlement in the same object.
8143
+ "plan_status": _ld.get("status", "active"),
8144
+ "validated_at": _ld.get("validated_at") or _ld.get("activated_at") or "",
8145
+ })
8149
8146
  sys.stdout.write(_json.dumps(out, indent=2, ensure_ascii=False) + "\n")
8150
8147
  sys.stdout.flush()
8151
8148
 
@@ -376,16 +376,78 @@ def _maybe_revalidate() -> None:
376
376
  pass
377
377
 
378
378
 
379
- def _init() -> None:
380
- global _license_data, is_pro
381
- _license_data = _load_license_file()
382
- is_pro = (
379
+ def entitlement() -> dict:
380
+ """The one answer to "what runs here today, and why" (P-2).
381
+
382
+ `auth status` used to publish four fields about this — `status`, `pro`,
383
+ `pro_gating`, `pro_effective`, plus a `pro_reason` sentence — and they read as
384
+ a contradiction: `{"status": "unauthenticated", "pro": true}`. Each field was
385
+ true on its own axis; together they told a buyer nothing about what they have,
386
+ why they have it, or what changes when it ends. That is the ADR-0008 pattern
387
+ exactly, on the commercial surface instead of an analysis one.
388
+
389
+ Every published entitlement field is derived from this dict and nowhere else.
390
+
391
+ Keys:
392
+ entitlement "pro" | "free" — what actually runs right now
393
+ source why: "license_key" | "early_adoption_unlock" | "free_tier"
394
+ authenticated whether a credential is on this machine (an independent
395
+ fact: today one can be entitled to Pro without one)
396
+ paywall_active whether the paywall is enforcing anything at all
397
+ when_it_changes what a user loses when `source` stops applying, in the
398
+ terms the gate actually uses — never a price
399
+ free_repo_java_file_limit
400
+ the number the size gate compares against
401
+ """
402
+ authenticated = _license_data is not None
403
+ licensed = bool(
383
404
  _license_data is not None
384
405
  and _license_data.get("plan") == "pro"
385
406
  and _license_data.get("status", "active") != "inactive"
386
407
  )
387
- if _PRO_UNLOCK_ALL:
388
- is_pro = True # TEMPORARY: early-adoption Pro unlock (see _PRO_UNLOCK_ALL)
408
+ if licensed:
409
+ source = "license_key"
410
+ elif _PRO_UNLOCK_ALL:
411
+ source = "early_adoption_unlock"
412
+ else:
413
+ source = "free_tier"
414
+
415
+ if source == "license_key":
416
+ when = "Your licence entitles you to Pro; nothing changes while it stays active."
417
+ elif source == "early_adoption_unlock":
418
+ when = (
419
+ "Pro runs without a licence during early adoption. When that ends, every command "
420
+ f"still runs at full output on repositories up to {_FREE_REPO_JAVA_FILE_LIMIT} Java "
421
+ "source files; above that, the heavy-analysis commands ask for Pro. Capability is "
422
+ "never what is gated — size, automation and team are."
423
+ )
424
+ else:
425
+ when = (
426
+ f"Every command runs at full output on repositories up to {_FREE_REPO_JAVA_FILE_LIMIT} "
427
+ "Java source files. Above that, the heavy-analysis commands require Pro."
428
+ )
429
+
430
+ return {
431
+ "entitlement": "pro" if (licensed or _PRO_UNLOCK_ALL) else "free",
432
+ "source": source,
433
+ "authenticated": authenticated,
434
+ "paywall_active": not _PRO_UNLOCK_ALL,
435
+ "when_it_changes": when,
436
+ "free_repo_java_file_limit": _FREE_REPO_JAVA_FILE_LIMIT,
437
+ }
438
+
439
+
440
+ def _init() -> None:
441
+ """Load the credential and derive the entitlement from the one authority.
442
+
443
+ `is_pro` is what every gate reads (`can_use`, `require_feature`), and it is
444
+ computed here from `entitlement()` rather than beside it — a second copy of
445
+ this rule is how `auth status` came to publish a state the commands
446
+ contradicted (P-2).
447
+ """
448
+ global _license_data, is_pro
449
+ _license_data = _load_license_file()
450
+ is_pro = entitlement()["entitlement"] == "pro"
389
451
 
390
452
 
391
453
  _init()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes