sourcecode 2.5.7__tar.gz → 2.5.8__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 (160) hide show
  1. {sourcecode-2.5.7 → sourcecode-2.5.8}/CHANGELOG.md +48 -0
  2. {sourcecode-2.5.7 → sourcecode-2.5.8}/PKG-INFO +1 -1
  3. {sourcecode-2.5.7 → sourcecode-2.5.8}/pyproject.toml +1 -1
  4. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/ris.py +39 -2
  6. {sourcecode-2.5.7 → sourcecode-2.5.8}/.github/workflows/build-windows.yml +0 -0
  7. {sourcecode-2.5.7 → sourcecode-2.5.8}/.gitignore +0 -0
  8. {sourcecode-2.5.7 → sourcecode-2.5.8}/.ruff.toml +0 -0
  9. {sourcecode-2.5.7 → sourcecode-2.5.8}/CONTRIBUTING.md +0 -0
  10. {sourcecode-2.5.7 → sourcecode-2.5.8}/LICENSE +0 -0
  11. {sourcecode-2.5.7 → sourcecode-2.5.8}/README.md +0 -0
  12. {sourcecode-2.5.7 → sourcecode-2.5.8}/SECURITY.md +0 -0
  13. {sourcecode-2.5.7 → sourcecode-2.5.8}/raw +0 -0
  14. {sourcecode-2.5.7 → sourcecode-2.5.8}/scripts/compare_integration_engines.py +0 -0
  15. {sourcecode-2.5.7 → sourcecode-2.5.8}/scripts/customer_smoke_test.sh +0 -0
  16. {sourcecode-2.5.7 → sourcecode-2.5.8}/scripts/generate_jdk_exports.py +0 -0
  17. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/adaptive_scanner.py +0 -0
  18. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/archetype.py +0 -0
  19. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/architecture_analyzer.py +0 -0
  20. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/architecture_summary.py +0 -0
  21. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/ast_extractor.py +0 -0
  22. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/cache.py +0 -0
  23. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/call_surface.py +0 -0
  24. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/caller_metrics.py +0 -0
  25. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/canonical_ir.py +0 -0
  26. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/cir_graphs.py +0 -0
  27. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/classifier.py +0 -0
  28. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/cli.py +0 -0
  29. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/code_notes_analyzer.py +0 -0
  30. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/confidence_analyzer.py +0 -0
  31. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/context_cache.py +0 -0
  32. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/context_graph.py +0 -0
  33. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/context_scorer.py +0 -0
  34. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/context_summarizer.py +0 -0
  35. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/contract_model.py +0 -0
  36. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/contract_pipeline.py +0 -0
  37. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/coverage_parser.py +0 -0
  38. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/dependency_analyzer.py +0 -0
  39. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/__init__.py +0 -0
  40. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/base.py +0 -0
  41. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/csproj_parser.py +0 -0
  42. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/dart.py +0 -0
  43. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/dotnet.py +0 -0
  44. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/elixir.py +0 -0
  45. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/go.py +0 -0
  46. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/heuristic.py +0 -0
  47. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/hybrid.py +0 -0
  48. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/java.py +0 -0
  49. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/jvm_ext.py +0 -0
  50. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/nodejs.py +0 -0
  51. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/parsers.py +0 -0
  52. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/php.py +0 -0
  53. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/project.py +0 -0
  54. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/python.py +0 -0
  55. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/ruby.py +0 -0
  56. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/rust.py +0 -0
  57. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/systems.py +0 -0
  58. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/terraform.py +0 -0
  59. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/detectors/tooling.py +0 -0
  60. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/doc_analyzer.py +0 -0
  61. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/dynamic_argument_surface.py +0 -0
  62. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/endpoint_literals.py +0 -0
  63. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/endpoint_metrics.py +0 -0
  64. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/entrypoint_classifier.py +0 -0
  65. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/env_analyzer.py +0 -0
  66. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/error_schema.py +0 -0
  67. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/evidence_provider.py +0 -0
  68. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/explain.py +0 -0
  69. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/file_chunker.py +0 -0
  70. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/file_classifier.py +0 -0
  71. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/format_contract.py +0 -0
  72. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/fqn_utils.py +0 -0
  73. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/git_analyzer.py +0 -0
  74. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/graph_analyzer.py +0 -0
  75. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/graph_evidence.py +0 -0
  76. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/hibernate_strat.py +0 -0
  77. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/jdk_exports.py +0 -0
  78. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/license.py +0 -0
  79. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/__init__.py +0 -0
  80. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  81. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  82. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  83. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  84. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  85. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/orchestrator.py +0 -0
  86. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/registry.py +0 -0
  87. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/runner.py +0 -0
  88. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp/server.py +0 -0
  89. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/mcp_nudge.py +0 -0
  90. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/metrics_analyzer.py +0 -0
  91. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/migrate_check.py +0 -0
  92. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/openapi_surface.py +0 -0
  93. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/output_budget.py +0 -0
  94. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/path_filters.py +0 -0
  95. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/pr_comment_renderer.py +0 -0
  96. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/pr_impact.py +0 -0
  97. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/prepare_context.py +0 -0
  98. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/progress.py +0 -0
  99. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/ranking_engine.py +0 -0
  100. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/reconciliation.py +0 -0
  101. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/redactor.py +0 -0
  102. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/relevance_scorer.py +0 -0
  103. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/rename_refactor.py +0 -0
  104. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/repo_classifier.py +0 -0
  105. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/repository_ir.py +0 -0
  106. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/__init__.py +0 -0
  107. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/context.py +0 -0
  108. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/errors.py +0 -0
  109. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/executor.py +0 -0
  110. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/planner.py +0 -0
  111. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/query.py +0 -0
  112. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/request.py +0 -0
  113. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/resolution.py +0 -0
  114. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/result.py +0 -0
  115. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/retriever.py +0 -0
  116. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/runtime.py +0 -0
  117. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps.py +0 -0
  118. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
  119. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps_graph.py +0 -0
  120. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps_impact.py +0 -0
  121. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps_intf.py +0 -0
  122. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps_struct.py +0 -0
  123. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/retrieval/steps_txsec.py +0 -0
  124. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/runtime_classifier.py +0 -0
  125. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/scanner.py +0 -0
  126. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/schema.py +0 -0
  127. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/security_config.py +0 -0
  128. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/security_posture.py +0 -0
  129. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/semantic_analyzer.py +0 -0
  130. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/semantic_impact_engine.py +0 -0
  131. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/semantic_integration_engine.py +0 -0
  132. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/semantic_services.py +0 -0
  133. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/serializer.py +0 -0
  134. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_event_topology.py +0 -0
  135. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_findings.py +0 -0
  136. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_impact.py +0 -0
  137. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_model.py +0 -0
  138. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_security_audit.py +0 -0
  139. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_semantic.py +0 -0
  140. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/spring_tx_analyzer.py +0 -0
  141. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/summarizer.py +0 -0
  142. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/telemetry/__init__.py +0 -0
  143. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/telemetry/config.py +0 -0
  144. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/telemetry/consent.py +0 -0
  145. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/telemetry/events.py +0 -0
  146. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/telemetry/filters.py +0 -0
  147. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/telemetry/transport.py +0 -0
  148. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/tree_utils.py +0 -0
  149. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/type_usage_surface.py +0 -0
  150. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/validation_inference.py +0 -0
  151. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/validation_surface.py +0 -0
  152. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/version_check.py +0 -0
  153. {sourcecode-2.5.7 → sourcecode-2.5.8}/src/sourcecode/workspace.py +0 -0
  154. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/functions/README.md +0 -0
  155. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/functions/get-license/index.ts +0 -0
  156. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  157. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/functions/telemetry/index.ts +0 -0
  158. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/sql/license_event_ordering.sql +0 -0
  159. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/sql/licensing_schema.sql +0 -0
  160. {sourcecode-2.5.7 → sourcecode-2.5.8}/supabase/sql/telemetry_events.sql +0 -0
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.5.8] — 2026-07-17
4
+
5
+ **A count must name what it counted.** 2.5.7 taught the headline to say *"Polyglot
6
+ repository … no single stack owns this repository's architecture."* Three lines
7
+ below it, the same field still said:
8
+
9
+ > 1 project detected.
10
+ > Stack: console.
11
+ > Target: net6.0.
12
+
13
+ on the confluent `examples` monorepo — 20+ subprojects, mostly Java/Python/Go.
14
+
15
+ ### Fixed
16
+
17
+ - **`.NET` summary lines were narrated as claims about the repository
18
+ (P2-F-RESIDUE(c))** (`architecture_summary.py`): every one of those lines
19
+ counts `.csproj` files. They are facts about the .NET stack alone —
20
+ *"1 project detected"* is true of the dotnet stack and false of the repo, and
21
+ it landed directly beside a headline that had just called the repo polyglot.
22
+ Each line now names the stack it measured:
23
+
24
+ > C#/.NET projects: 1.
25
+ > C#/.NET project types: console.
26
+ > C#/.NET target frameworks: net6.0.
27
+
28
+ Naming the stack costs one word and makes each line true on **any** repo, so no
29
+ polyglot detection is needed to decide the wording — a pure .NET solution reads
30
+ *"C#/.NET projects: 1."* just as correctly. The label comes from the same
31
+ `_STACK_LABELS` table the headline uses, never a second literal.
32
+
33
+ Two user-facing Spanish strings in an otherwise English summary went with them:
34
+ *"Patrón detectado: …"* and *"Solución .NET detectada"* now read *"C#/.NET
35
+ solution pattern: …"* and *"C#/.NET solution detected."*
36
+
37
+ ### Corrected
38
+
39
+ - **The 2.5.7 entry overstated its own tests.** It read *"16 new tests; suite
40
+ 3467 passed"*. Both numbers were derived arithmetically from a
41
+ `--collect-only` total — which includes skips — instead of being read off a
42
+ pytest summary line. Measured: **14 new tests**, and the suite reports
43
+ `3462 passed, 5 skipped, 1 deselected`. The entry is fixed above. A changelog
44
+ that inflates its own evidence is the same defect class these releases are
45
+ about; the numbers here are quoted from the summary line, not computed.
46
+
47
+ 1 new test; suite `3463 passed, 5 skipped, 1 deselected` (the deselection is a
48
+ pre-existing `file_chunker` failure unrelated to this work — the real ofbiz file
49
+ shrank below the test's 7500-line assertion).
50
+
3
51
  ## [2.5.7] — 2026-07-17
4
52
 
5
53
  **A framework claim must be attested by its own runtime.** The `examples` repo
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 2.5.7
3
+ Version: 2.5.8
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 = "2.5.7"
7
+ version = "2.5.8"
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__ = "2.5.7"
7
+ __version__ = "2.5.8"
@@ -29,7 +29,7 @@ import subprocess
29
29
  from dataclasses import asdict, dataclass
30
30
  from datetime import datetime, timezone
31
31
  from pathlib import Path
32
- from typing import Optional
32
+ from typing import Any, Optional
33
33
 
34
34
  RIS_SCHEMA_VERSION: str = "1.0"
35
35
  _RIS_FILENAME: str = "ris.json.gz"
@@ -107,9 +107,46 @@ def save_ris(repo_root: Path, ris: RepositoryIntelligenceSnapshot) -> None:
107
107
  # Data extraction from L1 core_dict
108
108
  # ---------------------------------------------------------------------------
109
109
 
110
+ def _entrypoint_paths(raw: Any) -> list[str]:
111
+ """Normalize agent_view's `entry_points` to the file paths RIS promises.
112
+
113
+ `structural_map["entrypoints"]` is consumed as a list of path STRINGS (it is
114
+ sliced, and every reader guards with `isinstance(fp, str)`), but agent_view
115
+ emits that key in two different shapes under one schema_version:
116
+
117
+ {"bootstrap": [path, …], "security": […], "controllers": {counts}}
118
+ when a bootstrap/security entry point was detected (Spring, …)
119
+ [{"path": …, "kind": …}, …]
120
+ otherwise
121
+
122
+ Storing either verbatim broke BOTH readers: the dict raised `KeyError` on
123
+ `entrypoints[:10]` — swallowed by a bare `except Exception`, silently
124
+ disabling the RIS fast path on exactly the Java/Spring repos it exists for —
125
+ and the list of dicts recovered zero paths, because a dict is not a `str`.
126
+
127
+ The shape drift itself is a separate schema question; normalizing here keeps
128
+ RIS's own contract true whichever shape it is handed, including plain paths.
129
+ """
130
+ if isinstance(raw, dict):
131
+ # Only bootstrap/security carry paths; `controllers` is a count summary.
132
+ out: list[str] = []
133
+ for key in ("bootstrap", "security"):
134
+ out.extend(p for p in (raw.get(key) or []) if isinstance(p, str))
135
+ return out
136
+ if isinstance(raw, list):
137
+ out = []
138
+ for item in raw:
139
+ if isinstance(item, str):
140
+ out.append(item)
141
+ elif isinstance(item, dict) and isinstance(item.get("path"), str):
142
+ out.append(item["path"])
143
+ return out
144
+ return []
145
+
146
+
110
147
  def _extract_structural_map(agent_data: dict) -> dict:
111
148
  """Extract structural map from agent_view output."""
112
- entry_points = agent_data.get("entry_points", [])
149
+ entry_points = _entrypoint_paths(agent_data.get("entry_points", []))
113
150
 
114
151
  layers = []
115
152
  domains = []
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes