sourcecode 5.5.4__tar.gz → 5.5.5__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.5.4 → sourcecode-5.5.5}/CHANGELOG.md +25 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/PKG-INFO +3 -3
- {sourcecode-5.5.4 → sourcecode-5.5.5}/README.md +2 -2
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/DEFECT-LEDGER.md +5 -1
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/USER_GUIDE.md +1 -1
- {sourcecode-5.5.4 → sourcecode-5.5.5}/pyproject.toml +1 -1
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/__init__.py +1 -1
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/cli.py +26 -12
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/repository_ir.py +48 -15
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/security_config_scan.py +7 -1
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/servlet_surface.py +32 -8
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/validation_surface.py +9 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/.github/workflows/perf-gate.yml +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/.gitignore +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/.ruff.toml +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/CLAUDE.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/CONTRIBUTING.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/LICENSE +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/SECURITY.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/CACHE.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/COMMERCIAL-OFFER.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/CUSTOMER-VALIDATION.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/DEMO-5MIN.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/DEVELOPMENT-ROADMAP.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/EXECUTION-PLAN-12MO.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/EXECUTIVE-ROADMAP.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/MANUAL-USUARIO.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/MODERNIZATION.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/PRODUCT_AUDIT.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/PRODUCT_IDENTITY.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/PRODUCT_TIERS.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/RC1-CHECKLIST.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/RELEASE-CHECKLIST.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/CATALOG-retrieval-intents.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-knowledge-provider-integration.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-p5.3b-statement-surface.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-p5.5-span-index.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-p6-semantic-impact-engine.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-p6-semantic-integration-engine.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-p7-semantic-services.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-robustness-security-inference.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-semantic-retrieval.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/EPV-p6-class-typeref.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p6-flow-analyzer-comparison.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p6-integration-detector-comparison.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p8-flow-analyzer-migration.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p9-integration-detector-migration.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0001-semantic-ir.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0002-source-evidence-boundary.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0003-architectural-characterization.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0004-semantic-retrieval.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0005-evidence-reconciliation.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0006-performance-harness.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0007-composition-semantics.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0008-answer-coherence.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/consumer-disposition-inventory.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/overview.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/product-architecture-review.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/product-strategy-layering.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/semantic-ir-consumer-matrix.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/semantic-ir-roadmap.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/baseline-ci.yml +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/commercial-pipeline-audit.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/contracts-ci.yml +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/contracts.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-15-petclinic-rest-issue11-vets-pagination.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-15-petclinic-rest-issue147-validation.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-15-petclinic-rest-workflow.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-15-phase18-openapi-surface.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-15-phase20-validation-surface.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-16-broadleaf-checkout-impact-fieldtest.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-16-petclinic-rest-issue11-weakness2-closed.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/eval/2026-06-16-spring-petclinic-issue2333-dead-vets.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/licensing-schema.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/migrate-check.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/README.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/REGRESSION-GATE.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/SUMMARY.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/alfresco__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/alfresco__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/broadleaf__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/broadleaf__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/eureka__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/eureka__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/jenkins__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/jenkins__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/jobrunr__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/jobrunr__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/keycloak__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/keycloak__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/neo4j__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/neo4j__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/ofbiz__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/ofbiz__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/openmrs__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/openmrs__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/petclinic__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.15/petclinic__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/SUMMARY.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/alfresco__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/alfresco__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/broadleaf__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/broadleaf__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/eureka__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/eureka__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/jenkins__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/jenkins__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/jobrunr__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/jobrunr__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/keycloak__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/keycloak__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/neo4j__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/neo4j__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/ofbiz__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/ofbiz__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/openmrs__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/openmrs__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/petclinic__ask__cold.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/2.5.16/petclinic__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/README.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/broadleaf__ask__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/broadleaf__endpoints__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/broadleaf__migrate-check__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/broadleaf__posture__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/broadleaf__spring-audit__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/gate-latest/broadleaf__validation__warm.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/perf/baselines/reference-best/README.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/posture.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/privacy.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/pro-experience-audit.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/schema.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/spec/envelope-v1.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/docs/spring-audit-ci.yml +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/raw +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/scripts/perf_gate.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/scripts/perf_harness.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/scripts/sync_gate_anchors.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/archetype.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/audit_report.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/baseline_autocapture.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/bundled_docs.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/cache.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/classifier.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/client_calls.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/compare.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/consumer_join.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/container_wiring.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/data_exposure.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/data_labels.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/declarations.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/degradation.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detach.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/envelope.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/environment_resolution.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/execution_plan.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/explain.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/gate_anchors.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/license.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/manifest_cache.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/dependency_import.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/non_coverage.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/openrewrite_recipe.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/output_encoding.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/parallel.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/partial_contract.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/perf.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/phased_run.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/posture.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/progress.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/provenance.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/readonly.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/redactor.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/release_info.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/remedies.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/ris.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/risk.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/rule_catalog.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/rule_pass.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/runs.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/sarif.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/scanner.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/schema.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/security_chain.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/security_config.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/serializer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/source_text.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/sql_taint.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/text_input.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/timeline.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/version_check.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/waivers.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/src/sourcecode/workspace.py +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/functions/README.md +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-5.5.4 → sourcecode-5.5.5}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.5.5] — 2026-08-13
|
|
6
|
+
|
|
7
|
+
**MSAS performance-audit corrections and read-only hygiene verification.**
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- `spring-audit` now preserves full default JSON when it fits the stdout
|
|
11
|
+
budget; only oversized answers are bounded, and the notice points to
|
|
12
|
+
`--output` for the complete report.
|
|
13
|
+
- SEC-004 ignores import-only deprecated encoders and reports concrete
|
|
14
|
+
construction or factory evidence instead.
|
|
15
|
+
- `pr-impact --files -` fails immediately on a terminal stdin with a pipe
|
|
16
|
+
instruction instead of waiting indefinitely.
|
|
17
|
+
- `ask config` now distinguishes declared custom security annotations from
|
|
18
|
+
mechanisms inferred with Likely confidence.
|
|
19
|
+
|
|
20
|
+
### Verification
|
|
21
|
+
- Re-ran read-only hygiene over the `spaghetti-api` and `eureka` fixtures.
|
|
22
|
+
The commands leave their checkouts untouched; `cold-start` reports `no_ris`
|
|
23
|
+
explicitly where no semantic model is available.
|
|
24
|
+
|
|
25
|
+
### Documentation
|
|
26
|
+
- Recorded the MSAS findings, their reproductions, the resolved commits, and
|
|
27
|
+
the remaining bounded-output, schema, timeline, benchmark, and Git-basis
|
|
28
|
+
work in the roadmap.
|
|
29
|
+
|
|
5
30
|
## [5.5.4] — 2026-08-13
|
|
6
31
|
|
|
7
32
|
**Re-audit performance and HTTP contract corrections.**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 5.5.
|
|
3
|
+
Version: 5.5.5
|
|
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.5.
|
|
129
|
+
ask version # ask 5.5.5 — 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.5.
|
|
91
|
+
ask version # ask 5.5.5 — and, on a build that has aged,
|
|
92
92
|
# how many releases have probably shipped since
|
|
93
93
|
```
|
|
94
94
|
|
|
@@ -24,6 +24,10 @@ The facts these rows are keyed to are published: `ask schema facts-v1` prints th
|
|
|
24
24
|
| AS-02 | Route projection emitted declarations from abstract Spring controllers, creating phantom routes and inflating the unprotected census. | 5.4.2 re-audit | Low | **closed 5.4.2** — abstract declarers are excluded while concrete subtype projection remains admitted; the route-surface regression covers both sides. |
|
|
25
25
|
| AS-03 | The distributed ledger could leave `C3-123` open after the 5.4.1 build already excluded static assets. | 5.4.2 re-audit | Informational | **closed 5.4.2** — the stale state was synchronized to the wheel it documents. |
|
|
26
26
|
| AS-04 | An unconstrained `@RequestMapping` was described by consumers as GET although Spring admits every verb. | 5.5.1 audit | Medium | **closed 5.5.1** — primary `method` is `ANY`; 5.5.4 adds the concrete `methods` list so consumers do not need to infer its expansion. |
|
|
27
|
+
| AS-05 | Test-source endpoint exclusion was neither visible nor reversible for modules whose test code lives below `src/main`. | 5.5.1 audit | High | **closed 5.5.3** — `--include-tests` changes admission and the production answer counts exclusions; 5.5.4 recovery adds the matched path basis. |
|
|
28
|
+
| AS-06 | `@InitBinder` alone was treated as evidence of programmatic validation, contaminating gaps and confidence. | 5.5.1 audit | High | **closed 5.5.1** — only a Spring `Validator` implementation or `setValidator` wiring declares the limit; 5.5.4 recovery publishes that population separately from annotation validators. |
|
|
29
|
+
| AS-07 | Nested types used as field types were reported statically unreferenced by modernization. | 5.5.1 audit | Medium | **closed 5.5.1** — field-type references contribute an incoming static edge. |
|
|
30
|
+
| AS-08 | `spring-audit` severity census could sum to zero beside nonzero findings. | 5.5.4 re-audit | High | **closed 5.5.4** — severity partitions reconcile to `total_findings`; this is asserted in the audit battery. |
|
|
27
31
|
|
|
28
32
|
---
|
|
29
33
|
|
|
@@ -46,7 +50,7 @@ The facts these rows are keyed to are published: `ask schema facts-v1` prints th
|
|
|
46
50
|
| C1-13 | **Hub-guard publishes `endpoints_total: 0` instead of `unknown`.** A service with 780 callers is capped at `depth=1` for cost — defensible — but reports 0 endpoints reached, contradicting the epistemic standard the tool imposes on itself everywhere else. Hubs are precisely where blast radius is asked for | 3.2.1 (eval #4) | Medium | **closed 3.6.0** — no battery repository crosses the guard (openmrs-core's largest hub, `Context`, has 215 caller classes against a threshold of 500), so it was reproduced on a generated fixture: `bfs_truncated: true`, `depth_reached: 1`, `endpoints_affected_count: 0` beside four more zeros nothing looked for. A reach-derived count of 0 under the cap is now `null`, named in `stats.unknown_under_cap`. The distinction is the point and is asserted both ways: a **non-zero** count under the cap stays a number (it is a floor the effect block already describes), and an **uncapped** run keeps its measured zero, because converting that would be the mirror-image defect. The hub threshold moved to module level so the fixture crosses the real guard instead of a copy of its value |
|
|
47
51
|
| C1-14 | **File-count drift across commands**: 3 334 / 3 337 / 3 342 / 3 374 files for one repository in one session. No command is wrong in isolation; together they cost the one thing a deterministic tool cannot lose — that its numbers agree with themselves | 3.2.1 (eval #4) | Medium | **within-document half closed 3.6.0 · cross-command half does not reproduce.** Of six commands measured on openmrs-core (`--compact`, `endpoints`, `spring-audit`, `migrate-check`, `modernize`, `validation`) only `migrate-check` publishes a scanned-file count at all, so there are no two figures left to disagree. What does reproduce is the same defect *inside one document*: `affected_files` named two populations — 265 under `summary` (every finding, any scope) against 264 under `effort_breakdown` (blocking findings only). Both correct; the shared name was the contradiction. Same remedy as C1-5: the narrower becomes `blocking_affected_files`, both carry a `_basis`, the old key stays an alias, and the battery asserts the two diverge exactly when a finding is non-blocking |
|
|
48
52
|
| C1-15 | **Analysis assumes a single destination.** Asked about a JDK move, `migrate-check` answers `headline_blocker: boot3_migration` and emits fix hints that send a developer to migrate namespaces they never planned to touch (481 `javax.persistence` under MIG-001). There is no way to say "JDK 11, keep Boot 2.7" | 3.2.1 (eval #4) | **High (product)** | **closed 3.6.0** — `--target-jdk N` and `--keep-boot` say which migration is being planned, filtered over the `migration_target` vocabulary every rule already carried rather than a parallel one. Measured on openmrs-core with `--target-jdk 11 --keep-boot`, the row's own acceptance: **MIG-001 85 → 0**, blocking 114 → 0, `headline_blocker` `hibernate_rewrite` → `none_applicable`, and the Hibernate 5→6 rewrite drops with it because Hibernate 6 arrives with Boot 3. Narrowing is not silencing: `metadata.route` publishes the target, the flag and every excluded axis, a `limitations` entry states how many findings were left out and that they are unresolved rather than fixed, and the route's own blockers stay (a JDK 11 route still reports MIG-021, asserted). The default is untouched, verified identical on three repositories |
|
|
49
|
-
| C1-16 | **Four fan-in figures for one class, and the note that promises the relationship is itself false.** Field: `modernize.in_degree` 1 026 / `impact-chain.direct_callers` 611 / `explain.incoming_callers` 519 / `impact.stats.direct_caller_count` 484 for one service, plus 3 222 vs 3 458 endpoints affected. **Re-measured on the battery, 3.4.0, `Money` @ BroadleafCommerce: 673 / 1 868 / 151 / 418** — `impact-chain` is absent from the published relationship and is **2,8× larger than the figure the note declares "always the largest of the three"**, while `explain` vs `impact` differ by **177 %**, not the *"small margin"* the same note promises. In the same runs `impact.stats.endpoints_affected_count: 0` against a populated `endpoints_affected` from `impact-chain` — a **false zero** on the blast-radius axis | 3.2.1 (eval #5) | **High** — this is the number a risk decision is taken with: *"¿el blast radius son 484 o 611 clases?"* | **
|
|
53
|
+
| C1-16 | **Four fan-in figures for one class, and the note that promises the relationship is itself false.** Field: `modernize.in_degree` 1 026 / `impact-chain.direct_callers` 611 / `explain.incoming_callers` 519 / `impact.stats.direct_caller_count` 484 for one service, plus 3 222 vs 3 458 endpoints affected. **Re-measured on the battery, 3.4.0, `Money` @ BroadleafCommerce: 673 / 1 868 / 151 / 418** — `impact-chain` is absent from the published relationship and is **2,8× larger than the figure the note declares "always the largest of the three"**, while `explain` vs `impact` differ by **177 %**, not the *"small margin"* the same note promises. In the same runs `impact.stats.endpoints_affected_count: 0` against a populated `endpoints_affected` from `impact-chain` — a **false zero** on the blast-radius axis | 3.2.1 (eval #5), reopened 5.5.4 | **High** — this is the number a risk decision is taken with: *"¿el blast radius son 484 o 611 clases?"* | **reopened 5.5.4.** The DI and subtype fixtures remain closed, but the claimed one-authority implementation was false for service locators: `impact` kept a local BFS that elevated `Locator#accessor` to every caller of `Locator`, while `impact-chain` used `caller_reach` and did not. 5.5.4 recovery removes that elevation and adds a two-accessor regression fixture; authority unification and cross-command parity remain open as Q-03. |
|
|
50
54
|
| C1-17 | **A fact with an authority still contradicts itself across two commands**: `--compact.analysis_gaps` says *"1 test file for 3 336 Java files"* while `review-pr.test_coverage_risk.repository_has_test_sources` says `false`, in the same repository. C1-2 was closed in 3.2.1 with five consumers rebound, and this evaluation ran **on 3.2.1** | 3.2.1 (eval #5) | Medium | **does not reproduce (measured 3.6.0)** — re-measured as the row instructed. On openmrs-core, keycloak and spring-petclinic neither statement is emitted, and both consumers reach one authority: `--compact` through `analyze_test_sources`, `review-pr` through `is_test_path`. What was missing is now asserted: the authority has **two entry points** and nothing held them to each other, which is exactly the shape a sixth consumer would take. Zero mismatches across a case table including the C1-2 discriminator (a `test` package inside a *main* source root is production code), plus the literal contradiction — "N test files" and "no test sources" — asserted unreachable in both directions |
|
|
51
55
|
| C1-18 | **The profile population differs per command, and the narrower one is what an agent reads.** Field: `--agent` reports a two-name profile set while `prepare-context fix-bug` reports four for the same repository in the same session — and the two names missing from the agent payload are the ones the *build* names for its deployable artefacts. Every finding about conditional security is keyed on that set, so the default agent surface answers the profile question with the population that lost the environments | 3.5.0 (eval #6) | **High** — it is the input to the one capability nothing else in the market has | **closed (unreleased)** — **fixture first, as C1-10 required**, and it reproduced worse than reported: on `tests/fixtures/spring_profile_population` the same repository in one session answered **`["qa","dev"]`** (default view — filenames + overlay directories), **`["dev","prod","staging"]`** (`posture` — config documents + `@Profile`) and **`["dev","prod","qa","staging"]`** (`--agent` / `fix-bug`, the union). Three populations under one name; every conditional-security finding is keyed on it. Authority `spring_profiles.profile_population`: four named signals (`file_naming`, `overlay_directory`, `config_documents`, `annotations`, plus `caller_supplied`), the union, and `by_signal` published so a name's provenance is auditable. The stack detector, `posture` and the serializer section all read it — asserted per surface, not claimed. Closing it exposed two false positives in the signals it inherited, both fixed structurally (never by name — VAI): an `application-{x}` file counts only **beside its base config** (alfresco's `alfresco/messages/application-model_de.properties` + 19 siblings invented twenty environments; now 0) and an overlay directory counts only when it **holds a config file** (spring-petclinic's `db/ messages/ static/ templates/` reported four; now `mysql, postgres`, which are its real profiles) |
|
|
52
56
|
| C1-19 | **File-count drift across commands, with witnesses this time.** 3 337 (`compact.project_summary`) / 3 336 (`analysis_gaps.testing`) / 3 342 (`migrate-check.metadata.java_files_scanned`) for one repository in one session | 3.8.0 (eval #7) | Medium | **closed 3.9.0** — measured, not equalised: the three figures count code-extension files in any language, the non-test denominator of a test ratio, and the .java files handed to the migration rules. Each names its population now, and `migrate-check.files_scanned_basis` states the two it is not. Original note: open — **C1-14's cross-command half, reopened.** 3.6.0 recorded that half as *not reproducing* because on openmrs-core only `migrate-check` published a scanned-file count at all; eval #7 shows three commands publishing one on a repository we do not have. Three populations are plausible and each may be right in isolation (all Java files / files admitted to the graph / files the migration rules scanned), which is exactly the C1-5 remedy: name the unit per figure, or bind them to one authority. Do not fix by making the numbers equal — measure which population each counts first |
|
|
@@ -2081,6 +2081,14 @@ def _resolve_files_option(
|
|
|
2081
2081
|
|
|
2082
2082
|
raw = str(files).replace(_text_input.BOM_CHAR, "").strip()
|
|
2083
2083
|
if raw == "-":
|
|
2084
|
+
if sys.stdin.isatty():
|
|
2085
|
+
_emit_error_json(
|
|
2086
|
+
INVALID_INPUT_CODE,
|
|
2087
|
+
"--files - reads the file list from stdin, but stdin is a terminal.",
|
|
2088
|
+
hint=f"Pipe the list: git diff --name-only main | ask {command} . --files -",
|
|
2089
|
+
expected="Piped stdin, a list file, or a comma-separated file list.",
|
|
2090
|
+
)
|
|
2091
|
+
raise typer.Exit(code=1)
|
|
2084
2092
|
return _text_input.parse_path_lines(_text_input.read_stdin_text()), "stdin"
|
|
2085
2093
|
as_path = Path(raw)
|
|
2086
2094
|
if as_path.is_file():
|
|
@@ -8867,7 +8875,8 @@ def spring_audit_cmd(
|
|
|
8867
8875
|
help=(
|
|
8868
8876
|
"Bounded summary: caps `findings` and the per-endpoint security projection "
|
|
8869
8877
|
"to their top 5, most-severe first. Every count is still measured over the "
|
|
8870
|
-
"whole population.
|
|
8878
|
+
"whole population. Stdout also switches to this form only when the full "
|
|
8879
|
+
"JSON exceeds its 50 KB budget; use --output for the complete report."
|
|
8871
8880
|
),
|
|
8872
8881
|
),
|
|
8873
8882
|
table: bool = typer.Option(
|
|
@@ -9204,17 +9213,19 @@ def spring_audit_cmd(
|
|
|
9204
9213
|
"phase that never ran is not evidence there is none."
|
|
9205
9214
|
)
|
|
9206
9215
|
|
|
9216
|
+
_full_data = combined.to_dict()
|
|
9207
9217
|
_bounded_default = (
|
|
9208
9218
|
not compact and output_path is None and format == "json" and not table
|
|
9219
|
+
and len(_json.dumps(_full_data, ensure_ascii=False).encode("utf-8")) > 50_000
|
|
9209
9220
|
)
|
|
9210
|
-
data = (
|
|
9211
|
-
combined.to_compact_dict()
|
|
9212
|
-
if compact or _bounded_default
|
|
9213
|
-
else combined.to_dict()
|
|
9214
|
-
)
|
|
9221
|
+
data = combined.to_compact_dict() if compact or _bounded_default else _full_data
|
|
9215
9222
|
if _bounded_default:
|
|
9216
9223
|
data.pop("mode", None)
|
|
9217
9224
|
data["default_output"] = "bounded"
|
|
9225
|
+
data.pop("compact_note", None)
|
|
9226
|
+
data["stdout_budget_note"] = (
|
|
9227
|
+
"Capped by the stdout payload budget; use --output <file> for the complete report."
|
|
9228
|
+
)
|
|
9218
9229
|
data.setdefault("metadata", {})["cache_layers"] = _cache_state
|
|
9219
9230
|
if _stopped_early:
|
|
9220
9231
|
# C3-87: the block is composed by `PhasedRun.status`, which is the
|
|
@@ -9249,17 +9260,19 @@ def spring_audit_cmd(
|
|
|
9249
9260
|
elif format == "github-comment":
|
|
9250
9261
|
output = _render_spring_audit_github_comment(combined, min_severity)
|
|
9251
9262
|
else:
|
|
9263
|
+
_full_data = combined.to_dict()
|
|
9252
9264
|
_bounded_default = (
|
|
9253
9265
|
not compact and output_path is None and format == "json" and not table
|
|
9266
|
+
and len(_json.dumps(_full_data, ensure_ascii=False).encode("utf-8")) > 50_000
|
|
9254
9267
|
)
|
|
9255
|
-
data = (
|
|
9256
|
-
combined.to_compact_dict()
|
|
9257
|
-
if compact or _bounded_default
|
|
9258
|
-
else combined.to_dict()
|
|
9259
|
-
)
|
|
9268
|
+
data = combined.to_compact_dict() if compact or _bounded_default else _full_data
|
|
9260
9269
|
if _bounded_default:
|
|
9261
9270
|
data.pop("mode", None)
|
|
9262
9271
|
data["default_output"] = "bounded"
|
|
9272
|
+
data.pop("compact_note", None)
|
|
9273
|
+
data["stdout_budget_note"] = (
|
|
9274
|
+
"Capped by the stdout payload budget; use --output <file> for the complete report."
|
|
9275
|
+
)
|
|
9263
9276
|
output = _serialize_dict(data, format)
|
|
9264
9277
|
|
|
9265
9278
|
# F-AV: our own readers ask for the count under either spelling — the break
|
|
@@ -12870,7 +12883,8 @@ def config_cmd(
|
|
|
12870
12883
|
_answer.say(f"Declaration: none at {_declaration_path}")
|
|
12871
12884
|
_answer.say(
|
|
12872
12885
|
" Nothing is declared, so `data-exposure` answers "
|
|
12873
|
-
"`answered: false
|
|
12886
|
+
"`answered: false`. Custom security annotations may still be inferred "
|
|
12887
|
+
"from usage with Likely confidence; declare them to make that policy Declared."
|
|
12874
12888
|
)
|
|
12875
12889
|
else:
|
|
12876
12890
|
_answer.say(f"Declaration: {_declaration_path}")
|
|
@@ -6448,6 +6448,7 @@ def extract_java_endpoints(
|
|
|
6448
6448
|
# calls. One candidate list keeps that work bounded and reusable below.
|
|
6449
6449
|
_config_files = sorted(root.rglob("application*.*"))
|
|
6450
6450
|
_excluded_test_source_routes = 0
|
|
6451
|
+
_excluded_test_patterns: set[str] = set()
|
|
6451
6452
|
if not include_tests:
|
|
6452
6453
|
_route_marker = _re.compile(
|
|
6453
6454
|
r"@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping|RequestMapping|GET|POST|PUT|DELETE|PATCH|Path)\b"
|
|
@@ -6456,6 +6457,15 @@ def extract_java_endpoints(
|
|
|
6456
6457
|
_candidate_rel = _rel(_candidate)
|
|
6457
6458
|
if not is_test_source_file(_candidate_rel):
|
|
6458
6459
|
continue
|
|
6460
|
+
_candidate_parts = _candidate_rel.lower().split("/")
|
|
6461
|
+
if "test-suite" in _candidate_parts:
|
|
6462
|
+
_excluded_test_patterns.add("test-suite/")
|
|
6463
|
+
elif "src/test/" in _candidate_rel.lower():
|
|
6464
|
+
_excluded_test_patterns.add("src/test/")
|
|
6465
|
+
elif "src/it/" in _candidate_rel.lower():
|
|
6466
|
+
_excluded_test_patterns.add("src/it/")
|
|
6467
|
+
else:
|
|
6468
|
+
_excluded_test_patterns.add("test-source classification")
|
|
6459
6469
|
try:
|
|
6460
6470
|
_excluded_test_source_routes += len(
|
|
6461
6471
|
_route_marker.findall(_candidate.read_text(encoding="utf-8", errors="replace"))
|
|
@@ -6962,6 +6972,11 @@ def extract_java_endpoints(
|
|
|
6962
6972
|
result["test_util_included"] = len(_test_util_endpoints)
|
|
6963
6973
|
if _excluded_test_source_routes:
|
|
6964
6974
|
result["test_source_excluded"] = _excluded_test_source_routes
|
|
6975
|
+
result["test_source_excluded_detail"] = {
|
|
6976
|
+
"count": _excluded_test_source_routes,
|
|
6977
|
+
"patterns_matched": sorted(_excluded_test_patterns),
|
|
6978
|
+
"basis": "path classification; use --include-tests to include these routes",
|
|
6979
|
+
}
|
|
6965
6980
|
result.setdefault("notes", []).append(
|
|
6966
6981
|
f"{_excluded_test_source_routes} route annotation(s) from test source trees "
|
|
6967
6982
|
"were excluded; use --include-tests to include them."
|
|
@@ -7187,6 +7202,10 @@ _DISPLAY_INDIRECT_CALLERS = 50
|
|
|
7187
7202
|
HUB_CALLER_THRESHOLD = 500
|
|
7188
7203
|
HUB_SAMPLE_SIZE = 20
|
|
7189
7204
|
HUB_SAMPLE_DEPTH = 2
|
|
7205
|
+
# A frontier is a hub for this query when it materially exceeds the target's
|
|
7206
|
+
# own fan-in, even if it does not reach the global safety cap above.
|
|
7207
|
+
HUB_RELATIVE_FANIN_MULTIPLIER = 3
|
|
7208
|
+
HUB_RELATIVE_FANIN_FLOOR = 20
|
|
7190
7209
|
|
|
7191
7210
|
|
|
7192
7211
|
def _symbol_listing_advice(root: "Optional[Path]") -> str:
|
|
@@ -7339,21 +7358,15 @@ def compute_blast_radius(
|
|
|
7339
7358
|
_rg_index = _class_method_index(reverse_graph)
|
|
7340
7359
|
|
|
7341
7360
|
def _walk_callers(_node: str) -> list[str]:
|
|
7342
|
-
"""
|
|
7361
|
+
"""Return the one-authority caller set for this exact frontier node.
|
|
7343
7362
|
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7363
|
+
`caller_reach` expands class nodes through their method keys, which is
|
|
7364
|
+
required for DI-normalized class frontiers. It deliberately does not
|
|
7365
|
+
invert that containment for a method: callers of `Locator#getA` are a
|
|
7366
|
+
subset of callers of `Locator`, and adding the latter leaks users of
|
|
7367
|
+
every other locator accessor into the blast cone.
|
|
7348
7368
|
"""
|
|
7349
|
-
|
|
7350
|
-
_node, reverse_graph, _rg_index, _impl_graph
|
|
7351
|
-
))
|
|
7352
|
-
if "#" in _node:
|
|
7353
|
-
candidates.extend(_all_callers_from_rg(
|
|
7354
|
-
_enclosing_class(_node), reverse_graph, _rg_index, _impl_graph
|
|
7355
|
-
))
|
|
7356
|
-
return list(dict.fromkeys(candidates))
|
|
7369
|
+
return _all_callers_from_rg(_node, reverse_graph, _rg_index, _impl_graph)
|
|
7357
7370
|
# Callers inject the interface, not the implementation, so a walk that does not
|
|
7358
7371
|
# know the implements relation stops one hop short of every DI consumer. Without
|
|
7359
7372
|
# it this traversal reached 200 classes and **no controller at all** for
|
|
@@ -7473,6 +7486,26 @@ def compute_blast_radius(
|
|
|
7473
7486
|
if _effective_depth > 1:
|
|
7474
7487
|
queue.append((c, 1))
|
|
7475
7488
|
|
|
7489
|
+
# A locator accessor can be a narrow method frontier on a broad class hub.
|
|
7490
|
+
# Measure the owner only to classify that frontier, never to expand it: the
|
|
7491
|
+
# latter would merge callers of unrelated accessors (Q-01).
|
|
7492
|
+
_seed_fan_in = max(1, len(set(direct_callers)))
|
|
7493
|
+
_hub_frontier_cutoff = max(
|
|
7494
|
+
HUB_RELATIVE_FANIN_FLOOR,
|
|
7495
|
+
_seed_fan_in * HUB_RELATIVE_FANIN_MULTIPLIER,
|
|
7496
|
+
)
|
|
7497
|
+
|
|
7498
|
+
def _is_hub_frontier(_node: str) -> bool:
|
|
7499
|
+
_fan_in = len(_walk_callers(_node))
|
|
7500
|
+
if "#" in _node:
|
|
7501
|
+
_fan_in = max(
|
|
7502
|
+
_fan_in,
|
|
7503
|
+
len(_all_callers_from_rg(
|
|
7504
|
+
_enclosing_class(_node), reverse_graph, _rg_index, _impl_graph
|
|
7505
|
+
)),
|
|
7506
|
+
)
|
|
7507
|
+
return _fan_in > _hub_frontier_cutoff
|
|
7508
|
+
|
|
7476
7509
|
# BFS for indirect callers
|
|
7477
7510
|
indirect_callers: list[str] = []
|
|
7478
7511
|
_indirect_parent: dict[str, str] = {}
|
|
@@ -7484,7 +7517,7 @@ def compute_blast_radius(
|
|
|
7484
7517
|
if depth >= _effective_depth:
|
|
7485
7518
|
continue
|
|
7486
7519
|
_node_callers = _walk_callers(node)
|
|
7487
|
-
if
|
|
7520
|
+
if _is_hub_frontier(node):
|
|
7488
7521
|
_hub_frontier_nodes.add(node)
|
|
7489
7522
|
for caller in _node_callers:
|
|
7490
7523
|
if caller not in visited:
|
|
@@ -7735,7 +7768,7 @@ def compute_blast_radius(
|
|
|
7735
7768
|
if _depth >= _effective_depth:
|
|
7736
7769
|
continue
|
|
7737
7770
|
_next = _walk_callers(_node)
|
|
7738
|
-
if
|
|
7771
|
+
if _is_hub_frontier(_node):
|
|
7739
7772
|
continue
|
|
7740
7773
|
for _caller in _next:
|
|
7741
7774
|
if _caller not in _without_hubs_seen:
|
|
@@ -276,7 +276,13 @@ def _scan_java(source: str, rel: str) -> "list[SecurityConfigObservation]":
|
|
|
276
276
|
))
|
|
277
277
|
break # one observation per algorithm per file
|
|
278
278
|
for encoder in _DEPRECATED_ENCODERS:
|
|
279
|
-
|
|
279
|
+
# An import only makes the type available; it is not evidence that
|
|
280
|
+
# a password encoder is used. Require construction or the legacy
|
|
281
|
+
# factory call so the witness opens on a remediation site.
|
|
282
|
+
m = re.search(
|
|
283
|
+
rf"(?:new\s+{re.escape(encoder)}\b|{re.escape(encoder)}\s*\.\s*getInstance\s*\()",
|
|
284
|
+
source,
|
|
285
|
+
)
|
|
280
286
|
if m:
|
|
281
287
|
out.append(SecurityConfigObservation(
|
|
282
288
|
rule="SEC-004",
|
|
@@ -83,12 +83,12 @@ def _child_text(elem: "ET.Element", name: str) -> str:
|
|
|
83
83
|
return ""
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
def _from_web_xml(xml_path: Path, relative: str) -> "list[ServletMapping]":
|
|
86
|
+
def _from_web_xml(xml_path: Path, relative: str) -> "tuple[list[ServletMapping], int]":
|
|
87
87
|
try:
|
|
88
88
|
text = xml_path.read_text(encoding="utf-8", errors="replace")
|
|
89
89
|
root = ET.fromstring(text)
|
|
90
90
|
except Exception:
|
|
91
|
-
return []
|
|
91
|
+
return [], 0
|
|
92
92
|
classes: "dict[str, str]" = {}
|
|
93
93
|
for elem in root.iter():
|
|
94
94
|
if _local(elem.tag) != "servlet":
|
|
@@ -98,10 +98,17 @@ def _from_web_xml(xml_path: Path, relative: str) -> "list[ServletMapping]":
|
|
|
98
98
|
if name:
|
|
99
99
|
classes[name] = klass
|
|
100
100
|
out: "list[ServletMapping]" = []
|
|
101
|
+
undeclared_servlet_mappings = 0
|
|
101
102
|
for elem in root.iter():
|
|
102
103
|
if _local(elem.tag) != "servlet-mapping":
|
|
103
104
|
continue
|
|
104
105
|
name = _child_text(elem, "servlet-name")
|
|
106
|
+
if not name or name not in classes:
|
|
107
|
+
undeclared_servlet_mappings += sum(
|
|
108
|
+
1 for child in elem.iter()
|
|
109
|
+
if _local(child.tag) == "url-pattern" and (child.text or "").strip()
|
|
110
|
+
)
|
|
111
|
+
continue
|
|
105
112
|
for child in elem.iter():
|
|
106
113
|
if _local(child.tag) != "url-pattern" or not (child.text or "").strip():
|
|
107
114
|
continue
|
|
@@ -122,10 +129,13 @@ def _from_web_xml(xml_path: Path, relative: str) -> "list[ServletMapping]":
|
|
|
122
129
|
pattern_match = re.search(r"<url-pattern\b[^>]*>\s*([^<]+?)\s*</url-pattern>", block, re.DOTALL | re.IGNORECASE)
|
|
123
130
|
if not pattern_match:
|
|
124
131
|
continue
|
|
132
|
+
servlet_name = name_match.group(1).strip() if name_match else ""
|
|
133
|
+
if not servlet_name or servlet_name not in classes:
|
|
134
|
+
continue
|
|
125
135
|
candidate = ServletMapping(
|
|
126
136
|
url_pattern=pattern_match.group(1).strip(),
|
|
127
|
-
servlet_name=
|
|
128
|
-
servlet_class=classes
|
|
137
|
+
servlet_name=servlet_name,
|
|
138
|
+
servlet_class=classes[servlet_name],
|
|
129
139
|
source_file=relative,
|
|
130
140
|
source="web.xml",
|
|
131
141
|
)
|
|
@@ -133,7 +143,7 @@ def _from_web_xml(xml_path: Path, relative: str) -> "list[ServletMapping]":
|
|
|
133
143
|
out.append(candidate)
|
|
134
144
|
except Exception:
|
|
135
145
|
pass
|
|
136
|
-
return out
|
|
146
|
+
return out, undeclared_servlet_mappings
|
|
137
147
|
|
|
138
148
|
|
|
139
149
|
def _from_registration_beans(java_path: Path, relative: str) -> "list[ServletMapping]":
|
|
@@ -178,6 +188,7 @@ def build_servlet_surface(
|
|
|
178
188
|
|
|
179
189
|
root = Path(root)
|
|
180
190
|
mappings: "list[ServletMapping]" = []
|
|
191
|
+
undeclared_servlet_mappings = 0
|
|
181
192
|
if files is None:
|
|
182
193
|
candidates: list[Path] = []
|
|
183
194
|
for directory, dirs, names in os.walk(root):
|
|
@@ -209,7 +220,9 @@ def build_servlet_surface(
|
|
|
209
220
|
except ValueError:
|
|
210
221
|
relative = Path(path).as_posix()
|
|
211
222
|
if path.name == "web.xml":
|
|
212
|
-
|
|
223
|
+
parsed, omitted = _from_web_xml(path, relative)
|
|
224
|
+
mappings.extend(parsed)
|
|
225
|
+
undeclared_servlet_mappings += omitted
|
|
213
226
|
elif path.suffix == ".java":
|
|
214
227
|
mappings.extend(_from_registration_beans(path, relative))
|
|
215
228
|
|
|
@@ -221,6 +234,7 @@ def build_servlet_surface(
|
|
|
221
234
|
_unique: dict[str, ServletMapping] = {}
|
|
222
235
|
for mapping in sorted(mappings, key=lambda m: (m.url_pattern, m.source_file, m.source)):
|
|
223
236
|
_unique.setdefault(mapping.url_pattern, mapping)
|
|
237
|
+
declared_mappings = list(mappings)
|
|
224
238
|
mappings = list(_unique.values())
|
|
225
239
|
patterns = sorted(_unique)
|
|
226
240
|
by_source: "dict[str, int]" = {}
|
|
@@ -232,15 +246,25 @@ def build_servlet_surface(
|
|
|
232
246
|
)]
|
|
233
247
|
shown = rows if limit is None else rows[:limit]
|
|
234
248
|
|
|
249
|
+
display_omitted = len(rows) - len(shown)
|
|
250
|
+
omitted_total = undeclared_servlet_mappings + display_omitted
|
|
251
|
+
omitted_by_reason: dict[str, int] = {}
|
|
252
|
+
if undeclared_servlet_mappings:
|
|
253
|
+
omitted_by_reason["servlet_not_declared"] = undeclared_servlet_mappings
|
|
254
|
+
if display_omitted:
|
|
255
|
+
omitted_by_reason["display_limit"] = display_omitted
|
|
256
|
+
|
|
235
257
|
return {
|
|
236
258
|
"schema_version": SCHEMA_VERSION,
|
|
237
259
|
"population_key": POPULATION,
|
|
238
260
|
"total_url_patterns": len(patterns),
|
|
239
|
-
"declarations": len(
|
|
261
|
+
"declarations": len(declared_mappings),
|
|
262
|
+
"declarations_unit": "live servlet-mapping declarations before URL-pattern deduplication",
|
|
240
263
|
"by_source": dict(sorted(by_source.items())),
|
|
241
264
|
"url_patterns": patterns,
|
|
242
265
|
"mappings": shown,
|
|
243
|
-
"mappings_omitted":
|
|
266
|
+
"mappings_omitted": omitted_total,
|
|
267
|
+
"mappings_omitted_by_reason": omitted_by_reason,
|
|
244
268
|
"population": (
|
|
245
269
|
"servlet mappings declared in `web.xml` or registered as a "
|
|
246
270
|
"`ServletRegistrationBean` — HTTP surface that is NOT a Spring handler "
|
|
@@ -614,7 +614,16 @@ def build_validation_surface(
|
|
|
614
614
|
"summary": {
|
|
615
615
|
"endpoints_with_body": len(out_endpoints),
|
|
616
616
|
"validated_fields": total_validated_fields,
|
|
617
|
+
# This catalog contains annotation-based ConstraintValidator types.
|
|
618
|
+
# Spring Validator wiring is detected separately below and must not
|
|
619
|
+
# be read as zero just because it belongs to another population.
|
|
617
620
|
"custom_validators_declared": len(custom_list),
|
|
621
|
+
"custom_validators_declared_unit": "annotation-based ConstraintValidator declarations",
|
|
622
|
+
"programmatic_validators_declared": len(programmatic_evidence),
|
|
623
|
+
"programmatic_validators_declared_unit": (
|
|
624
|
+
"detected org.springframework.validation.Validator implementations "
|
|
625
|
+
"or setValidator wiring; rules are not modeled per endpoint"
|
|
626
|
+
),
|
|
618
627
|
"custom_validators_linked": len(custom_used),
|
|
619
628
|
"gaps": len(gaps),
|
|
620
629
|
},
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-knowledge-provider-integration.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-p6-semantic-integration-engine.md
RENAMED
|
File without changes
|
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/DESIGN-robustness-security-inference.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p6-flow-analyzer-comparison.md
RENAMED
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p6-integration-detector-comparison.md
RENAMED
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p8-flow-analyzer-migration.md
RENAMED
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/REPORT-p9-integration-detector-migration.md
RENAMED
|
File without changes
|
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0002-source-evidence-boundary.md
RENAMED
|
File without changes
|
{sourcecode-5.5.4 → sourcecode-5.5.5}/docs/architecture/adr/0003-architectural-characterization.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|