sourcecode 4.2.0__tar.gz → 4.3.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-4.2.0 → sourcecode-4.3.0}/CHANGELOG.md +182 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/PKG-INFO +27 -8
- {sourcecode-4.2.0 → sourcecode-4.3.0}/README.md +26 -7
- {sourcecode-4.2.0 → sourcecode-4.3.0}/pyproject.toml +1 -1
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architectural_baseline.py +19 -0
- sourcecode-4.3.0/src/sourcecode/baseline_autocapture.py +375 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cache_model.py +19 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cli.py +552 -23
- sourcecode-4.3.0/src/sourcecode/client_calls.py +305 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_graph.py +11 -0
- sourcecode-4.3.0/src/sourcecode/data_exposure.py +353 -0
- sourcecode-4.3.0/src/sourcecode/data_labels.py +200 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/dynamic_argument_surface.py +12 -5
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/format_contract.py +1 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/non_coverage.py +45 -0
- sourcecode-4.3.0/src/sourcecode/openrewrite_recipe.py +278 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/posture.py +32 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/repository_ir.py +24 -3
- sourcecode-4.3.0/src/sourcecode/risk.py +764 -0
- sourcecode-4.3.0/src/sourcecode/sarif.py +618 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/validation_inference.py +33 -4
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/verify_repo.py +17 -2
- sourcecode-4.2.0/src/sourcecode/risk.py +0 -403
- {sourcecode-4.2.0 → sourcecode-4.3.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/.gitignore +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/.ruff.toml +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/CONTRIBUTING.md +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/LICENSE +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/SECURITY.md +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/raw +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/scripts/perf_harness.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/archetype.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/compare.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/degradation.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/envelope.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/environment_resolution.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/explain.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/license.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/perf.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/release_info.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/remedies.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/rule_catalog.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/security_config.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/security_config_scan.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/README.md +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-4.2.0 → sourcecode-4.3.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,188 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`ask migrate-recipe` — the migration report in the form the executor takes**
|
|
8
|
+
(roadmap M10.5 item 5 / M8.5, experimental). `migrate-check` already names the
|
|
9
|
+
OpenRewrite recipe each finding carries (296 of 309 on openmrs-core) and a reader
|
|
10
|
+
still had to copy them out of a JSON payload by hand — field evaluation #4's verdict
|
|
11
|
+
on that gap was *"el informe muere en un cajón; el codemod se convierte en PRs"*. The
|
|
12
|
+
command emits the declarative composite recipe naming exactly those recipes, the
|
|
13
|
+
artifact coordinates derived from their packages, and the invocation for the build the
|
|
14
|
+
repository declares (Maven or Gradle). It writes nothing without `--write`, so an audit
|
|
15
|
+
of somebody else's repository can run it; `--write` refuses to replace an existing
|
|
16
|
+
`rewrite.yml` without `--force`. **Nothing here edits source** — that is NC-005's
|
|
17
|
+
position, not a gap: OpenRewrite is the executor and this is its input.
|
|
18
|
+
- The recipe list comes from the findings, never from a catalogue of what OpenRewrite
|
|
19
|
+
can do: a recipe nobody's finding asked for would rewrite code nobody measured.
|
|
20
|
+
- Every finding with no recipe is published under `manual_remainder`. Measured on
|
|
21
|
+
BroadleafCommerce: **25 blocking findings in product code and not one automatable**,
|
|
22
|
+
which is an answer, not an empty result — and the reason an empty recipe list prints
|
|
23
|
+
*no* runnable command, because `mvn … rewrite:run` over nothing is a green executor
|
|
24
|
+
run that reads as "the migration is automated".
|
|
25
|
+
- Advisory hygiene is excluded by default (`--include-hygiene` opts in): on openmrs-core
|
|
26
|
+
it takes the population from 125 findings to 309 and adds `JavaTimeAPIs`, and a
|
|
27
|
+
migration diff that also modernises date handling cannot be reviewed as one change.
|
|
28
|
+
- The coverage block names **both** populations — its own and `migrate-check`'s narrower
|
|
29
|
+
`blocking_count` (125 against 114 on openmrs-core) — because two populations under one
|
|
30
|
+
name is the defect this project keeps finding in its own output.
|
|
31
|
+
|
|
32
|
+
## [4.3.0] — 2026-08-03
|
|
33
|
+
|
|
34
|
+
Minor, not a patch: two commands are new (`ask enrich`, `ask data-exposure`), the
|
|
35
|
+
composed risk model gains two factors, and `ask verify` writes a file where it
|
|
36
|
+
wrote none — every one of them additive, none of them removing a published field
|
|
37
|
+
or moving an exit code. A pipeline that reads this release the way it read 4.2.0
|
|
38
|
+
gets the same answers, plus blocks it can ignore.
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **`ask baseline capture --auto` — an architectural history that does not depend on
|
|
43
|
+
somebody remembering** (roadmap M10.5, head of the milestone). The snapshot has
|
|
44
|
+
shipped since D5; the *series* is the asset a competitor cannot backfill, and in
|
|
45
|
+
every repository measured so far its length is zero, because capture is a command a
|
|
46
|
+
human has to type. `--auto` is the form a pipeline can keep: it captures one baseline
|
|
47
|
+
per commit, keeps an already-captured commit instead of relabelling it, refuses to
|
|
48
|
+
file a tree with uncommitted changes under the commit it would be stored as, and
|
|
49
|
+
**exits 0 whatever happens** — a build never goes red because a snapshot could not be
|
|
50
|
+
taken. Every outcome names itself (`captured` / `skipped` with the reason and a
|
|
51
|
+
sentence of effect), so a pipeline log says which happened rather than going quiet.
|
|
52
|
+
A skip costs no analysis: the decision is taken before the IR is built, so the common
|
|
53
|
+
case in a per-push job is ~0.2 s against 1.8 s for a capture. New authority
|
|
54
|
+
`sourcecode/baseline_autocapture.py`; `docs/baseline-ci.yml` now captures per merge
|
|
55
|
+
as well as per tag.
|
|
56
|
+
- **`ask data-exposure` — which routes can carry the data you labelled, and who
|
|
57
|
+
reaches them** (roadmap M10.5 item 3, experimental). Nothing here detects sensitive
|
|
58
|
+
data: a label is a judgement about a domain, a field named `dni` is a national
|
|
59
|
+
identifier in one repository and a column name in another, and the engine never
|
|
60
|
+
branches on a name (VAI). It is declared once under `dataLabels` in
|
|
61
|
+
`sourcecode.config.json`; everything after that is measured over authorities that
|
|
62
|
+
already exist — the call reach `impact-chain` walks, the endpoint security surface
|
|
63
|
+
`risk` weighs, the profile resolution `posture` publishes (`--profile`). Two evidence
|
|
64
|
+
classes, published apart and never added together: `signature` (the handler names the
|
|
65
|
+
labelled type in its own signature) and `call_reach` (the chain reaches it — a
|
|
66
|
+
supremum, not a proof, because the mapping in between is not modelled: NC-008).
|
|
67
|
+
Measured: petclinic labelling `Owner#telephone` → **7 routes by signature**;
|
|
68
|
+
BroadleafCommerce labelling `Customer` → **6 by call reach and none by signature**,
|
|
69
|
+
because those controllers return view names. A repository that declared nothing is
|
|
70
|
+
`answered: false`, never zero exposed routes, and a declared type the graph never
|
|
71
|
+
resolved is named with the note that this is not evidence it is unexposed.
|
|
72
|
+
- **A request handler declares types too.** `_extract_class_type_refs` enumerated
|
|
73
|
+
`symbol_kind == "method"`, and a handler is classified `endpoint` at emission (a
|
|
74
|
+
factory method `bean`), so the class-scope type surface contained **no controller
|
|
75
|
+
signature anywhere in a repository**: `structural_references_to_type("Owner")` on
|
|
76
|
+
petclinic returned 3 atoms, none of them a route that takes an `Owner` as its request
|
|
77
|
+
body, and "which routes accept or return this type" answered nothing while looking
|
|
78
|
+
like an answer. Now 10 atoms, 7 of them handler signatures. Same shape as the F.4-1
|
|
79
|
+
body-surface seam, one scope up; `member_kind` still publishes the kind the symbol was
|
|
80
|
+
classified with.
|
|
81
|
+
- **The history answers from the repository path.** `ask trend .` and
|
|
82
|
+
`ask baseline trend .` now take either a repository or a directory of baselines, and
|
|
83
|
+
`ask baseline diff .` defaults to the newest point in that repository's own history
|
|
84
|
+
instead of requiring `--baseline <file>`. Capture writes to `<repo>/.ask/baselines`,
|
|
85
|
+
so making the reader name the storage directory was the same friction that kept the
|
|
86
|
+
series empty. An explicit directory (the `--dir` case) is unchanged, and a repository
|
|
87
|
+
with no history gets an error that names how to start one. New
|
|
88
|
+
`architectural_baseline.latest_baseline_path`, ordered exactly as the trend series is
|
|
89
|
+
ordered so "the last point" and "the base of a default diff" cannot disagree.
|
|
90
|
+
- **`ask verify` carries the history for free.** The gate is the run that already happens
|
|
91
|
+
on every push and already builds the IR a baseline is extracted from, so where a
|
|
92
|
+
repository keeps `.ask/baselines` the gate adds the current commit to it and publishes
|
|
93
|
+
what it did under `architectural_history` — on every run, including the ones that
|
|
94
|
+
captured nothing, because a series that silently stopped growing is invisible until the
|
|
95
|
+
day somebody needs it (I-8). Measured on BroadleafCommerce: 3.9 s with the capture
|
|
96
|
+
against 4.0 s without, i.e. inside the noise; eureka 1.8 s against 0.8 s (its IR is
|
|
97
|
+
smaller, the extraction is not). The passenger cannot move the gate: the verdict, the
|
|
98
|
+
exit code and every other field are identical with and without it, and an exception
|
|
99
|
+
inside it is swallowed. `ASK_BASELINE_AUTOCAPTURE=0/1` overrides in both directions.
|
|
100
|
+
- ⚠One measured cost stated rather than hidden: a baseline is ~730 KB on a 3 300-file
|
|
101
|
+
monolith, because it stores the full endpoint surface and fan-in map so a later
|
|
102
|
+
`baseline diff` is faithful. A point per merge is a megabyte-scale history; a point
|
|
103
|
+
per release is not. `--dir` sends them outside the repository.
|
|
104
|
+
- ⚠Found by the battery, not by the field: the first capture writes an untracked file
|
|
105
|
+
**inside the repository**, so a plain `git status --porcelain` check would have
|
|
106
|
+
reported a dirty tree from then on and every later run would have skipped — a
|
|
107
|
+
history of exactly one. The dirtiness question excludes this tool's own footprint
|
|
108
|
+
(`.ask/`) and nothing else, because everything else is what the baseline measures —
|
|
109
|
+
and the second half of that came from eureka, where `verify --init` writes
|
|
110
|
+
`.ask/contracts.yml` and, counted as a modification, would stop the history from
|
|
111
|
+
ever starting.
|
|
112
|
+
- **`ask enrich --sarif <log>` — somebody else's detection, ranked by what this
|
|
113
|
+
repository does with it** (roadmap M10, first deliverable). This product does not
|
|
114
|
+
detect injection, CVEs or secrets and says so in every security payload (NC-001,
|
|
115
|
+
NC-002); the scanners that do have no bean graph, no profile model and no endpoint
|
|
116
|
+
id they share with anything, so their output is a list nobody can order. `enrich`
|
|
117
|
+
reads a SARIF 2.1.0 log from Semgrep, CodeQL or Trivy and runs the **same
|
|
118
|
+
composition** `ask risk` runs over each finding — same axes, same weights, same
|
|
119
|
+
`RiskComposer` — with one difference: `defect_severity` is the scanner's own
|
|
120
|
+
verdict (`security-severity` when the tool published one, `level` otherwise),
|
|
121
|
+
carried through with the scanner named as its authority. Nothing re-rates,
|
|
122
|
+
confirms or contradicts a finding. Results sharing (tool, rule, symbol) are one
|
|
123
|
+
defect with several witnesses; a result the join could not place — a file outside
|
|
124
|
+
the population this build read, a line with no declaration above it — is published
|
|
125
|
+
under `unresolved` with the reason, never dropped.
|
|
126
|
+
- **The CVE half of the same command: a dependency finding is joined through the
|
|
127
|
+
coordinate, not through a line.** A result located on `pom.xml` or
|
|
128
|
+
`build.gradle` is about a library, so the coordinate is read back out of the
|
|
129
|
+
manifest the scanner named and the reach is the worst of the types that import
|
|
130
|
+
it — *of forty vulnerable dependencies, which ones does an unauthenticated route
|
|
131
|
+
actually reach?* Importers are found from the IR's existing `imports` edges, by
|
|
132
|
+
the coordinate's group id or by its artifact id as a package segment, and each
|
|
133
|
+
row publishes which basis found them. A library nothing imports is `unresolved`
|
|
134
|
+
and never "unreachable": reflection, a service loader and use through another
|
|
135
|
+
dependency all leave no import edge. Both kinds rank in one list, because a CVE
|
|
136
|
+
in a reachable library and an injection finding in a handler are the same
|
|
137
|
+
question to whoever decides what to fix first.
|
|
138
|
+
- **`--profile <set>` on `ask risk` and `ask enrich` — profile context per finding**
|
|
139
|
+
(M10 exit criterion). The access axis stops answering for *the repository as
|
|
140
|
+
configured* and answers for *that deployment*: `posture` resolves the conditional
|
|
141
|
+
bean graph and the request chain under the named set, through a new published
|
|
142
|
+
seam (`posture.endpoint_access_under`, `posture.access_verdict`), so a composed
|
|
143
|
+
row and a `posture` run can never disagree about the same profile set. A decision
|
|
144
|
+
resolves an endpoint the repository-wide surface left at `coverage_unknown`, in
|
|
145
|
+
either direction — measured on a fixture, one defect scores 11.52/`open` under
|
|
146
|
+
`dev`, 8.06/`unknown` with no set named, and 5.76/`protected` under `prod`. When
|
|
147
|
+
both authorities decided, the worse of them wins, per endpoint.
|
|
148
|
+
- **`ask risk` gains a fifth factor: `query_construction`** (roadmap F.4-1). The
|
|
149
|
+
field asked the question this answers the structural half of — *"con 618 HQL
|
|
150
|
+
concatenados, ¿alguno concatena entrada de request?"* Following request input to
|
|
151
|
+
a query is dataflow, is declared out of scope in NC-001, and stays there. What
|
|
152
|
+
is publishable without it is the adjacency: this defect's own code assembles a
|
|
153
|
+
query string by concatenation, and the four factors beside it already say whether
|
|
154
|
+
that code is reachable, unauthenticated and writing. Read from the α
|
|
155
|
+
argument-shape atoms the IR already carries (`dynamic_argument_surface`) — no new
|
|
156
|
+
analysis, one pass, joined per defect. `not_observed` means the shape was absent
|
|
157
|
+
from the body facts; it is never a claim that a query is safely parameterised.
|
|
158
|
+
- **…and a sixth: `input_constraints`** — the other half of the same field question
|
|
159
|
+
(*"1 201 bodies sin validación"*). Joined by route against `validation`'s gap
|
|
160
|
+
list: `absent` means one of the endpoints reaching this defect accepts a request
|
|
161
|
+
body with no declared constraint, taking the worst of the reached routes for the
|
|
162
|
+
reason the auth axis does. `ask risk` now publishes the `non_coverage` block too,
|
|
163
|
+
because two axes describing the input path, composed with an open access verdict,
|
|
164
|
+
read as *injection* unless the payload states that no dataflow was followed.
|
|
165
|
+
|
|
166
|
+
### Fixed
|
|
167
|
+
|
|
168
|
+
- **`validation` counted handlers that take no argument as body endpoints.** The
|
|
169
|
+
body surface was the verb alone (POST/PUT/PATCH) and the declared limitation said
|
|
170
|
+
the parameter list was not captured. It is now captured (`_handler_params`) and
|
|
171
|
+
read in the negative direction only: an empty parameter list proves no body can
|
|
172
|
+
bind. A handler whose parameters are all path or query values still counts, and
|
|
173
|
+
the limitation says so.
|
|
174
|
+
|
|
175
|
+
- **The α argument-shape surface was blind to every controller body.**
|
|
176
|
+
`dynamic_argument_surface` walked `kind="method"` and `kind="constructor"` symbol
|
|
177
|
+
nodes; a request handler is a `kind="endpoint"` node. The owner population is now
|
|
178
|
+
the body-fact layer's own (`ContextGraph.body_owners()`).
|
|
179
|
+
|
|
180
|
+
### Changed
|
|
181
|
+
|
|
182
|
+
- `severity_effective` in `ask risk` can now be larger for a row whose code
|
|
183
|
+
concatenates a query. Every factor's neutral value is 1.0, so a new axis only
|
|
184
|
+
ever moves a row **up**: no band a reader has already acted on is demoted by
|
|
185
|
+
this release.
|
|
186
|
+
|
|
5
187
|
## [4.2.0] — 2026-08-03
|
|
6
188
|
|
|
7
189
|
Minor, not a patch, by this project's own criterion: two published figures move
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.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
|
|
@@ -160,8 +160,8 @@ ask verify /path/to/repo --init
|
|
|
160
160
|
# writes nothing — the form an audit of somebody else's repository can run.
|
|
161
161
|
ask verify /path/to/repo --init --dry-run
|
|
162
162
|
|
|
163
|
-
# What each defect actually costs once reach, access
|
|
164
|
-
#
|
|
163
|
+
# What each defect actually costs once reach, access, write effect and the shape of
|
|
164
|
+
# the input path are in it — ordered, every factor traceable to the command that owns it.
|
|
165
165
|
ask risk /path/to/repo
|
|
166
166
|
```
|
|
167
167
|
|
|
@@ -254,12 +254,16 @@ guesses is a confident security falsehood — the worst failure mode this tool h
|
|
|
254
254
|
### 5c · Composed Risk *(experimental)*
|
|
255
255
|
Every command above answers one axis, and a reader composes them by hand. `ask risk` does the
|
|
256
256
|
join over the endpoint and symbol ids these commands already share with each other:
|
|
257
|
-
`severity_effective = defect_severity × reachability × auth_verdict × write_effect`. The
|
|
258
|
-
product of the published factors **is** the published score — decomposable to the
|
|
257
|
+
`severity_effective = defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`. The
|
|
258
|
+
product of the published factors **is** the published score — decomposable to the six
|
|
259
259
|
figures and the authority behind each — and an axis this build cannot measure is `unknown`,
|
|
260
260
|
weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
|
|
261
261
|
field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
|
|
262
262
|
**high (8.06)** once *reachable unauthenticated* and *writes to the database* are in it.
|
|
263
|
+
The last two factors describe the input path — a query assembled by concatenation, a route
|
|
264
|
+
accepting a body with no declared constraint. They are **adjacencies, not dataflow**: no
|
|
265
|
+
value is followed from a request to a sink, which is `NC-001` and is published in the
|
|
266
|
+
payload's own `non_coverage` block.
|
|
263
267
|
`ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
|
|
264
268
|
→ [reference](docs/USER_GUIDE.md)
|
|
265
269
|
|
|
@@ -285,7 +289,7 @@ experimental: both are true, and they are two different facts.
|
|
|
285
289
|
|---|---|---|
|
|
286
290
|
| **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
|
|
287
291
|
| **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
|
|
288
|
-
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `posture` · `archetype` |
|
|
292
|
+
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
|
|
289
293
|
| **parked** | kept working, no longer developed | `retrieve` |
|
|
290
294
|
|
|
291
295
|
The same table is printed by `ask --help`, and both are generated from one authority
|
|
@@ -302,7 +306,10 @@ from it.
|
|
|
302
306
|
| Command | Tier | Answers | Note |
|
|
303
307
|
|---|---|---|---|
|
|
304
308
|
| `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
|
|
305
|
-
| `risk` | experimental | what each defect actually costs, once reach, access
|
|
309
|
+
| `risk` | experimental | what each defect actually costs, once reach, access, write effect and the shape of the input path are in it | `defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`; every factor names its authority |
|
|
310
|
+
| `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`; the same composition as `risk`, with the scanner as the severity authority |
|
|
311
|
+
| `migrate-recipe` | experimental | the migration report as the OpenRewrite recipe that applies it | only recipes a finding named; the manual remainder published beside them; writes nothing without `--write`, and never a runnable command for an empty recipe list |
|
|
312
|
+
| `data-exposure` | experimental | which routes can carry the data you labelled, and who reaches them | labels declared in `sourcecode.config.json` — never inferred from a name; `signature` and `call_reach` evidence published apart, field-level flow out of scope (NC-008) |
|
|
306
313
|
| `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators) |
|
|
307
314
|
| `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment` |
|
|
308
315
|
| `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan |
|
|
@@ -317,7 +324,7 @@ from it.
|
|
|
317
324
|
| `review-pr` / `fix-bug` / `prepare-context` | supported | diff review, symptom triage, task-shaped context | |
|
|
318
325
|
| `plan` / `compare` / `delta` / `contract-diff` | supported | what to review for a change; candidates by measured cost; outcome of a change; public-contract break | no verdicts, measured cost only |
|
|
319
326
|
| `validation` | supported | request-body validation coverage and gaps | |
|
|
320
|
-
| `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend
|
|
327
|
+
| `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend .` reads the series (a repository path or a baselines directory), `ask baseline diff .` compares the tree against its newest point | trend reporting, not gating. Baselines land in `.ask/baselines` **inside the repository** — the history travels with the code, not with a vendor; an audit that must not write passes `--dir`. `capture --auto` is the unattended form (one baseline per commit, never rewrites one, never fails the build) — automate it: [baseline-ci.yml](docs/baseline-ci.yml) |
|
|
321
328
|
| `retrieve` | parked | typed knowledge queries over the model | |
|
|
322
329
|
| `archetype` | experimental | evidence-based architectural archetype | |
|
|
323
330
|
| `rename-class` / `chunk-file` | supported | word-boundary Java rename; split a large file for an agent | |
|
|
@@ -368,6 +375,18 @@ And one about the endpoint surface itself:
|
|
|
368
375
|
|---|---|---|
|
|
369
376
|
| **HTTP surface that is not a Spring handler mapping — a servlet declared in `web.xml` or registered as a `ServletRegistrationBean`, a container-level mapping, a static console mounted by a library.** | The endpoint population is projected from the Spring route model: one entry per handler mapping. A servlet is reachable over HTTP and is not in that model, so it is absent from `endpoints`, from the access verdicts derived from it, and from every ratio keyed on the total. Merging a second population into that count would move a published figure and every ratio with it, so the population is declared before it is widened. | Read the deployment descriptors for `<servlet-mapping>` entries and the Spring configuration for `ServletRegistrationBean` beans. Field evaluation #9 found a monitoring console mounted this way, behind a credential `ask spring-audit` did report (SEC-007) at a path nothing here listed. |
|
|
370
377
|
|
|
378
|
+
And one about labelled data:
|
|
379
|
+
|
|
380
|
+
| Not covered | Why | What answers it |
|
|
381
|
+
|---|---|---|
|
|
382
|
+
| **Whether a labelled member actually leaves the process on a given route — field-level dataflow through mappers, DTOs, serializers and projections.** | Exposure here is measured at TYPE granularity over the same call reach every other command walks: a route reaches the labelled type, or its signature names it. Whether the mapping in between keeps the labelled member is a dataflow question, and answering it by approximation would put a confident `no` on a route that does leak. So `call_reach` is published as a supremum and says so. | Read the mapping on the routes this answer ranks first — they are the ones worth a human — and label the DTO too if it carries the member, which makes the route `signature` instead of `call_reach`. |
|
|
383
|
+
|
|
384
|
+
And one about who calls a route:
|
|
385
|
+
|
|
386
|
+
| Not covered | Why | What answers it |
|
|
387
|
+
|---|---|---|
|
|
388
|
+
| **Whether a route is called from outside this repository — another service, a mobile app, a partner, a cron job, or a client whose URL is assembled at run time.** | The join reads the TypeScript/JavaScript checked in beside the server and only the call shapes whose verb and path are written at the call site. That is a floor on who calls a route and can never be a ceiling: the repository cannot observe consumers it does not contain. So a route with no call site here is published as a candidate for deletion, never as dead API. | Access logs or an API gateway answer who really calls a route. The opposite direction is decisive without them: a client call matching no route is a request this repository's own front end makes and its server does not serve. |
|
|
389
|
+
|
|
371
390
|
**Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
|
|
372
391
|
must change, what each change reaches, and what a gate should block — and it removes none of
|
|
373
392
|
it. Field evaluation scored it 7/10 as a report generator and 5.5/10 as a development tool,
|
|
@@ -122,8 +122,8 @@ ask verify /path/to/repo --init
|
|
|
122
122
|
# writes nothing — the form an audit of somebody else's repository can run.
|
|
123
123
|
ask verify /path/to/repo --init --dry-run
|
|
124
124
|
|
|
125
|
-
# What each defect actually costs once reach, access
|
|
126
|
-
#
|
|
125
|
+
# What each defect actually costs once reach, access, write effect and the shape of
|
|
126
|
+
# the input path are in it — ordered, every factor traceable to the command that owns it.
|
|
127
127
|
ask risk /path/to/repo
|
|
128
128
|
```
|
|
129
129
|
|
|
@@ -216,12 +216,16 @@ guesses is a confident security falsehood — the worst failure mode this tool h
|
|
|
216
216
|
### 5c · Composed Risk *(experimental)*
|
|
217
217
|
Every command above answers one axis, and a reader composes them by hand. `ask risk` does the
|
|
218
218
|
join over the endpoint and symbol ids these commands already share with each other:
|
|
219
|
-
`severity_effective = defect_severity × reachability × auth_verdict × write_effect`. The
|
|
220
|
-
product of the published factors **is** the published score — decomposable to the
|
|
219
|
+
`severity_effective = defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`. The
|
|
220
|
+
product of the published factors **is** the published score — decomposable to the six
|
|
221
221
|
figures and the authority behind each — and an axis this build cannot measure is `unknown`,
|
|
222
222
|
weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
|
|
223
223
|
field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
|
|
224
224
|
**high (8.06)** once *reachable unauthenticated* and *writes to the database* are in it.
|
|
225
|
+
The last two factors describe the input path — a query assembled by concatenation, a route
|
|
226
|
+
accepting a body with no declared constraint. They are **adjacencies, not dataflow**: no
|
|
227
|
+
value is followed from a request to a sink, which is `NC-001` and is published in the
|
|
228
|
+
payload's own `non_coverage` block.
|
|
225
229
|
`ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
|
|
226
230
|
→ [reference](docs/USER_GUIDE.md)
|
|
227
231
|
|
|
@@ -247,7 +251,7 @@ experimental: both are true, and they are two different facts.
|
|
|
247
251
|
|---|---|---|
|
|
248
252
|
| **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
|
|
249
253
|
| **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
|
|
250
|
-
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `posture` · `archetype` |
|
|
254
|
+
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
|
|
251
255
|
| **parked** | kept working, no longer developed | `retrieve` |
|
|
252
256
|
|
|
253
257
|
The same table is printed by `ask --help`, and both are generated from one authority
|
|
@@ -264,7 +268,10 @@ from it.
|
|
|
264
268
|
| Command | Tier | Answers | Note |
|
|
265
269
|
|---|---|---|---|
|
|
266
270
|
| `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
|
|
267
|
-
| `risk` | experimental | what each defect actually costs, once reach, access
|
|
271
|
+
| `risk` | experimental | what each defect actually costs, once reach, access, write effect and the shape of the input path are in it | `defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`; every factor names its authority |
|
|
272
|
+
| `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`; the same composition as `risk`, with the scanner as the severity authority |
|
|
273
|
+
| `migrate-recipe` | experimental | the migration report as the OpenRewrite recipe that applies it | only recipes a finding named; the manual remainder published beside them; writes nothing without `--write`, and never a runnable command for an empty recipe list |
|
|
274
|
+
| `data-exposure` | experimental | which routes can carry the data you labelled, and who reaches them | labels declared in `sourcecode.config.json` — never inferred from a name; `signature` and `call_reach` evidence published apart, field-level flow out of scope (NC-008) |
|
|
268
275
|
| `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators) |
|
|
269
276
|
| `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment` |
|
|
270
277
|
| `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan |
|
|
@@ -279,7 +286,7 @@ from it.
|
|
|
279
286
|
| `review-pr` / `fix-bug` / `prepare-context` | supported | diff review, symptom triage, task-shaped context | |
|
|
280
287
|
| `plan` / `compare` / `delta` / `contract-diff` | supported | what to review for a change; candidates by measured cost; outcome of a change; public-contract break | no verdicts, measured cost only |
|
|
281
288
|
| `validation` | supported | request-body validation coverage and gaps | |
|
|
282
|
-
| `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend
|
|
289
|
+
| `baseline capture\|diff` · `trend` | supported | versioned architectural metrics over time; `ask trend .` reads the series (a repository path or a baselines directory), `ask baseline diff .` compares the tree against its newest point | trend reporting, not gating. Baselines land in `.ask/baselines` **inside the repository** — the history travels with the code, not with a vendor; an audit that must not write passes `--dir`. `capture --auto` is the unattended form (one baseline per commit, never rewrites one, never fails the build) — automate it: [baseline-ci.yml](docs/baseline-ci.yml) |
|
|
283
290
|
| `retrieve` | parked | typed knowledge queries over the model | |
|
|
284
291
|
| `archetype` | experimental | evidence-based architectural archetype | |
|
|
285
292
|
| `rename-class` / `chunk-file` | supported | word-boundary Java rename; split a large file for an agent | |
|
|
@@ -330,6 +337,18 @@ And one about the endpoint surface itself:
|
|
|
330
337
|
|---|---|---|
|
|
331
338
|
| **HTTP surface that is not a Spring handler mapping — a servlet declared in `web.xml` or registered as a `ServletRegistrationBean`, a container-level mapping, a static console mounted by a library.** | The endpoint population is projected from the Spring route model: one entry per handler mapping. A servlet is reachable over HTTP and is not in that model, so it is absent from `endpoints`, from the access verdicts derived from it, and from every ratio keyed on the total. Merging a second population into that count would move a published figure and every ratio with it, so the population is declared before it is widened. | Read the deployment descriptors for `<servlet-mapping>` entries and the Spring configuration for `ServletRegistrationBean` beans. Field evaluation #9 found a monitoring console mounted this way, behind a credential `ask spring-audit` did report (SEC-007) at a path nothing here listed. |
|
|
332
339
|
|
|
340
|
+
And one about labelled data:
|
|
341
|
+
|
|
342
|
+
| Not covered | Why | What answers it |
|
|
343
|
+
|---|---|---|
|
|
344
|
+
| **Whether a labelled member actually leaves the process on a given route — field-level dataflow through mappers, DTOs, serializers and projections.** | Exposure here is measured at TYPE granularity over the same call reach every other command walks: a route reaches the labelled type, or its signature names it. Whether the mapping in between keeps the labelled member is a dataflow question, and answering it by approximation would put a confident `no` on a route that does leak. So `call_reach` is published as a supremum and says so. | Read the mapping on the routes this answer ranks first — they are the ones worth a human — and label the DTO too if it carries the member, which makes the route `signature` instead of `call_reach`. |
|
|
345
|
+
|
|
346
|
+
And one about who calls a route:
|
|
347
|
+
|
|
348
|
+
| Not covered | Why | What answers it |
|
|
349
|
+
|---|---|---|
|
|
350
|
+
| **Whether a route is called from outside this repository — another service, a mobile app, a partner, a cron job, or a client whose URL is assembled at run time.** | The join reads the TypeScript/JavaScript checked in beside the server and only the call shapes whose verb and path are written at the call site. That is a floor on who calls a route and can never be a ceiling: the repository cannot observe consumers it does not contain. So a route with no call site here is published as a candidate for deletion, never as dead API. | Access logs or an API gateway answer who really calls a route. The opposite direction is decisive without them: a client call matching no route is a request this repository's own front end makes and its server does not serve. |
|
|
351
|
+
|
|
333
352
|
**Positioning.** Until an executor ships, this is the **diagnosis layer**: it measures what
|
|
334
353
|
must change, what each change reaches, and what a gate should block — and it removes none of
|
|
335
354
|
it. Field evaluation scored it 7/10 as a report generator and 5.5/10 as a development tool,
|
|
@@ -312,6 +312,25 @@ def load_baseline(path: Path) -> dict:
|
|
|
312
312
|
return data
|
|
313
313
|
|
|
314
314
|
|
|
315
|
+
def latest_baseline_path(directory: Path) -> "Path | None":
|
|
316
|
+
"""The most recently captured baseline in `directory`, or None if there is none.
|
|
317
|
+
|
|
318
|
+
Ordered exactly as `load_baselines_dir` orders its series (capture time, commit
|
|
319
|
+
as the tie-break), so "the last point in the trend" and "the base a diff uses by
|
|
320
|
+
default" can never disagree about which artifact that is.
|
|
321
|
+
"""
|
|
322
|
+
dated: list[tuple[str, str, Path]] = []
|
|
323
|
+
for p in sorted(Path(directory).glob("*.json")):
|
|
324
|
+
try:
|
|
325
|
+
b = load_baseline(p)
|
|
326
|
+
except (OSError, ValueError, json.JSONDecodeError):
|
|
327
|
+
continue
|
|
328
|
+
dated.append((str(b.get("captured_at", "")), str(b.get("commit", "")), p))
|
|
329
|
+
if not dated:
|
|
330
|
+
return None
|
|
331
|
+
return max(dated, key=lambda t: (t[0], t[1]))[2]
|
|
332
|
+
|
|
333
|
+
|
|
315
334
|
def load_baselines_dir(directory: Path) -> list[dict]:
|
|
316
335
|
"""Load every architectural baseline in `directory`, sorted by capture time."""
|
|
317
336
|
out: list[dict] = []
|