sourcecode 5.3.1__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.1 → sourcecode-5.4.0}/CHANGELOG.md +98 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/PKG-INFO +3 -3
- {sourcecode-5.3.1 → 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.1 → sourcecode-5.4.0}/pyproject.toml +9 -2
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-5.3.1 → 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.1 → sourcecode-5.4.0}/src/sourcecode/cli.py +304 -87
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/client_calls.py +114 -13
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/consumer_join.py +35 -6
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/data_labels.py +31 -21
- sourcecode-5.4.0/src/sourcecode/declarations.py +179 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/release_info.py +15 -4
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/repository_ir.py +159 -24
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/security_config.py +58 -17
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/serializer.py +22 -1
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_impact.py +11 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/sql_taint.py +229 -23
- sourcecode-5.3.1/src/sourcecode/declarations.py +0 -81
- {sourcecode-5.3.1 → sourcecode-5.4.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/.github/workflows/perf-gate.yml +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/.gitignore +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/.ruff.toml +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/CLAUDE.md +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/CONTRIBUTING.md +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/LICENSE +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/SECURITY.md +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/raw +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/scripts/perf_gate.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/scripts/perf_harness.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/scripts/sync_gate_anchors.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/archetype.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/audit_report.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/compare.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/container_wiring.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/data_exposure.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/degradation.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detach.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/envelope.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/environment_resolution.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/execution_plan.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/explain.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/gate_anchors.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/license.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/dependency_import.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/non_coverage.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/openrewrite_recipe.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/output_encoding.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/parallel.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/partial_contract.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/perf.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/phased_run.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/posture.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/provenance.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/readonly.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/remedies.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/risk.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/rule_catalog.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/rule_pass.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/runs.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/sarif.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/security_chain.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/security_config_scan.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/servlet_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/source_text.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/text_input.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/timeline.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/waivers.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/functions/README.md +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-5.3.1 → sourcecode-5.4.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,104 @@
|
|
|
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
|
+
|
|
5
103
|
## [5.3.1] — 2026-08-11
|
|
6
104
|
|
|
7
105
|
**Six fixes from one field battery.** 5.3.0 was run over the 14 repositories in
|
|
@@ -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.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# First Customer Validation (Increment #3.1)
|
|
2
|
+
|
|
3
|
+
Prepares ASK Engine to be **shown to real users for the first time** — developers,
|
|
4
|
+
architects, CTOs — and to run **validation interviews**. This is about the *communication*
|
|
5
|
+
of the product, not the engine. Nothing here changes analysis behavior.
|
|
6
|
+
|
|
7
|
+
Contents:
|
|
8
|
+
1. First-two-minutes audit (what a new user actually understands)
|
|
9
|
+
2. README-as-landing-page review + high-impact / low-cost copy proposals (ready to paste)
|
|
10
|
+
3. End-to-end journey (README → install → first command → first value → Pro) with frictions
|
|
11
|
+
4. The 5-minute demo → [`DEMO-5MIN.md`](DEMO-5MIN.md)
|
|
12
|
+
5. User-interview question bank (validate, don't sell)
|
|
13
|
+
|
|
14
|
+
The offer being validated: [`COMMERCIAL-OFFER.md`](COMMERCIAL-OFFER.md) ·
|
|
15
|
+
[`MODERNIZATION.md`](MODERNIZATION.md) · [`PRODUCT_TIERS.md`](PRODUCT_TIERS.md).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. First-two-minutes audit
|
|
20
|
+
|
|
21
|
+
Assumes a developer who has never seen ASK Engine and reads only the current repository
|
|
22
|
+
(README first). Observations only — objective, no fixes applied here.
|
|
23
|
+
|
|
24
|
+
### What they understand in the first 30 seconds
|
|
25
|
+
Reading the title + tagline + first paragraph (`README.md:1–20`):
|
|
26
|
+
- It is a tool called **ASK Engine**; the CLI is `sourcecode`.
|
|
27
|
+
- It gives **AI coding agents** persistent structural context and a fast repeated-analysis
|
|
28
|
+
cache; the headline benefit framed is **speed** (re-parse avoidance, ~17x on Keycloak).
|
|
29
|
+
- It targets **large Java or TypeScript monoliths**.
|
|
30
|
+
|
|
31
|
+
### What they understand in the first 2 minutes
|
|
32
|
+
Scrolling to the cache table, token table, install, and Quickstart (`README.md:24–131`):
|
|
33
|
+
- There is a **persistent content-hash cache** with measured speedups and bounded token output.
|
|
34
|
+
- The CLI does much more than caching: `impact`, `migrate-check`, `spring-audit`,
|
|
35
|
+
`impact-chain`, `endpoints`, `validation`, `onboard`, `review-pr`, `fix-bug` all appear in
|
|
36
|
+
the Quickstart.
|
|
37
|
+
- It runs **locally / offline** (stated later, `README.md:283`).
|
|
38
|
+
|
|
39
|
+
### What they do NOT understand
|
|
40
|
+
- **What the flagship is.** Modernization (`migrate-check`) is item #5 in the Quickstart —
|
|
41
|
+
no emphasis — yet it is the buy-trigger in the offer. The reader can't tell the headline
|
|
42
|
+
job from the long-tail command list.
|
|
43
|
+
- **That Impact is the differentiator.** "What breaks if I change this?" — the moat vs
|
|
44
|
+
grep/LLMs — is one line among a dozen commands, not positioned as the reason to care.
|
|
45
|
+
- **Who it's for.** The tagline says "Java **or TypeScript** monolith", but the product
|
|
46
|
+
monetizes **Java/Spring** and several capabilities are Java/Spring-only. A TypeScript dev
|
|
47
|
+
is invited in, then hits Java-only walls.
|
|
48
|
+
- **Free vs Pro at a glance.** The split lives at `README.md:264` (Pricing) — below a very
|
|
49
|
+
long command reference. A buyer scanning "what do I get, why would I pay" must scroll past
|
|
50
|
+
everything first. (Prior audit gap **D3 / F3**.)
|
|
51
|
+
- **Differentiation.** Nowhere near the top does the README say *why this beats grep, an
|
|
52
|
+
LLM, or SonarQube/OpenRewrite* — the three things a buyer will compare it to.
|
|
53
|
+
|
|
54
|
+
### Doubts they still have before installing
|
|
55
|
+
- **Does my code leave the machine?** (Answer — no egress, offline — is true and good, but
|
|
56
|
+
appears late; a security-conscious buyer wants it up top.)
|
|
57
|
+
- **Do I need an account / license / key to try it?** (Answer — no, fully local, Pro
|
|
58
|
+
currently unlocked — not stated upfront.)
|
|
59
|
+
- **Will it work on *my* repo?** Non-Spring Java? Non-Java? (Honest limitations exist but are
|
|
60
|
+
at the very bottom, `README.md:238–261`.)
|
|
61
|
+
|
|
62
|
+
### What would stop them trying it
|
|
63
|
+
- **No Java repo handy** — nothing to point it at. (Mitigation: the demo names two public
|
|
64
|
+
repos; the README's first value example should too.)
|
|
65
|
+
- **No single "try it in 30 seconds" line at the very top** — the first runnable command is
|
|
66
|
+
after the install section.
|
|
67
|
+
- Low friction otherwise: `pip install sourcecode` / `brew install`, then `ask .`.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 2. README as a landing page
|
|
72
|
+
|
|
73
|
+
Evaluated as the page that has to sell in one scroll.
|
|
74
|
+
|
|
75
|
+
| Landing criterion | Current state | Verdict |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| Problem is clear in 1 screen | Problem stated is *agent re-parse latency* only | ⚠ narrow — the expensive-questions problem (impact / modernization) is missing up top |
|
|
78
|
+
| Differentiation vs grep / LLM / static analysis | Not stated near the top | ✗ absent early |
|
|
79
|
+
| Real examples | Strong — measured cache tables, real repos (Keycloak, Broadleaf) | ✓ |
|
|
80
|
+
| Call to action | Install + Quickstart present | ✓ but value CTA ("check your upgrade readiness free") missing |
|
|
81
|
+
| Time-to-first-value | `ask .` is fast; but first *impressive* command isn't foregrounded | ⚠ |
|
|
82
|
+
| Free vs Pro visible without scrolling | No — at `:264` | ✗ (D3/F3) |
|
|
83
|
+
|
|
84
|
+
### High-impact / low-cost proposals (copy ready to paste — NOT applied this increment)
|
|
85
|
+
|
|
86
|
+
Each is pure copy near the top; no engine or gating change. Ordered by impact.
|
|
87
|
+
|
|
88
|
+
**P-1 — Reframe the tagline + one-line problem (highest impact).** Replace the
|
|
89
|
+
agent-only framing (`README.md:3`) with the expensive-questions framing that names the two
|
|
90
|
+
buy-jobs, keeping the agent story as one of them:
|
|
91
|
+
|
|
92
|
+
> **Deterministic answers to the expensive questions about a large Java codebase —
|
|
93
|
+
> _what breaks if I change this_ and _are we ready to upgrade_ — with the source to prove
|
|
94
|
+
> every answer.**
|
|
95
|
+
> Built for enterprise Java/Spring monoliths. Runs locally, offline, no account. Also
|
|
96
|
+
> serves fast, cached ground-truth to AI coding agents.
|
|
97
|
+
|
|
98
|
+
**P-2 — Add a "What you get (Free vs Pro)" box right after the tagline** (fixes D3/F3).
|
|
99
|
+
Four rows — Impact, System Map, Modernization, Agent context — each with the one-line job
|
|
100
|
+
and "Free on normal repos · Pro at enterprise scale". Lifts the offer above the fold; links
|
|
101
|
+
to `COMMERCIAL-OFFER.md`.
|
|
102
|
+
|
|
103
|
+
**P-3 — Add a top "Try it in 30 seconds" block** naming a public repo so a reader with no
|
|
104
|
+
Java repo handy can still see value:
|
|
105
|
+
> ```bash
|
|
106
|
+
> pip install sourcecode
|
|
107
|
+
> git clone https://github.com/spring-projects/spring-petclinic && cd spring-petclinic
|
|
108
|
+
> ask migrate-check . # upgrade readiness, free, source-backed
|
|
109
|
+
> ask impact OwnerController . # what breaks if I change this?
|
|
110
|
+
> ```
|
|
111
|
+
|
|
112
|
+
**P-4 — One "vs grep / LLM / static analysis" line** near the top: *"grep finds text, an
|
|
113
|
+
LLM guesses, ASK Engine proves — every finding carries the source line, and the blast-radius
|
|
114
|
+
graph follows Spring DI that grep and LLMs miss."*
|
|
115
|
+
|
|
116
|
+
**P-5 — Fix the audience contradiction:** the tagline should say **Java/Spring**; move the
|
|
117
|
+
"other languages get repo-shape only" nuance into the capabilities section so a TypeScript
|
|
118
|
+
reader isn't over-promised.
|
|
119
|
+
|
|
120
|
+
These are proposals for the next copy pass. Applying them is a one-file, reversible edit.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 3. End-to-end journey & frictions
|
|
125
|
+
|
|
126
|
+
The path a first user walks, with the friction at each hop.
|
|
127
|
+
|
|
128
|
+
| Hop | Reference | Friction |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| **README top** | `README.md:1–20` | Value prop = agent cache only; buy-jobs (impact, modernization) not foregrounded (**F1/F3/D3**). |
|
|
131
|
+
| **Install** | `README.md:62–84` | Clean — `pip install sourcecode` / `brew`. `ask version` confirms. Low friction. |
|
|
132
|
+
| **First command** | `README.md:88–131` | Quickstart is a 12-command wall; no "start here" ordering. A new user doesn't know which command to run first. |
|
|
133
|
+
| **First useful result** | live | `ask .` / `--compact` returns in ~0.3s warm. Good. But the *impressive* first result (blast radius, readiness score) isn't the one signposted first. |
|
|
134
|
+
| **Discover Free vs Pro** | `README.md:264` | Only reachable after the full command reference. Buyer scanning for "why pay" scrolls a long way (**D3**). |
|
|
135
|
+
| **Pro invite / activation** | `license.py`, `PRODUCT_TIERS.md` | Pro currently unlocked for everyone (early-adoption banner honest). When gated, prompt now shows Get-a-license + activate (G1 resolved). No `SOURCECODE_PURCHASE_URL` set yet (points to docs). **F2** — no in-tool pointer to pricing from `--help`/welcome. |
|
|
136
|
+
|
|
137
|
+
**Net:** install and time-to-first-result are strong; the weakness is entirely
|
|
138
|
+
**positioning / ordering of the value story**, not the tool. All frictions are copy-level
|
|
139
|
+
(F1/F2/F3/D3), already tracked in `RC1-CHECKLIST.md` §4 and `pro-experience-audit.md`.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 4. The 5-minute demo
|
|
144
|
+
|
|
145
|
+
See [`DEMO-5MIN.md`](DEMO-5MIN.md) — a reproducible script over two public repos
|
|
146
|
+
(BroadleafCommerce, OpenMRS) showing only what impresses a buyer: precise blast radius,
|
|
147
|
+
modernization readiness with real blockers, and the cache speed story. No internal
|
|
148
|
+
architecture shown. All numbers in that script were captured from a real run on 2026-07-05.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 5. User-interview question bank
|
|
153
|
+
|
|
154
|
+
For validation interviews. **Goal: validate hypotheses, not sell.** Open questions, let the
|
|
155
|
+
user talk, don't lead. Group by whichever hat the interviewee wears.
|
|
156
|
+
|
|
157
|
+
### Warm-up (any interviewee)
|
|
158
|
+
- Walk me through the last time you had to make a change in a large, unfamiliar codebase.
|
|
159
|
+
What did you do first?
|
|
160
|
+
- When you join a new service/monolith, how long until you trust yourself to change it?
|
|
161
|
+
|
|
162
|
+
### Core hypothesis probes (the four questions, asked without naming the product)
|
|
163
|
+
- **What problem were you trying to solve?** — last time you needed to know the blast radius
|
|
164
|
+
of a change, or plan a framework upgrade. What triggered it?
|
|
165
|
+
- **What did you expect to find / what did you reach for?** — grep, IDE call hierarchy, an
|
|
166
|
+
LLM, a static-analysis tool, asking a senior? What did that get you, and where did it fall
|
|
167
|
+
short?
|
|
168
|
+
- **What result would surprise you?** — if a tool told you "changing this class touches 54
|
|
169
|
+
endpoints across 2 modules" in ten seconds, would you believe it? What would make you
|
|
170
|
+
trust it?
|
|
171
|
+
- **What would you pay to avoid?** — describe a change or upgrade that went wrong (missed
|
|
172
|
+
caller, a `@Transactional` bypass, a botched Boot/Jakarta migration). What did it cost —
|
|
173
|
+
hours, an incident, a delayed release?
|
|
174
|
+
|
|
175
|
+
### Modernization segment (platform / architecture lead)
|
|
176
|
+
- How do you *currently* estimate a Boot 2→3 / Jakarta / JDK / Hibernate upgrade? How
|
|
177
|
+
confident is that estimate?
|
|
178
|
+
- What blocks you from starting — unknown scope, unknown effort, fear of what breaks?
|
|
179
|
+
- If you had a per-dimension readiness score with the source line behind every blocker,
|
|
180
|
+
what would you do with it? Who signs off on the budget?
|
|
181
|
+
|
|
182
|
+
### Impact segment (developer / tech lead)
|
|
183
|
+
- Before a risky change, how do you find everything it affects today? How often does
|
|
184
|
+
something get missed?
|
|
185
|
+
- How much do you trust an LLM's answer to "what calls this?" on your monolith? Have you
|
|
186
|
+
been burned?
|
|
187
|
+
- Spring DI: does your tooling follow interface→impl injection, or do you check by hand?
|
|
188
|
+
|
|
189
|
+
### AI-agent segment (teams using Claude Code / Cursor / Copilot)
|
|
190
|
+
- How do your agents get repo context today? How often do they hallucinate structure?
|
|
191
|
+
- Would deterministic, cached, source-backed context change how you run agents in CI?
|
|
192
|
+
|
|
193
|
+
### Pricing / packaging reactions (last, low-pressure)
|
|
194
|
+
- €19/dev/mo, free below 500 Java files and unlimited on normal repos — does that framing
|
|
195
|
+
make sense? Where would you expect to hit the paywall?
|
|
196
|
+
- Would you rather pay per developer, per repo, or per organization? Why?
|
|
197
|
+
- What single capability, if it worked perfectly, would justify the subscription on its own?
|
|
198
|
+
|
|
199
|
+
### Anti-goals (do not do in interviews)
|
|
200
|
+
- Don't demo before asking what they do today — you'll bias the answers.
|
|
201
|
+
- Don't defend the tool when they describe a gap — write the gap down.
|
|
202
|
+
- Don't ask "would you buy this?" — ask what they've *already paid for or lost*.
|