sourcecode 5.3.0__tar.gz → 5.4.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-5.3.0 → sourcecode-5.4.0}/CHANGELOG.md +150 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/PKG-INFO +3 -3
- {sourcecode-5.3.0 → sourcecode-5.4.0}/README.md +2 -2
- sourcecode-5.4.0/docs/CACHE.md +180 -0
- sourcecode-5.4.0/docs/COMMERCIAL-OFFER.md +115 -0
- sourcecode-5.4.0/docs/CUSTOMER-VALIDATION.md +202 -0
- sourcecode-5.4.0/docs/DEFECT-LEDGER.md +444 -0
- sourcecode-5.4.0/docs/DEMO-5MIN.md +134 -0
- sourcecode-5.4.0/docs/DEVELOPMENT-ROADMAP.md +2818 -0
- sourcecode-5.4.0/docs/EXECUTION-PLAN-12MO.md +173 -0
- sourcecode-5.4.0/docs/EXECUTIVE-ROADMAP.md +182 -0
- sourcecode-5.4.0/docs/MANUAL-USUARIO.md +1035 -0
- sourcecode-5.4.0/docs/MODERNIZATION.md +82 -0
- sourcecode-5.4.0/docs/PRODUCT_AUDIT.md +170 -0
- sourcecode-5.4.0/docs/PRODUCT_IDENTITY.md +106 -0
- sourcecode-5.4.0/docs/PRODUCT_TIERS.md +188 -0
- sourcecode-5.4.0/docs/RC1-CHECKLIST.md +62 -0
- sourcecode-5.4.0/docs/RELEASE-CHECKLIST.md +94 -0
- sourcecode-5.4.0/docs/USER_GUIDE.md +1511 -0
- sourcecode-5.4.0/docs/architecture/CATALOG-retrieval-intents.md +420 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-knowledge-provider-integration.md +134 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-p5.3b-statement-surface.md +505 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-p5.5-span-index.md +533 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-p6-semantic-impact-engine.md +95 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-p6-semantic-integration-engine.md +89 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-p7-semantic-services.md +177 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-robustness-security-inference.md +423 -0
- sourcecode-5.4.0/docs/architecture/DESIGN-semantic-retrieval.md +492 -0
- sourcecode-5.4.0/docs/architecture/EPV-p6-class-typeref.md +103 -0
- sourcecode-5.4.0/docs/architecture/REPORT-p6-flow-analyzer-comparison.md +201 -0
- sourcecode-5.4.0/docs/architecture/REPORT-p6-integration-detector-comparison.md +121 -0
- sourcecode-5.4.0/docs/architecture/REPORT-p8-flow-analyzer-migration.md +157 -0
- sourcecode-5.4.0/docs/architecture/REPORT-p9-integration-detector-migration.md +151 -0
- sourcecode-5.4.0/docs/architecture/adr/0001-semantic-ir.md +890 -0
- sourcecode-5.4.0/docs/architecture/adr/0002-source-evidence-boundary.md +256 -0
- sourcecode-5.4.0/docs/architecture/adr/0003-architectural-characterization.md +107 -0
- sourcecode-5.4.0/docs/architecture/adr/0004-semantic-retrieval.md +177 -0
- sourcecode-5.4.0/docs/architecture/adr/0005-evidence-reconciliation.md +418 -0
- sourcecode-5.4.0/docs/architecture/adr/0006-performance-harness.md +133 -0
- sourcecode-5.4.0/docs/architecture/adr/0007-composition-semantics.md +437 -0
- sourcecode-5.4.0/docs/architecture/adr/0008-answer-coherence.md +180 -0
- sourcecode-5.4.0/docs/architecture/consumer-disposition-inventory.md +137 -0
- sourcecode-5.4.0/docs/architecture/overview.md +49 -0
- sourcecode-5.4.0/docs/architecture/product-architecture-review.md +209 -0
- sourcecode-5.4.0/docs/architecture/product-strategy-layering.md +167 -0
- sourcecode-5.4.0/docs/architecture/semantic-ir-consumer-matrix.md +110 -0
- sourcecode-5.4.0/docs/architecture/semantic-ir-roadmap.md +299 -0
- sourcecode-5.4.0/docs/baseline-ci.yml +82 -0
- sourcecode-5.4.0/docs/commercial-pipeline-audit.md +142 -0
- sourcecode-5.4.0/docs/contracts-ci.yml +51 -0
- sourcecode-5.4.0/docs/contracts.md +313 -0
- sourcecode-5.4.0/docs/eval/2026-06-15-petclinic-rest-issue11-vets-pagination.md +47 -0
- sourcecode-5.4.0/docs/eval/2026-06-15-petclinic-rest-issue147-validation.md +93 -0
- sourcecode-5.4.0/docs/eval/2026-06-15-petclinic-rest-workflow.md +122 -0
- sourcecode-5.4.0/docs/eval/2026-06-15-phase18-openapi-surface.md +47 -0
- sourcecode-5.4.0/docs/eval/2026-06-15-phase20-validation-surface.md +48 -0
- sourcecode-5.4.0/docs/eval/2026-06-16-broadleaf-checkout-impact-fieldtest.md +106 -0
- sourcecode-5.4.0/docs/eval/2026-06-16-petclinic-rest-issue11-weakness2-closed.md +71 -0
- sourcecode-5.4.0/docs/eval/2026-06-16-spring-petclinic-issue2333-dead-vets.md +146 -0
- sourcecode-5.4.0/docs/licensing-schema.md +78 -0
- sourcecode-5.4.0/docs/migrate-check.md +363 -0
- sourcecode-5.4.0/docs/perf/README.md +63 -0
- sourcecode-5.4.0/docs/perf/REGRESSION-GATE.md +274 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/SUMMARY.md +68 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/alfresco__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/alfresco__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/broadleaf__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/broadleaf__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/eureka__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/eureka__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/jenkins__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/jenkins__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/jobrunr__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/jobrunr__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/keycloak__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/keycloak__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/neo4j__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/neo4j__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/ofbiz__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/ofbiz__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/openmrs__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/openmrs__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/petclinic__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.15/petclinic__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/SUMMARY.md +112 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/alfresco__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/alfresco__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/broadleaf__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/broadleaf__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/eureka__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/eureka__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/jenkins__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/jenkins__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/jobrunr__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/jobrunr__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/keycloak__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/keycloak__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/neo4j__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/neo4j__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/ofbiz__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/ofbiz__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/openmrs__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/openmrs__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/petclinic__ask__cold.json +52 -0
- sourcecode-5.4.0/docs/perf/baselines/2.5.16/petclinic__ask__warm.json +40 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/README.md +79 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/broadleaf__ask__warm.json +47 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/broadleaf__endpoints__warm.json +47 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/broadleaf__migrate-check__warm.json +47 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/broadleaf__posture__warm.json +47 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/broadleaf__spring-audit__warm.json +47 -0
- sourcecode-5.4.0/docs/perf/baselines/gate-latest/broadleaf__validation__warm.json +47 -0
- sourcecode-5.4.0/docs/perf/baselines/reference-best/README.md +34 -0
- sourcecode-5.4.0/docs/posture.md +446 -0
- sourcecode-5.4.0/docs/privacy.md +205 -0
- sourcecode-5.4.0/docs/pro-experience-audit.md +115 -0
- sourcecode-5.4.0/docs/schema.md +894 -0
- sourcecode-5.4.0/docs/spec/envelope-v1.md +84 -0
- sourcecode-5.4.0/docs/spring-audit-ci.yml +56 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/pyproject.toml +9 -2
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/audit_report.py +19 -2
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/baseline_autocapture.py +43 -17
- sourcecode-5.4.0/src/sourcecode/bundled_docs.py +64 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/cli.py +308 -88
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/client_calls.py +114 -13
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/consumer_join.py +71 -7
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/data_labels.py +31 -21
- sourcecode-5.4.0/src/sourcecode/declarations.py +179 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/release_info.py +15 -4
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/repository_ir.py +225 -63
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/ris.py +54 -8
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/runs.py +21 -2
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/security_config.py +58 -17
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/serializer.py +22 -1
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_impact.py +11 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/sql_taint.py +229 -23
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/summarizer.py +8 -2
- sourcecode-5.3.0/src/sourcecode/declarations.py +0 -81
- {sourcecode-5.3.0 → sourcecode-5.4.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/.github/workflows/perf-gate.yml +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/.gitignore +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/.ruff.toml +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/CLAUDE.md +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/CONTRIBUTING.md +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/LICENSE +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/SECURITY.md +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/raw +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/scripts/perf_gate.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/scripts/perf_harness.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/scripts/sync_gate_anchors.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/archetype.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/compare.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/container_wiring.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/data_exposure.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/degradation.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detach.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/envelope.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/environment_resolution.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/execution_plan.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/explain.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/gate_anchors.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/license.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/dependency_import.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/non_coverage.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/openrewrite_recipe.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/output_encoding.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/parallel.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/partial_contract.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/perf.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/phased_run.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/posture.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/provenance.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/readonly.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/remedies.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/risk.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/rule_catalog.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/rule_pass.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/sarif.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/security_chain.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/security_config_scan.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/servlet_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/source_text.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/text_input.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/timeline.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/waivers.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/functions/README.md +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-5.3.0 → sourcecode-5.4.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,156 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.4.0] — 2026-08-12
|
|
6
|
+
|
|
7
|
+
**Fourteen rows from one audit, and the worst defect this ledger has recorded.**
|
|
8
|
+
ASK 5.3.1 was audited in the field under a written non-persistence protocol —
|
|
9
|
+
113 instrumented invocations, 50 of 51 non-prohibited commands, zero crashes,
|
|
10
|
+
zero tracebacks, the repository byte-identical to its baseline at the end — and
|
|
11
|
+
16 of its claims were cross-verified line by line against source. Thirteen held.
|
|
12
|
+
Three did not, and one of those three is the headline of this release.
|
|
13
|
+
|
|
14
|
+
**54,7 % of a monolith's HTTP surface was published as unguarded while carrying
|
|
15
|
+
a live authorization annotation.** A handler whose `@RequestMapping` is declared
|
|
16
|
+
on an abstract superclass was indexed under the *declaring* member, and the gate
|
|
17
|
+
lives on the *override* — so 1 955 of 3 574 endpoints read `none_detected` with
|
|
18
|
+
the annotation right there in source. It propagated to eight commands, ran in
|
|
19
|
+
the unsafe direction, and it retires this project's own most-quoted figure: the
|
|
20
|
+
"2 635 endpoints with no security policy" this repository has cited since
|
|
21
|
+
evaluation #7 is really ≈659.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- **A handler keeps the gate it declares, not the one it inherits.** The
|
|
25
|
+
inheritance projection now names the member that *runs* (`effective_symbol`)
|
|
26
|
+
beside the one that declares the mapping, and every security lookup reads
|
|
27
|
+
both. The projection can only ever *add* a policy the override declares for
|
|
28
|
+
itself — the inherited verdict is never widened away. Second half, same root:
|
|
29
|
+
an inherited-mapping override was classified as a non-handler by the custom
|
|
30
|
+
gate predicate, putting the only members carrying the gate on the wrong side
|
|
31
|
+
of the specificity ratio and, on a repository where most controllers extend a
|
|
32
|
+
generic base, suppressing the gate outright.
|
|
33
|
+
- **A SQL statement's identity is its namespace, not its bare name.** `risk`
|
|
34
|
+
published as the repository's #1 critical row a `${}` that cannot be exploited,
|
|
35
|
+
joined to a call trace that does not exist: tainted calls were matched to
|
|
36
|
+
mapper statements by method name alone, so a controller calling its own
|
|
37
|
+
service's `actualizar` was reported as reaching a mapper statement `actualizar`
|
|
38
|
+
in an unrelated namespace. The correct key was already written in the code and
|
|
39
|
+
unused. A call is now a statement's only when its receiver resolves to that
|
|
40
|
+
mapper; an unresolvable receiver leaves the sink `undecidable`, never
|
|
41
|
+
`reaches`. And the interpolated expression is finally read: an OGNL ternary
|
|
42
|
+
over two string literals is a closed allowlist by construction — precisely the
|
|
43
|
+
mitigation SEC-008's own `fix_hint` recommends — and leaves the sink
|
|
44
|
+
population into a published `bounded_interpolations` list.
|
|
45
|
+
- **The security verdict is a fact about the tree, not about the shell.** Two
|
|
46
|
+
runs of `endpoints` over one unchanged tree returned two different censuses.
|
|
47
|
+
The programmatic-security fallback read a repository-relative path with no
|
|
48
|
+
root, resolving it against the process working directory: run from inside the
|
|
49
|
+
repository it read the file, run from anywhere else it cached a false. The
|
|
50
|
+
same scan could not tell code from prose — it matched `hasRole(` inside
|
|
51
|
+
`@PreAuthorize("hasRole('ADMIN')")`, a declarative gate on another method read
|
|
52
|
+
as runtime enforcement of this one. And a whole-file regex was preempting a
|
|
53
|
+
per-method gate on both surfaces.
|
|
54
|
+
- **One definition of the working set per document.** `git_context.uncommitted_files:
|
|
55
|
+
1` sat beside `_cache.has_uncommitted_changes: false` in one payload. One
|
|
56
|
+
predicate now answers both, and what it excludes is published
|
|
57
|
+
(`uncommitted_files_not_read`) rather than subtracted in silence.
|
|
58
|
+
- **A declaration that cannot be used says so.** A `sourcecode.config.json` with
|
|
59
|
+
an invented top-level key, a misspelt `dataLabels` and
|
|
60
|
+
`customSecurityAnnotations` as an array of strings ran completely clean —
|
|
61
|
+
`declaration.problems: []`, `declaration_problems: 0`, the two fields the
|
|
62
|
+
schema publishes for exactly this. `ask config` now distinguishes *not
|
|
63
|
+
declared* from *declared and unusable*, and prints the keys the file accepts
|
|
64
|
+
from the registry the loaders read.
|
|
65
|
+
- **`impact` no longer prints the inverse of its own field.** `risk_level: high`
|
|
66
|
+
above "Low-risk isolated change" is gone; `risk_score` stays `null` where none
|
|
67
|
+
could be measured, and the floor the level asserts travels under its own name
|
|
68
|
+
so the row can still be ordered.
|
|
69
|
+
- **A written tail is not a URL, and a comment is not a call.** A client call
|
|
70
|
+
whose head is an interpolation is no longer promoted to `broken_integration` —
|
|
71
|
+
the path matched against is the written tail and the head is unknown — and the
|
|
72
|
+
TypeScript extractor now blanks comments, so a commented-out documentation
|
|
73
|
+
placeholder is not admitted as a live call.
|
|
74
|
+
- **`generate-tests` binds its budget on the clock a user reads.** 56,45 s to
|
|
75
|
+
enforce a 30 000 ms limit and return nothing: the abandoned walk was joined at
|
|
76
|
+
interpreter shutdown. It runs on a daemon thread now, and the default budget
|
|
77
|
+
is derived from the scope instead of being a constant measured against a walk
|
|
78
|
+
that no longer exists.
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
- `--env-map`, `--code-notes`, `--dependencies` and `--architecture` say that
|
|
82
|
+
`--compact` and `--agent` already enable them, from one sentence in one place.
|
|
83
|
+
- `repo-ir --force` names both guards it bypasses, in both units.
|
|
84
|
+
- `--base-ref` also accepts `--since`; `verify --baseline` also accepts `-b`;
|
|
85
|
+
`baseline capture --dir` and `migrate-check --history-dir` accept each other's
|
|
86
|
+
spelling. Nothing is renamed. `--files` takes the same three shapes on every
|
|
87
|
+
command that has it, through one reader.
|
|
88
|
+
- `docs/USER_GUIDE.md` and `docs/DEFECT-LEDGER.md` ship in the wheel, and the
|
|
89
|
+
surfaces that name them resolve the pointer from what is actually packaged.
|
|
90
|
+
- `enrich` publishes the pipeline that feeds it (`trivy fs --format sarif` →
|
|
91
|
+
`ask enrich . --sarif`) in its own help and in the guide.
|
|
92
|
+
- `untested_sources` declares the population it counts over and is present
|
|
93
|
+
whenever the ranking ran.
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
- `tests/test_cli_grammar.py` — one concept, one spelling, derived from the CLI
|
|
97
|
+
registry, with every exception declared and reasoned.
|
|
98
|
+
- `tests/test_bundled_docs.py` — a document a surface names is a document this
|
|
99
|
+
build carries, asserted against the wheel manifest.
|
|
100
|
+
|
|
101
|
+
Suite: **8 240 passed, 14 skipped.**
|
|
102
|
+
|
|
103
|
+
## [5.3.1] — 2026-08-11
|
|
104
|
+
|
|
105
|
+
**Six fixes from one field battery.** 5.3.0 was run over the 14 repositories in
|
|
106
|
+
the field corpus — 22 commands each, plus the symbol-level commands and the
|
|
107
|
+
edge-input battery. No command crashed on its own account: every non-zero exit
|
|
108
|
+
was a well-formed input error. What the battery found instead is the class this
|
|
109
|
+
series keeps returning to — two surfaces answering one question with two
|
|
110
|
+
numbers, and a count published under the name of a population it does not count.
|
|
111
|
+
|
|
112
|
+
### Fixed
|
|
113
|
+
- **One admission authority for the route population.** `extract_java_endpoints`
|
|
114
|
+
filtered its Java files with `is_test_path` alone, while `find_java_files` —
|
|
115
|
+
which feeds the IR and therefore `spring-audit`, `impact`, `validation` and
|
|
116
|
+
`data-exposure` — also drops the `src/main` of a module that is itself test
|
|
117
|
+
infrastructure. Measured on jobrunr: `endpoints` published 3 annotation routes
|
|
118
|
+
from `quarkus-jobrunr-tests` that `spring-audit` could not see at all, 3
|
|
119
|
+
against `endpoints_analyzed: 0`, under the payload's own
|
|
120
|
+
`semantic_model_endpoints_note` declaring the two counts to be one figure. The
|
|
121
|
+
rule is now `repository_ir.is_test_source_file`, called by both builders
|
|
122
|
+
(jobrunr 14/3 → 12/0; every other repository in the corpus unchanged).
|
|
123
|
+
- **A call site is an HTTP call only where an HTTP client is.** The Java
|
|
124
|
+
consumer-join matcher admitted `<receiver>.put|patch|delete|exchange("…")` on
|
|
125
|
+
any receiver — HTTP verbs, and three of the most common method names in Java.
|
|
126
|
+
Measured on eureka joined against open-banking-gateway: all 20 rows of
|
|
127
|
+
`calls_unresolved` were `Map.put` literals in one file, and a
|
|
128
|
+
`map.put("/x", v)` would have been published as a consumer calling `/x` — the
|
|
129
|
+
direction the module declares decisive. A file must now import or declare an
|
|
130
|
+
HTTP client type before its call sites are read.
|
|
131
|
+
- **A snapshot that measured nothing reports unknown, not zero.**
|
|
132
|
+
`update_ris_api_surface` / `update_ris_spring_audit` write a stub snapshot so
|
|
133
|
+
their own section survives when no full one exists; `cold-start` read that stub
|
|
134
|
+
as a measurement. On alfresco-community-repo — 7 000+ Java files, 901
|
|
135
|
+
WebScripts — it answered `validation: {spring_detected: false,
|
|
136
|
+
controllers_found: 0, status: "valid"}` with every section empty. Now
|
|
137
|
+
`status: cold_start_incomplete`, `validation.status: empty_snapshot`, every
|
|
138
|
+
count `null`, with a statement naming what is unknown and how to build the
|
|
139
|
+
snapshot. A repository measured to have no Spring surface still reports its
|
|
140
|
+
zeroes — that is a fact.
|
|
141
|
+
- **The scale signal counts files, and says files.** The headline sentence of
|
|
142
|
+
every Java summary ended with "N Java classes" while counting `.java` paths.
|
|
143
|
+
BroadleafCommerce is 2 659 Java files and 3 032 declared types, so the label
|
|
144
|
+
contradicted `repo-ir.analysis_meta.classes` in the same run.
|
|
145
|
+
- **The human audit bundle prints counts, not Python objects.** The two
|
|
146
|
+
breakdown lines of the markdown report interpolated their dicts directly, so
|
|
147
|
+
the signed evidence bundle published `- Endpoint access: {'no_rule_matched':
|
|
148
|
+
676}` on keycloak, and a literal `None` for a section that was never measured.
|
|
149
|
+
- **Bookkeeping never takes down a finished analysis.** `RunRecord.write` had no
|
|
150
|
+
guard on its terminal write, so a run directory that disappeared during the
|
|
151
|
+
analysis — a concurrent `ask cache clear`, a tmp reaper, an evicted cache —
|
|
152
|
+
raised `FileNotFoundError` out of the analysis scope's exit. Observed on
|
|
153
|
+
`audit-report`, which died with a traceback having already composed the report.
|
|
154
|
+
|
|
5
155
|
## [5.3.0] — 2026-08-11
|
|
6
156
|
|
|
7
157
|
**The capability queue, built on the stable point.** 5.2.0 was the highest-scored
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.4.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`**
|
|
@@ -126,7 +126,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
126
126
|
# pip / pipx
|
|
127
127
|
pipx install sourcecode # or: pip install sourcecode
|
|
128
128
|
|
|
129
|
-
ask version # ask 5.
|
|
129
|
+
ask version # ask 5.4.0 — and, on a build that has aged,
|
|
130
130
|
# how many releases have probably shipped since
|
|
131
131
|
```
|
|
132
132
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Context · Impact · Migration · Architecture · Review — everything from one structural model.**
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|

|
|
9
9
|
|
|
10
10
|
> **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
|
|
@@ -88,7 +88,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
88
88
|
# pip / pipx
|
|
89
89
|
pipx install sourcecode # or: pip install sourcecode
|
|
90
90
|
|
|
91
|
-
ask version # ask 5.
|
|
91
|
+
ask version # ask 5.4.0 — and, on a build that has aged,
|
|
92
92
|
# how many releases have probably shipped since
|
|
93
93
|
```
|
|
94
94
|
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Cache model — what a warm gives you, and what invalidates it
|
|
2
|
+
|
|
3
|
+
Field evaluation #3 ran `ask cache warm` (103 s), watched `--compact` come back in 1 s, then
|
|
4
|
+
watched `--agent --full --env-map --depth 20` take 171 s **after that warm**, and most of
|
|
5
|
+
`prepare-context` behave as if no cache existed. Their verdict was not that the cache is slow:
|
|
6
|
+
|
|
7
|
+
> *"El warm no es un warm general — el modelo de invalidación no está documentado y no es
|
|
8
|
+
> predecible."*
|
|
9
|
+
|
|
10
|
+
Two costs, and the second is the one that hurt: nothing told them which of their commands a
|
|
11
|
+
warm would help. This page is the answer, and it is generated from the same table the CLI
|
|
12
|
+
prints — run `ask cache model` for it in the terminal, `ask cache model --json` in a script.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## One rule for invalidation
|
|
17
|
+
|
|
18
|
+
**Every layer keys on the exact tree state. Any change to the analysed files invalidates it —
|
|
19
|
+
committed or not, staged or not, tracked or not.** A clean tree keys on the commit, so a repeat
|
|
20
|
+
run with no edits hits. A tree without a git repository is signed by the size and mtime of its
|
|
21
|
+
files and follows the same rule.
|
|
22
|
+
|
|
23
|
+
That was not true before 3.2.2: the snapshot cache keyed on the committed HEAD, so an
|
|
24
|
+
uncommitted edit was served the pre-edit answer (defect C1-9 in the
|
|
25
|
+
[defect ledger](DEFECT-LEDGER.md)). If you are reading this because a stale answer surprised
|
|
26
|
+
you on an older version, that is the bug, and upgrading is the fix.
|
|
27
|
+
|
|
28
|
+
Two things invalidate everything, everywhere:
|
|
29
|
+
|
|
30
|
+
- **An analyzer change.** A content hash of the analyzer's own source is in every key, so a new
|
|
31
|
+
release never serves an answer computed by the old logic.
|
|
32
|
+
- **`ask cache clear`.** `--all` also drops the RIS.
|
|
33
|
+
|
|
34
|
+
`--no-cache` skips the cache for one run without writing over what is stored.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Where it lives
|
|
39
|
+
|
|
40
|
+
| Path | Holds |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `~/.sourcecode/cache/<repo-id>/` | snapshot cache (`core-*`, `view-*`), the RIS, `prepare-context` task answers |
|
|
43
|
+
| `~/.sourcecode/ctx-*.json.gz` | the shared Canonical IR |
|
|
44
|
+
| `~/.sourcecode/parse-cache-v1/` | the per-file parse cache |
|
|
45
|
+
|
|
46
|
+
`SOURCECODE_CACHE_DIR` and `SOURCECODE_CONTEXT_CACHE_DIR` move them. Nothing leaves the machine.
|
|
47
|
+
|
|
48
|
+
The cache is keyed to **the path you analysed**: `cache warm ./service-a` warms `service-a`, not
|
|
49
|
+
the enclosing monorepo, and `cache status` / `cache clear` resolve to that same scope.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## The model
|
|
54
|
+
|
|
55
|
+
<!-- BEGIN GENERATED: ask cache model --markdown -->
|
|
56
|
+
| Layer | What it stores | What invalidates it | `cache warm` |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| `snapshot` | the rendered answer of the root command (L1 core analysis + L2 view) | tree state · analyzer fingerprint · analysis flags (--env-map, --depth, --docs, --exclude, …) for the core; presentation flags (--compact, --agent, --full, --format, …) for the view | built for the compact view (`--agent` also builds the agent view) |
|
|
59
|
+
| `ris` | the Repository Intelligence Snapshot — structural index, endpoint index, summaries | tree state (the snapshot records the tree it describes) | rebuilt on every warm |
|
|
60
|
+
| `cir` | the shared Canonical IR — the Java parse every knowledge command reuses | tree state · analyzer fingerprint · schema version | built |
|
|
61
|
+
| `task` | one `prepare-context` task answer, per task and per option set | tree state · task · --symptom / --all / --include-config / --format | never — a warm does not run any task |
|
|
62
|
+
| `parse` | the symbol extraction of one file, keyed by its bytes | the file's own bytes and the extractor's source — content-addressed, so it is never stale and never needs invalidating. Bounded by `ASK_PARSE_CACHE_MAX_MB` (default 512 MB, least-recently-used, enforced on write) and reported in `cache status` (F-AR) | filled for every Java file the warm parses |
|
|
63
|
+
|
|
64
|
+
Measured on BroadleafCommerce (2 000+ Java files, dirty tree), warm machine, 3.2.2, each command in isolation.
|
|
65
|
+
|
|
66
|
+
Measured on release 3.2.2. Figures are that build's on that repository, not a prediction for yours; the nightly performance gate (`docs/perf/REGRESSION-GATE.md`) is what re-measures them.
|
|
67
|
+
|
|
68
|
+
The second anchor is the field one, and it carries its own build for the same reason (C3-97): field evaluation #26: spring-audit on 3 342 Java files took 31 s (Windows, pipx, mixed cache) against 8.8 s on the 2 000-file reference. Where a command was measured on an earlier release than the one you are running, `ask cache model` says so on that row rather than presenting the figure as this build's.
|
|
69
|
+
|
|
70
|
+
| Command | A warm gives it | Measured (nothing cached → after a warm) | Repeat run cached | Layers | Notes |
|
|
71
|
+
|---|---|---|---|---|---|
|
|
72
|
+
| `ask (root)` | the answer | --compact 13.3 s cold → 0.3 s warm (cold re-measured on 3.7.0: was 19.3 s, C3-6); --agent --full --env-map --depth 20 34.7 s → 33.9 s (no gain) | yes | `snapshot`, `ris`, `parse` | `--compact` is what a warm stores by default; `--agent` needs `cache warm --agent`. `--env-map`, `--depth N` and `--exclude` change the *analysis*, so they miss the warmed core and rescan — the 171 s the field measured after a 103 s warm on 4.10.4. Eval #23 timed the same invocation at 72,3 s from a purged cache, and then paid 71,7 s again for `--agent` on the state it had just analysed (C3-103). |
|
|
73
|
+
| `posture` | the shared work | 10.1 s → 1.6 s | no | `cir`, `parse` | Resolves the conditional bean graph on every run, over the shared CIR a warm builds — the parse it used to repeat for itself. `--diff` compares two profile sets over that one IR, so the second side costs the resolution only. |
|
|
74
|
+
| `risk` | the shared work | not measured on the battery yet — the composition is bounded by the `spring-audit` + `impact-chain` costs listed here, not by new analysis | no | `cir`, `parse` | Composes what the audit, impact-chain and the posture already answer, so it pays each of their costs once over the shared CIR a warm builds — one parse for the whole composition, and the reachability query is cached per symbol within the run. |
|
|
75
|
+
| `enrich` | the shared work | not measured on the battery yet — bounded by the `risk` composition, plus reading one JSON file | no | `cir`, `parse` | Runs the same composition as `risk` over the repository, then joins a SARIF log to it. Reading the log is negligible; everything a warm helps with is the repository side, so what it buys is what it buys `risk`. |
|
|
76
|
+
| `audit-report` | the shared work | not measured on the battery yet — bounded by `risk` + `posture`, or by `posture` when `--from-risk` is supplied | no | `cir`, `parse` | Packages `risk` and `posture` evidence. A warm helps the repository side; `--from-risk risk.json` skips risk recomputation entirely and only builds the posture/report projection. |
|
|
77
|
+
| `migrate-recipe` | the shared work | not measured on the battery yet — bounded by `migrate-check` on the same repository (openmrs-core ~2 s) | no | `parse` | Runs the same scan as `migrate-check` and projects its findings into an OpenRewrite recipe, so it buys exactly what a warm buys `migrate-check`: the parse, not the rule pass. |
|
|
78
|
+
| `data-exposure` | the shared work | not measured on the battery yet — one `impact-chain` traversal per declared seed type over a CIR the warm already paid for | no | `cir`, `parse` | Walks the same call reach as `impact-chain` once per declared type and reads the endpoint security surface, both over the shared CIR a warm builds. Cost scales with the number of declared types, not with the size of the label. |
|
|
79
|
+
| `endpoints` | the shared work | 3.3 s → 1.4 s (re-measured on 3.7.0; was 2.8 s → 2.9 s) | no | `ris`, `parse` | Recomputes the endpoint surface on every run, over a parse a warm has already paid for. Until 3.7.0 the extractor parsed every file itself instead of reading the shared parse cache, and a warm measurably bought it nothing (C3-6). |
|
|
80
|
+
| `spring-audit` | the shared work | 8.8 s → 3.7 s | no | `ris`, `parse` | Recomputes every run, but over a parse a warm has already paid for. |
|
|
81
|
+
| `migrate-check` | nothing | 4.8 s → 4.8 s | no | `cir` | Computes its own inventory and shares nothing a warm builds. Only `--blast-radius` reuses the shared CIR. |
|
|
82
|
+
| `impact-chain` | the shared work | 9.9 s → 1.7 s | no | `cir`, `parse` | The CIR is the expensive half — this is where a warm pays most. |
|
|
83
|
+
| `impact` | the shared work | 4.9 s → 2.8 s | no | `parse` | — |
|
|
84
|
+
| `pr-impact` | the shared work | not timed | no | `parse` | Diff-dependent: the answer itself is never stored. What it costs follows the diff, not the repository: 12,5 s on an ordinary one and 11,8 s on a diff of security configuration, measured at field scale. |
|
|
85
|
+
| `verify` | nothing | not timed | no | — | Runs the contracts against a fresh reading. |
|
|
86
|
+
| `verify-edit` | the shared work | 14.6 s → 9.6 s → 5.6 s on repeat | yes | `parse` | Built for the edit loop: the parse cache is what keeps an unchanged file out of the next run. Its own second run is faster again. At field size that loop is not short yet: eval #23 measured 76,6 s on a tree with no edits, because the HEAD side is still built in a throwaway worktree instead of reusing the shared CIR (C3-102). |
|
|
87
|
+
| `review-pr` | nothing | 1.1 s → 2.3 s (slower) | no | `cir` | Diff-dependent, and it reuses the CIR only if one exists. On a small diff, loading the warmed CIR costs more than the work it saves. |
|
|
88
|
+
| `plan` | the shared work | 9.3 s → 3.8 s | no | `parse` | — |
|
|
89
|
+
| `compare` | the shared work | not timed | no | `parse` | — |
|
|
90
|
+
| `delta` | nothing | not timed | no | — | Analyses two states — two checkouts, or two refs materialised into temporary trees; neither is the tree the cache describes. |
|
|
91
|
+
| `contract-diff` | nothing | not timed | no | — | Analyses two states (checkouts or refs); neither is the tree the cache describes. |
|
|
92
|
+
| `fix-bug` | nothing | not timed | yes | `task` | Shorthand for `prepare-context fix-bug`; caches its own answer, which a warm never runs. |
|
|
93
|
+
| `rename-class` | nothing | not timed | no | — | — |
|
|
94
|
+
| `prepare-context` | the answer | onboard 6.5 s → 0.3 s with a warm — but a second run with NO warm recomputes (10.2 s → 9.4 s at 5 486 files; C1-40) · refactor 7.7 s → 7.7 s (0.3 s on repeat) · generate-tests 12.4 s → 11.0 s (0.3 s on repeat) | yes | `task`, `ris`, `cir`, `parse` | Per task: `onboard` and `explain` are served from the RIS a warm rebuilds; `refactor`, `fix-bug` and `generate-tests` cache their own answer, but a warm does not run them, so their first call pays full price; `delta` and `review-pr` are diff-dependent and never cached. |
|
|
95
|
+
| `onboard` | the answer | with a warm: 6.5 s → 0.3 s (2 000 files) · 10.2 s → 0.7 s (5 486 files). WITHOUT a warm, a second identical run: 10.2 s → 9.4 s (5 486 files) — no answer hit | no | `task`, `ris` | Shorthand for `prepare-context onboard`. A warm stores its answer; the command does NOT store its own, so a second run without a warm pays full price. C1-40: the field read `repeat cached` here, ran it twice with no warm, and measured 56 s then 23,5 s — this row said it would be a hit. |
|
|
96
|
+
| `explain` | the shared work | 9.8 s → 1.6 s | no | `cir` | Serves from the shared CIR a warm builds. |
|
|
97
|
+
| `export` | the shared work | 8.8 s → 3.7 s | no | `parse` | — |
|
|
98
|
+
| `repo-ir` | the shared work | 5.1 s → 2.9 s | no | `parse` | Carried as *did not finish* from 4.10.4 until eval #23 ran it at field size in 9,8 s — a run that did not finish once is not a command that cannot finish (C3-100, and the same correction `modernize` needed). |
|
|
99
|
+
| `validation` | the shared work | 11.6 s → 6.4 s | no | `parse` | — |
|
|
100
|
+
| `modernize` | the shared work | 5.2 s → 3.0 s | no | `parse` | Blocked in the session that recorded C3-53 and measured since: a run that did not finish once is not a command that cannot finish. |
|
|
101
|
+
| `chunk-file` | nothing | not timed | no | — | Reads one file; nothing to cache. |
|
|
102
|
+
| `cold-start` | the answer | 0.2 s either way | yes | `ris` | Reads the RIS a warm rebuilds — that is all it does. Without one it answers `no_ris` instead of a snapshot. |
|
|
103
|
+
| `timeline` | nothing | not timed | no | — | Each sample is a fresh materialisation of a different commit, so nothing is shared between samples: two commits are two trees, and a cache keyed on a tree state can only ever serve one of them. The per-sample cost is measured and published in the payload. |
|
|
104
|
+
| `trend` | nothing | not timed | no | — | Reads stored baseline artifacts from disk; analyses no source, so no cache layer applies. Same command as `baseline trend`. |
|
|
105
|
+
| `baseline` | the shared work | capture 8.7 s → 3.6 s | no | `parse` | `capture`/`diff`/`trend` over architectural metrics. The field figure is `capture`, the subcommand that analyses; `trend` reads stored artifacts and has its own row. |
|
|
106
|
+
| `retrieve` | the shared work | not timed | no | `cir`, `parse` | Every query builds or reuses the shared CIR a warm builds. |
|
|
107
|
+
| `archetype` | the shared work | 9.3 s → 5.6 s | no | `parse` | — |
|
|
108
|
+
| `activate` | nothing | not timed | no | — | Not an analysis. |
|
|
109
|
+
| `auth` | nothing | not timed | no | — | Not an analysis. |
|
|
110
|
+
| `cache` | nothing | not timed | no | — | Operates on the caches themselves. |
|
|
111
|
+
| `config` | nothing | not timed | no | — | Not an analysis. |
|
|
112
|
+
| `mcp` | the shared work | not timed | yes | `snapshot`, `ris`, `cir`, `parse` | Serves the same commands over MCP, with the same layers. |
|
|
113
|
+
| `schema` | nothing | not timed | no | — | Prints registries; reads no repository. |
|
|
114
|
+
| `telemetry` | nothing | not timed | no | — | Not an analysis. |
|
|
115
|
+
| `version` | nothing | not timed | no | — | Not an analysis. |
|
|
116
|
+
<!-- END GENERATED -->
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## What this costs in CI
|
|
121
|
+
|
|
122
|
+
A pipeline with no persisted cache directory pays the cold price **every run** — the cache is on
|
|
123
|
+
disk, not in the repository, so a fresh container starts cold whatever you did yesterday.
|
|
124
|
+
Measured on BroadleafCommerce (2 000+ Java files, dirty tree, warm machine):
|
|
125
|
+
|
|
126
|
+
| Run | Nothing cached | After `cache warm` | Repeat |
|
|
127
|
+
|---|---|---|---|
|
|
128
|
+
| `ask --compact` | 17.7 s | **0.3 s** | 0.3 s |
|
|
129
|
+
| `ask --agent --full --env-map --depth 20` | 34.7 s | 33.9 s | 0.3 s |
|
|
130
|
+
| `endpoints` | 2.8 s | 2.9 s | 2.8 s |
|
|
131
|
+
| `spring-audit` | 8.8 s | 3.7 s | 3.6 s |
|
|
132
|
+
| `posture` | 10.1 s | **1.6 s** | 1.6 s |
|
|
133
|
+
| `migrate-check` | 4.8 s | 4.8 s | 4.8 s |
|
|
134
|
+
| `impact-chain` | 9.9 s | **1.7 s** | 1.7 s |
|
|
135
|
+
| `explain` | 9.8 s | **1.6 s** | 1.6 s |
|
|
136
|
+
| `prepare-context onboard` | 6.5 s | **0.3 s** | 0.3 s |
|
|
137
|
+
| `prepare-context refactor` | 7.7 s | 7.7 s | **0.3 s** |
|
|
138
|
+
| `prepare-context generate-tests` | 12.4 s | 11.0 s | **0.3 s** |
|
|
139
|
+
|
|
140
|
+
`cache warm` itself took **18 s** on that repository, and it reports its own elapsed time when it
|
|
141
|
+
finishes, precisely so the figure is in front of whoever writes the pipeline. On the 3 342-file
|
|
142
|
+
monolith of field evaluation #3 the same warm took 103 s and a cold `--agent --full --env-map
|
|
143
|
+
--depth 20` took 171 s.
|
|
144
|
+
|
|
145
|
+
Read the table twice. A warm is worth most to `--compact`, `impact-chain`, `explain`, `posture`
|
|
146
|
+
and `prepare-context onboard`; it is worth **nothing** to `endpoints` and `migrate-check`, and the
|
|
147
|
+
`prepare-context` tasks that are not `onboard`/`explain` only get fast on their *own* second run,
|
|
148
|
+
which a warm cannot trigger for them. If your pipeline runs `endpoints` and `migrate-check`, a
|
|
149
|
+
warm is 18 s you will not get back.
|
|
150
|
+
|
|
151
|
+
Three ways to spend less:
|
|
152
|
+
|
|
153
|
+
1. **Persist `~/.sourcecode` between jobs** (cache the directory in your CI). Then only the files
|
|
154
|
+
that changed are re-derived.
|
|
155
|
+
2. **Warm the view your pipeline consumes**, not the default one — `cache warm --agent` if the
|
|
156
|
+
pipeline reads `--agent`.
|
|
157
|
+
3. **Ask for the command you need**, not for `--full`. `--full` and a raised `--depth` change the
|
|
158
|
+
analysis, so they are a different, colder question than `--compact`.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Reading the freshness of an answer
|
|
163
|
+
|
|
164
|
+
Every root-command payload carries `_cache`:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
"_cache": {
|
|
168
|
+
"cache_source": "L2_view",
|
|
169
|
+
"git_head_at_generation": "45649e0",
|
|
170
|
+
"current_git_head": "45649e0",
|
|
171
|
+
"is_stale": false,
|
|
172
|
+
"has_uncommitted_changes": true,
|
|
173
|
+
"generated_at": "2026-07-29T04:57:39Z",
|
|
174
|
+
"data_scope": "COMPACT"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`cache_source` is `fresh` when the run computed the answer, and `L1_core` / `L2_view` when it was
|
|
179
|
+
served. `ask cache status` reports what is stored for a repository, and `ask cache freshness`
|
|
180
|
+
reports how far the RIS is from the current HEAD.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# ASK Engine — Commercial Offer
|
|
2
|
+
|
|
3
|
+
The single, coherent Free/Pro offer, defined by **customer value** (not technical
|
|
4
|
+
difficulty). Companion to [`PRODUCT_TIERS.md`](PRODUCT_TIERS.md) (the mechanical split)
|
|
5
|
+
and [`MODERNIZATION.md`](MODERNIZATION.md) (the flagship product narrative). CLI command:
|
|
6
|
+
`sourcecode`.
|
|
7
|
+
|
|
8
|
+
## The one-sentence offer
|
|
9
|
+
|
|
10
|
+
> **ASK Engine answers the expensive questions about a large Java codebase —
|
|
11
|
+
> deterministically, with the source to prove it. Free on normal repos; Pro when the
|
|
12
|
+
> work gets enterprise-scale or automated.**
|
|
13
|
+
|
|
14
|
+
The gating axis is **size + automation**, never capability. Nothing is crippled on Free;
|
|
15
|
+
you pay exactly when the tool is replacing the most engineering time — a monolith above
|
|
16
|
+
**500 Java source files**, or CI/CD automation. **€19/mo · €190/yr, per developer.**
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## The offer by capability
|
|
21
|
+
|
|
22
|
+
Each capability framed as a customer job. "Free part / Pro part" is the same size axis:
|
|
23
|
+
full on repos ≤ 500 Java files; Pro on enterprise-scale monoliths (and CI automation).
|
|
24
|
+
|
|
25
|
+
### 1. Impact — "what breaks if I change this?"
|
|
26
|
+
*Commands: `impact`, `impact-chain`, `review-pr`, `pr-impact`, `fix-bug`.*
|
|
27
|
+
- **Problem:** before touching a monolith, know the blast radius — callers, endpoints,
|
|
28
|
+
transactional and security surface — without guessing.
|
|
29
|
+
- **Buyer:** enterprise developer, tech lead.
|
|
30
|
+
- **Why pay:** on a codebase too large to hold in your head (or an LLM's context), a
|
|
31
|
+
precise, source-backed change-risk answer prevents expensive mistakes. This is the moat
|
|
32
|
+
— determinism where LLMs hallucinate and grep can't follow the logic.
|
|
33
|
+
- **Free:** full power on repos ≤ 500 Java files.
|
|
34
|
+
- **Pro:** enterprise-scale monoliths + CI automation (`review-pr --format github-comment`).
|
|
35
|
+
|
|
36
|
+
### 2. System Map — "what is this system, and what does it talk to?"
|
|
37
|
+
*Commands: `onboard`, `export` (`--c4`/`--module-graph`/`--integrations`), `endpoints`, `spring-audit`, `explain`.*
|
|
38
|
+
- **Problem:** understand an unfamiliar monolith — module structure, endpoints, external
|
|
39
|
+
integrations — fast.
|
|
40
|
+
- **Buyer:** architect, newly-onboarded engineer.
|
|
41
|
+
- **Why pay:** an accurate, current map of a system nobody fully understands; onboarding
|
|
42
|
+
in days, not months.
|
|
43
|
+
- **Free:** full on ≤ 500 Java files.
|
|
44
|
+
- **Pro:** enterprise-scale + rich/CI-consumable exports.
|
|
45
|
+
|
|
46
|
+
### 3. Modernization — "are we ready to upgrade, and what blocks us?" ← flagship
|
|
47
|
+
*Commands: `migrate-check` (readiness), `validation`; see [`MODERNIZATION.md`](MODERNIZATION.md).*
|
|
48
|
+
- **Problem:** Boot 2→3, javax→jakarta, Hibernate 5→6, JDK and dependency readiness — a
|
|
49
|
+
budgeted, deadline-driven project full of unknowns.
|
|
50
|
+
- **Buyer:** platform/architecture lead with an allocated upgrade budget.
|
|
51
|
+
- **Why pay:** turn a months-long unknown into a measured plan; this is the capability
|
|
52
|
+
tied most directly to a funded project — the clearest willingness-to-pay.
|
|
53
|
+
- **Free:** the **readiness assessment** at any size (see freemium decision below).
|
|
54
|
+
- **Pro:** the **full remediation detail + effort plan** on enterprise-scale monoliths.
|
|
55
|
+
|
|
56
|
+
### 4. Agent Platform — "give my AI agents ground truth."
|
|
57
|
+
*Commands: `mcp`, `repo-ir`, `cold-start`, `prepare-context`.*
|
|
58
|
+
- **Problem:** AI coding agents re-parse the repo every session and hallucinate structure.
|
|
59
|
+
- **Buyer:** teams using AI coding agents (Claude Code, Cursor, Copilot).
|
|
60
|
+
- **Why pay:** deterministic, cached, source-backed context — and CI automation on every PR.
|
|
61
|
+
- **Free:** local `mcp serve`, `cold-start`, and 30 `prepare-context delta` runs/repo.
|
|
62
|
+
- **Pro:** delta automation beyond the free quota (the CI/CD axis) + `generate-tests` at scale.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Decision: `migrate-check` is FREEMIUM
|
|
67
|
+
|
|
68
|
+
**Question:** should `migrate-check` be fully Free, fully Pro, or freemium?
|
|
69
|
+
|
|
70
|
+
**Decision: FREEMIUM** — the assessment is Free at any size; the full at-scale detail is Pro.
|
|
71
|
+
|
|
72
|
+
**Justification (customer value, not technique):**
|
|
73
|
+
- `migrate-check` is the **buy-trigger**: it maps to a budgeted upgrade project. The
|
|
74
|
+
*assessment* (a readiness score, the dimension breakdown, the headline blocker) is what
|
|
75
|
+
creates the *"we have a problem, let's fund this"* moment. **Gating the assessment fully
|
|
76
|
+
to Pro hides the hook and kills conversion** — the buyer never discovers the value on
|
|
77
|
+
their real monolith.
|
|
78
|
+
- Fully Free, however, gives away the high-value deliverable — a complete, actionable
|
|
79
|
+
remediation plan on a 5,000-file monolith — for nothing.
|
|
80
|
+
- **Freemium resolves both:** the diagnosis is free everywhere (maximizes discovery); the
|
|
81
|
+
detailed, at-scale, actionable plan is the paid deliverable. This mirrors the existing
|
|
82
|
+
capped-preview model (`fix-bug` top-5, `modernize` structural-only on large repos), so it
|
|
83
|
+
introduces **no new gating axis** — just the same size axis applied to `migrate-check`.
|
|
84
|
+
|
|
85
|
+
**The exact split:**
|
|
86
|
+
|
|
87
|
+
| Signal | Free (any size) | Pro (repos > 500 Java files) |
|
|
88
|
+
|--------|-----------------|------------------------------|
|
|
89
|
+
| `readiness_score` + per-dimension scores (jakarta/boot3/jdk/hibernate) | ✅ | ✅ |
|
|
90
|
+
| `headline_blocker`, `blocking_count`, `applicable_dimensions` | ✅ | ✅ |
|
|
91
|
+
| summary counts (`total_findings`, `by_severity`) | ✅ | ✅ |
|
|
92
|
+
| **full `findings` detail** (per-file, per-rule, code context) | preview (top-N) on large repos | ✅ full |
|
|
93
|
+
| **`effort_breakdown` / estimated effort plan** | — on large repos | ✅ |
|
|
94
|
+
| `hygiene_findings`, `non_blocking` detail | — on large repos | ✅ |
|
|
95
|
+
|
|
96
|
+
On repos ≤ 500 Java files everything stays free (the model's promise). On enterprise
|
|
97
|
+
monoliths, a Free user gets the **score + a top-N findings preview + an upgrade prompt** —
|
|
98
|
+
enough to see the value and justify the budget.
|
|
99
|
+
|
|
100
|
+
**Implementation note.** The paywall is currently OFF (`_PRO_UNLOCK_ALL`), so this gate is
|
|
101
|
+
dormant. The capping is specified as a concrete step in
|
|
102
|
+
[`RC1-CHECKLIST.md`](RC1-CHECKLIST.md) / [`RELEASE-CHECKLIST.md`](RELEASE-CHECKLIST.md), to
|
|
103
|
+
land **together with paywall reactivation** (where it is exercised and tested end-to-end).
|
|
104
|
+
It is byte-neutral under the current unlock: with everyone floored to Pro, `migrate-check`
|
|
105
|
+
output is unchanged, so the reference-repo oracles do not move.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Pricing
|
|
110
|
+
|
|
111
|
+
**€19/mo · €190/yr, per developer.** Self-serve, no metering, no sales motion. Sits at the
|
|
112
|
+
floor of the closest comparable (CodeScene $20–30/dev/mo) and matches dev-tool norms
|
|
113
|
+
(Cursor/Copilot $10–20/mo). ASK Engine is a focused CLI, so pricing at — not above — the
|
|
114
|
+
comp floor maximizes adoption. Enterprise (multi-repo, SSO, dashboards) is a future,
|
|
115
|
+
separately-sold SKU — not advertised until it exists.
|