sourcecode 2.3.0__tar.gz → 2.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sourcecode-2.3.0 → sourcecode-2.5.0}/CHANGELOG.md +106 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/PKG-INFO +4 -4
- {sourcecode-2.3.0 → sourcecode-2.5.0}/README.md +3 -3
- {sourcecode-2.3.0 → sourcecode-2.5.0}/pyproject.toml +1 -1
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/archetype.py +46 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/cli.py +491 -4
- sourcecode-2.5.0/src/sourcecode/context_cache.py +637 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/context_graph.py +32 -24
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/explain.py +24 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/repository_ir.py +1 -1
- sourcecode-2.5.0/src/sourcecode/retrieval/__init__.py +192 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/context.py +241 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/errors.py +41 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/executor.py +51 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/planner.py +297 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/query.py +484 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/request.py +94 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/resolution.py +135 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/result.py +144 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/retriever.py +62 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/runtime.py +259 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps.py +242 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps_endpoint.py +311 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps_graph.py +248 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps_impact.py +293 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps_intf.py +247 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps_struct.py +338 -0
- sourcecode-2.5.0/src/sourcecode/retrieval/steps_txsec.py +351 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/security_config.py +4 -4
- {sourcecode-2.3.0 → sourcecode-2.5.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/.gitignore +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/.ruff.toml +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/CONTRIBUTING.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/LICENSE +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/SECURITY.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/raw +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/license.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/functions/README.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-2.3.0 → sourcecode-2.5.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -1,5 +1,111 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.5.0] — 2026-07-13
|
|
4
|
+
|
|
5
|
+
**Semantic Retrieval Engine v1 — a declarative, agent-ready query layer over ASK's
|
|
6
|
+
already-built knowledge.** Retrieval turns *"ask a typed question of the repository"*
|
|
7
|
+
into a first-class, reusable operation (Layer 3.5, above the Knowledge Layer, below any
|
|
8
|
+
presentation). It **queries** existing structured knowledge — it never extracts, parses,
|
|
9
|
+
or computes new evidence: every answer is a composition of existing engines acquired
|
|
10
|
+
through one shared, cached `KnowledgeContext`. Frozen as v1 in ADR-0004.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Semantic Retrieval Engine** (`src/sourcecode/retrieval/`): a typed `RetrievalRequest`
|
|
15
|
+
→ `IntentResolver` → `QueryPlanner` → declarative `KnowledgeQuery` (a closed, serializable
|
|
16
|
+
Step algebra) → generic `QueryPlanRuntime` → structured `KnowledgeResult` (entities,
|
|
17
|
+
evidence, observations, confidence, structured explanation, provenance, executed plan).
|
|
18
|
+
Adding an intent is enum + plan + registered steps — the generic Runtime is unchanged;
|
|
19
|
+
this held across 11 phases and **29 intents / 9 domains**.
|
|
20
|
+
- **29 experimental `ask retrieve …` intents** across Architecture, Impact, Transactions,
|
|
21
|
+
Security, Interfaces/Validation, Integrations, Subsystems, Dependencies, and Graph — each
|
|
22
|
+
a pure composition of an existing engine (ArchetypeClassifier, `compute_blast_radius`,
|
|
23
|
+
`SpringSemanticModel`, `run_tx_audit`, `run_security_audit`, `build_validation_surface`,
|
|
24
|
+
`SemanticIntegrationEngine`, `run_impact_chain`, the module graph). Cross-pack step reuse
|
|
25
|
+
(`ResolveTarget`, `ResolveEndpointRef`, `ResolveScope`, generic `BuildResult`).
|
|
26
|
+
- **Consolidation (B1–B4):** lazy SourceMap acquisition; per-acquisition timing surfaced in
|
|
27
|
+
the runtime report; impact-pack evidence parity; the `limit` option activated (default
|
|
28
|
+
unbounded). `ADR-0004` + `DESIGN-knowledge-provider-integration.md` document the frozen
|
|
29
|
+
contract and the pattern for adding future knowledge providers.
|
|
30
|
+
- **User guide — architecture chapters (EN + ES):** *How ASK works*, *The semantic engine*,
|
|
31
|
+
*Architectural intelligence*, *AI workflows* — the Semantic IR / Context Graph / Knowledge
|
|
32
|
+
Layer / evidence model that the guides previously did not cover.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **Cold-path performance / apparent hang:** `ContextGraph.relations()`/`symbols()` were
|
|
37
|
+
re-converting every edge and re-sorting every node on each call, and per-file consumers
|
|
38
|
+
call them once per file — an O(files × edges) blow-up that made cold `ask --agent` take
|
|
39
|
+
minutes on large repositories. Memoizing the projections cut jobrunr cold ~21 s → ~4 s and
|
|
40
|
+
BroadleafCommerce cold `--agent` from a multi-minute hang to ~54 s. Benefits every command
|
|
41
|
+
that reads the graph.
|
|
42
|
+
- **`archetype` library de-bias (P0):** consumable libraries were confidently labeled
|
|
43
|
+
`engine` (their internals are engine-like). Non-runnable artifacts (no app/server/servlet
|
|
44
|
+
entry) are now correctly distinguished from runnable engines — jobrunr `engine(high)` →
|
|
45
|
+
`library(low)`; real engines (Neo4j) unchanged. Implemented as transparent, auditable
|
|
46
|
+
evidence.
|
|
47
|
+
- **`fix-bug` argument consistency (P0):** now accepts the sibling-consistent
|
|
48
|
+
`fix-bug <symptom> <path>` form (mirroring `impact <target> <path>`) instead of failing
|
|
49
|
+
with a raw usage error; `--symptom` and path-only forms remain unchanged.
|
|
50
|
+
|
|
51
|
+
### Removed
|
|
52
|
+
|
|
53
|
+
- All references to a proprietary third-party security annotation were scrubbed from code,
|
|
54
|
+
tests, and docs (ASK references nothing vendor-proprietary).
|
|
55
|
+
|
|
56
|
+
## [2.4.0] — 2026-07-12
|
|
57
|
+
|
|
58
|
+
**AI Context Cache — a provider-agnostic cache for ASK's reusable Knowledge
|
|
59
|
+
Context.** This is *not* a prompt cache: it never stores prompts, generated text,
|
|
60
|
+
or LLM responses. It caches the structured knowledge ASK derives from source —
|
|
61
|
+
so expensive commands stop re-parsing the same repository on every run. The cache
|
|
62
|
+
belongs entirely to ASK and is consumed identically by any AI provider (GPT,
|
|
63
|
+
Claude, Gemini, local models) or none at all; the LLM never participates in
|
|
64
|
+
producing or reading it.
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- **`context_cache.py` — the AI Context Cache component.** Operates at the
|
|
69
|
+
*knowledge* level: it caches the reusable Canonical IR (the expensive Java
|
|
70
|
+
parse) keyed **only by knowledge state**, never by command or prompt. The key
|
|
71
|
+
is `worktree_signature + KL_SCHEMA_VERSION + PRODUCER_VERSION + scope`, where
|
|
72
|
+
`worktree_signature` is the committed HEAD folded with a hash of the working-tree
|
|
73
|
+
diff when dirty — so a new commit *or* an uncommitted edit deterministically
|
|
74
|
+
invalidates the entry rather than serving stale context. Invalidation is
|
|
75
|
+
state-based, never TTL-based for correctness (TTL and a max-entry cap exist only
|
|
76
|
+
as cleanup). Entries are gzip'd, inspectable envelopes (no opaque blobs);
|
|
77
|
+
persistence survives across executions under `~/.sourcecode/context-cache/`.
|
|
78
|
+
- **`get_or_build_cir()` — the reusable-knowledge entry point.** Builds the
|
|
79
|
+
Canonical IR once and, on a hit, rebuilds the full CIR cheaply from the cached
|
|
80
|
+
raw IR via `ir_dict_to_canonical` — skipping the parse entirely, with the
|
|
81
|
+
`cir_hash` verified equal so the rebuilt CIR is provably faithful. Because the
|
|
82
|
+
key is command-agnostic, every command that needs a CIR shares one entry: once
|
|
83
|
+
wired, `impact` / `review-pr` / `modernize` reuse it for free.
|
|
84
|
+
- **`CachedContext`** — an inspectable structured record (`metadata`, `entities`,
|
|
85
|
+
`evidence`, `observations`, `summaries`, `graph_metrics`, `payload`,
|
|
86
|
+
`timestamps`, `producer_version`). Advisory metrics are tracked from day one:
|
|
87
|
+
hits, misses, invalidations, stores, hit ratio, average lookup/build time, bytes
|
|
88
|
+
stored, contexts reused.
|
|
89
|
+
- **`ask cache context-stats` / `ask cache context-clear`** — observability and
|
|
90
|
+
management for the context cache, kept distinct from the existing snapshot-cache
|
|
91
|
+
`cache status` / `cache clear` so neither clobbers the other.
|
|
92
|
+
- **`ask explain` is the first consumer.** It fetches its CIR through
|
|
93
|
+
`get_or_build_cir` and derives the class explanation cheaply from the shared
|
|
94
|
+
knowledge; each run reports `Context cache: HIT/MISS` with timing. Output is
|
|
95
|
+
byte-identical whether served from cache or a fresh build.
|
|
96
|
+
|
|
97
|
+
### Notes
|
|
98
|
+
|
|
99
|
+
- **Only `explain` is wired** — a deliberate reference integration to validate the
|
|
100
|
+
design before connecting `impact` / `onboard` / `prepare-context` / `archetype` /
|
|
101
|
+
`review-pr` / `modernize`. The SourceMap-based commands (`onboard`,
|
|
102
|
+
`prepare-context`, `archetype`) will use a separate cache scope.
|
|
103
|
+
- No AI-provider-specific logic, no embeddings, no RAG, no prompt/response caching.
|
|
104
|
+
- Env vars: `SOURCECODE_CONTEXT_CACHE_{DIR,DISABLE,TTL_DAYS,MAX_ENTRIES}`.
|
|
105
|
+
- Tests: `tests/test_context_cache.py` adds 23 tests (hit/miss, commit/dirty/version
|
|
106
|
+
invalidation, persistence, corruption recovery, concurrency, TTL GC, CIR
|
|
107
|
+
round-trip fidelity, cross-command reuse). No report or behaviour cutover.
|
|
108
|
+
|
|
3
109
|
## [2.3.0] — 2026-07-12
|
|
4
110
|
|
|
5
111
|
**Module graph promoted to a first-class Evidence Provider for architectural
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Keywords: agents,ai,codebase,context,developer-tools,llm
|
|
@@ -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
|
-

|
|
46
46
|

|
|
47
47
|
|
|
48
48
|
> **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
|
|
@@ -84,7 +84,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
84
84
|
# pip / pipx
|
|
85
85
|
pipx install sourcecode # or: pip install sourcecode
|
|
86
86
|
|
|
87
|
-
ask version # ask 2.
|
|
87
|
+
ask version # ask 2.5.0
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
> **Package vs. command.** The install package is named `sourcecode` this release
|
|
@@ -218,7 +218,7 @@ repo root (otherwise they report `policy: "none_detected"`):
|
|
|
218
218
|
```json
|
|
219
219
|
{
|
|
220
220
|
"customSecurityAnnotations": [
|
|
221
|
-
{ "fullyQualifiedName": "com.example.security.
|
|
221
|
+
{ "fullyQualifiedName": "com.example.security.CustomSecurityAnnotation", "shortName": "CustomSecurityAnnotation" }
|
|
222
222
|
]
|
|
223
223
|
}
|
|
224
224
|
```
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Context · Impact · Migration · Architecture · Review — everything from one structural model.**
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|

|
|
9
9
|
|
|
10
10
|
> **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
|
|
@@ -46,7 +46,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
46
46
|
# pip / pipx
|
|
47
47
|
pipx install sourcecode # or: pip install sourcecode
|
|
48
48
|
|
|
49
|
-
ask version # ask 2.
|
|
49
|
+
ask version # ask 2.5.0
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
> **Package vs. command.** The install package is named `sourcecode` this release
|
|
@@ -180,7 +180,7 @@ repo root (otherwise they report `policy: "none_detected"`):
|
|
|
180
180
|
```json
|
|
181
181
|
{
|
|
182
182
|
"customSecurityAnnotations": [
|
|
183
|
-
{ "fullyQualifiedName": "com.example.security.
|
|
183
|
+
{ "fullyQualifiedName": "com.example.security.CustomSecurityAnnotation", "shortName": "CustomSecurityAnnotation" }
|
|
184
184
|
]
|
|
185
185
|
}
|
|
186
186
|
```
|
|
@@ -80,6 +80,17 @@ _MIN_PRIMARY_SCORE = 0.05
|
|
|
80
80
|
# A winner must clear this absolute score (not just the top-2 margin) to earn
|
|
81
81
|
# medium/high confidence — a near-floor lone candidate stays "low".
|
|
82
82
|
_MIN_CONFIDENT_SCORE = 0.5
|
|
83
|
+
# Fraction of engine's positive contribution discounted for a non-runnable artifact
|
|
84
|
+
# (P0 library de-bias): an engine-like internal core is expected of a library, so it is not
|
|
85
|
+
# discriminating. Tuned so a clear library (no app/server/servlet entry) is not confidently
|
|
86
|
+
# labeled an engine, while runnable systems (which never trigger the gate) are untouched.
|
|
87
|
+
_LIBRARY_ENGINE_DISCOUNT = 0.55
|
|
88
|
+
# Entry kinds that make a repo a runnable system (an app/server/servlet/daemon) rather
|
|
89
|
+
# than a consumable library. Used to gate the library de-bias (P0).
|
|
90
|
+
_RUNNABLE_ENTRY_KINDS = frozenset({
|
|
91
|
+
"application", "bootstrap", "main", "server", "daemon", "worker",
|
|
92
|
+
"mvc_controller", "jax_rs_controller", "servlet", "security_filter", "filter",
|
|
93
|
+
})
|
|
83
94
|
|
|
84
95
|
|
|
85
96
|
@dataclass
|
|
@@ -389,6 +400,41 @@ class ArchetypeClassifier:
|
|
|
389
400
|
f"{f.module_count} modules; distributed mass ≈ {cm['distributed']:.0%}",
|
|
390
401
|
1.5, multi, max(cm["distributed"], 0.1))
|
|
391
402
|
self._apply_graph_evidence("software_archetype", cands, f)
|
|
403
|
+
# ── Library de-bias (P0) ────────────────────────────────────────────────
|
|
404
|
+
# A consumable JVM artifact — `jar` packaging with no server/bootstrap/application
|
|
405
|
+
# entry — is a library, not a runnable system. But a library naturally exhibits
|
|
406
|
+
# engine-like topology: a few core API types with high fan-in, tightly-coupled
|
|
407
|
+
# internals (SCCs), hub concentration. Those graph metrics (`graph_*`) otherwise
|
|
408
|
+
# label every library an "engine" (observed: jobrunr → engine(high), library 0.3).
|
|
409
|
+
# Correct it transparently: (1) add a packaging-grounded library signal that does
|
|
410
|
+
# not depend on an `api/` package existing; (2) append a NAMED negative evidence row
|
|
411
|
+
# that discounts most of engine's graph-derived score, since topological hubness in
|
|
412
|
+
# a library is expected and therefore not discriminating for "engine".
|
|
413
|
+
# A runnable/web entry of ANY kind (an app bootstrap, an HTTP controller, a
|
|
414
|
+
# servlet, a daemon) means the repo is a system you run, not a library you depend
|
|
415
|
+
# on. Packaging is unreliable here (gradle libs report no packaging; maven
|
|
416
|
+
# aggregators report `pom`), so the entry-kind surface is the robust signal.
|
|
417
|
+
is_runnable = any(k in f.entry_kinds for k in _RUNNABLE_ENTRY_KINDS)
|
|
418
|
+
is_library_shaped = not is_runnable
|
|
419
|
+
if is_library_shaped:
|
|
420
|
+
add("library", "no_runnable_entry",
|
|
421
|
+
f"entry kinds {sorted(f.entry_kinds) or 'none'} — no app/server/servlet "
|
|
422
|
+
"bootstrap; a consumable artifact, not a runnable system",
|
|
423
|
+
3.0, 1.0, 0.7)
|
|
424
|
+
# A library legitimately owns an engine-like core (storage/kernel mass, hub
|
|
425
|
+
# topology, SCCs) — that is what a library *is*. Discount most of engine's
|
|
426
|
+
# positive evidence for a non-runnable artifact so its internal machinery does
|
|
427
|
+
# not, alone, promote it to "engine". Transparent: a named negative row.
|
|
428
|
+
engine_positive = sum(max(0.0, e.contribution) for e in cands["engine"])
|
|
429
|
+
if engine_positive > 0:
|
|
430
|
+
discount = engine_positive * _LIBRARY_ENGINE_DISCOUNT
|
|
431
|
+
cands["engine"].append(Evidence(
|
|
432
|
+
"library_core_discount",
|
|
433
|
+
"non-runnable artifact: an engine-like internal core (storage/kernel "
|
|
434
|
+
"mass, hubs, SCCs) is expected of a library and is not, alone, evidence "
|
|
435
|
+
"of an engine product",
|
|
436
|
+
1.0, 1.0, 1.0, -discount,
|
|
437
|
+
))
|
|
392
438
|
return self._resolve("software_archetype", cands, f)
|
|
393
439
|
|
|
394
440
|
def _architectural_style(self, f: _Features) -> DimensionResult:
|