sourcecode 4.18.0__tar.gz → 5.0.1__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.18.0 → sourcecode-5.0.1}/.github/workflows/perf-gate.yml +6 -1
- {sourcecode-4.18.0 → sourcecode-5.0.1}/CHANGELOG.md +121 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/PKG-INFO +5 -5
- {sourcecode-4.18.0 → sourcecode-5.0.1}/README.md +4 -4
- {sourcecode-4.18.0 → sourcecode-5.0.1}/pyproject.toml +1 -1
- {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/perf_gate.py +19 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/__init__.py +1 -1
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cache_model.py +329 -43
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cli.py +20 -4
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detach.py +7 -3
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/execution_plan.py +76 -21
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/perf.py +4 -2
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/phased_run.py +10 -8
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/posture.py +13 -26
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/release_info.py +1 -1
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/repository_ir.py +21 -31
- sourcecode-5.0.1/src/sourcecode/security_chain.py +148 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/security_config_scan.py +54 -4
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/source_text.py +18 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/.gitignore +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/.ruff.toml +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/CLAUDE.md +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/CONTRIBUTING.md +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/LICENSE +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/SECURITY.md +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/raw +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/scripts/perf_harness.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/archetype.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/audit_report.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/baseline_autocapture.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cache.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/classifier.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/client_calls.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/compare.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/container_wiring.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/data_exposure.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/data_labels.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/declarations.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/degradation.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/envelope.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/environment_resolution.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/explain.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/license.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/dependency_import.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/non_coverage.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/openrewrite_recipe.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/output_encoding.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/parallel.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/partial_contract.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/progress.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/provenance.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/readonly.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/redactor.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/remedies.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/ris.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/risk.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/rule_catalog.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/rule_pass.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/runs.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/sarif.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/scanner.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/schema.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/security_config.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/serializer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/servlet_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/text_input.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/version_check.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/src/sourcecode/workspace.py +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/README.md +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-4.18.0 → sourcecode-5.0.1}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -59,14 +59,18 @@ jobs:
|
|
|
59
59
|
python3 scripts/perf_gate.py --print-config | tee gate-config.json
|
|
60
60
|
echo "repo_url=$(python3 -c "import json;print(json.load(open('gate-config.json'))['repository_url'])")" >> "$GITHUB_OUTPUT"
|
|
61
61
|
echo "repo=$(python3 -c "import json;print(json.load(open('gate-config.json'))['repository'])")" >> "$GITHUB_OUTPUT"
|
|
62
|
+
echo "fleet_subdir=$(python3 -c "import json;print(json.load(open('gate-config.json'))['fleet_subdir'])")" >> "$GITHUB_OUTPUT"
|
|
62
63
|
echo "mode=$(python3 -c "import json;print(json.load(open('gate-config.json'))['mode'])")" >> "$GITHUB_OUTPUT"
|
|
63
64
|
echo "runs=$(python3 -c "import json;print(json.load(open('gate-config.json'))['min_runs'])")" >> "$GITHUB_OUTPUT"
|
|
64
65
|
echo "commands=$(python3 -c "import json;print(' '.join(repr(c) for c in json.load(open('gate-config.json'))['commands']))")" >> "$GITHUB_OUTPUT"
|
|
65
66
|
|
|
66
67
|
- name: Clone the gate repository
|
|
68
|
+
# Into the directory the harness resolves the gate repository to, which
|
|
69
|
+
# `--print-config` publishes. Naming it here instead cost three nightlies
|
|
70
|
+
# that measured nothing.
|
|
67
71
|
run: |
|
|
68
72
|
mkdir -p fleet
|
|
69
|
-
git clone --depth 1 "${{ steps.cfg.outputs.repo_url }}" "fleet/${{ steps.cfg.outputs.
|
|
73
|
+
git clone --depth 1 "${{ steps.cfg.outputs.repo_url }}" "fleet/${{ steps.cfg.outputs.fleet_subdir }}"
|
|
70
74
|
|
|
71
75
|
- name: Measure
|
|
72
76
|
env:
|
|
@@ -84,6 +88,7 @@ jobs:
|
|
|
84
88
|
run: |
|
|
85
89
|
python3 scripts/perf_gate.py \
|
|
86
90
|
--baseline "$BASELINE_DIR" \
|
|
91
|
+
--require-baseline \
|
|
87
92
|
--current perf-run \
|
|
88
93
|
--report perf-run/gate.json \
|
|
89
94
|
--table perf-run/RELEASE-TABLE.md
|
|
@@ -2,6 +2,127 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.0.1] — 2026-08-11
|
|
6
|
+
|
|
7
|
+
**A patch on the release that made the product's own cost figures honest, for the
|
|
8
|
+
four cells that refresh did not reach.** No analysis changes: `onboard` payloads
|
|
9
|
+
on spring-petclinic and jobrunr are byte-identical against 5.0.0. What moves is
|
|
10
|
+
the operational advice on two commands — `repo-ir` and `baseline capture` are
|
|
11
|
+
foreground work at field scale, where 5.0.0 still sent them to a nightly job on a
|
|
12
|
+
4.10.4 outcome.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Four cost cells the 5.0.0 refresh did not reach, and two of them said the
|
|
17
|
+
field could not run a command it has since run twice (C3-100).** C3-97 gave
|
|
18
|
+
every field figure the build it was taken on and re-measured what evaluation
|
|
19
|
+
#22 had run; what #22 had not run kept its 4.10.4 cell. `ask` (root) published
|
|
20
|
+
115 s, `baseline` 11 s, and — worse, because the claim is categorical rather
|
|
21
|
+
than numeric — `repo-ir` and `verify-edit` published `field_blocked`, which the
|
|
22
|
+
model renders as *"did not finish in an interactive session"*. Evaluation #23
|
|
23
|
+
ran all four from a purged cache on the same repository: root **72,3 s**,
|
|
24
|
+
`repo-ir` **9,8 s**, `baseline capture` **2,2 s**, `verify-edit` **76,6 s**.
|
|
25
|
+
`repo-ir` and `baseline` are foreground work at field scale where the product
|
|
26
|
+
was sending them to a nightly job.
|
|
27
|
+
- **An outcome is a measurement, so it expires like one.** `field_blocked` was the
|
|
28
|
+
strongest claim in the table and the only one that could be written without a
|
|
29
|
+
build behind it. It is dated now wherever it is published (*"did not finish in
|
|
30
|
+
an interactive session on 4.10.4 … and nothing has re-measured it since"*), and
|
|
31
|
+
the battery rejects an undated one.
|
|
32
|
+
- **A figure now states the cache state it was taken in.** The root analysis is
|
|
33
|
+
72,3 s from a purged cache and 0,3 s from a warm one; publishing one number
|
|
34
|
+
without saying which invites a reader to compare two different facts. Every
|
|
35
|
+
field figure carries `warm`/`cold`/`mixed`, in the `here:` line, the `cache
|
|
36
|
+
model` rows and the JSON.
|
|
37
|
+
- **The headline anchor is read off the table instead of copied beside it.**
|
|
38
|
+
`FIELD_ANCHOR`, `FIELD_ANCHOR_SECONDS` and `FIELD_ANCHOR_MEASURED_VERSION` are
|
|
39
|
+
derived from the `spring-audit` row — the missed copy is what C3-100 was — and
|
|
40
|
+
`field_currency()` now also names every row measured before the newest figure in
|
|
41
|
+
the same table (`rows_behind_the_newest_field_measurement`), which is the
|
|
42
|
+
staleness that hid for three releases: not *"older than the build you are
|
|
43
|
+
running"* but *"older than the refresh that reached the row next to it"*.
|
|
44
|
+
- **The root row was invisible to the surface its measurement exists for.**
|
|
45
|
+
`cost_row("ask (root)")` resolved to no row, so `cache model`'s `here:` line for
|
|
46
|
+
the root analysis was published from the command's *class*, with no figure in
|
|
47
|
+
it, on every repository. Found while checking the refresh on a real one.
|
|
48
|
+
|
|
49
|
+
## [5.0.0] — 2026-08-11
|
|
50
|
+
|
|
51
|
+
**The engine got 280× faster in 4.18.0 and every number the product quoted about
|
|
52
|
+
its own cost still described the build before it.** This release changes no
|
|
53
|
+
analysis: it makes what ASK says about itself true again, and makes the way it
|
|
54
|
+
went stale impossible to repeat silently. Field evaluation #22 — eighth
|
|
55
|
+
measurement of the same 3 342-file repository at the same commit — scored the
|
|
56
|
+
build **9,2/10** and named this as the one place the product states something
|
|
57
|
+
false with confidence.
|
|
58
|
+
|
|
59
|
+
**Why a major.** No API breaks. What changes is an answer thousands of readers
|
|
60
|
+
act on: commands that were published as *"not a foreground run here — `--output
|
|
61
|
+
<file> --detach`, or a nightly job"* are now published as foreground work, and
|
|
62
|
+
the operational advice in `--help`, `cache model`, the budget warning and the
|
|
63
|
+
remedies moves with them. A recommendation that reverses is a contract change
|
|
64
|
+
whatever the surface, so it is versioned like one.
|
|
65
|
+
|
|
66
|
+
**Fixed in this release:**
|
|
67
|
+
|
|
68
|
+
- **The cost anchors described a build that no longer exists (C3-97).** `spring-audit`'s
|
|
69
|
+
field anchor was **2 351 s**, measured on 4.11.0; the same command, on the same
|
|
70
|
+
repository at the same commit, takes **8,4 s** on 4.18.0 — the two
|
|
71
|
+
catastrophic-backtracking patterns behind that figure were deleted in C3-95 and
|
|
72
|
+
C3-96. Four surfaces read the anchors and none could tell they were old:
|
|
73
|
+
`execution_plan`'s `here:` verdict, the budget warning, the `cache model`
|
|
74
|
+
header, and the front page. The product therefore recommended a nightly job for
|
|
75
|
+
an eight-second command, and an operator sizing `ASK_MAX_ANALYSIS_SECONDS` from
|
|
76
|
+
it would set the budget ~280× too high. Anchors refreshed from evaluation #22
|
|
77
|
+
(`spring-audit` 2 351 → 8,4 s · `risk` 3 232 → 73,3 s · `posture` 38 → 8,0 s ·
|
|
78
|
+
`migrate-check` 26,7 → 10,2 s · `endpoints` 5,0 → 3,8 s), first anchors recorded
|
|
79
|
+
for `impact-chain` 5,5 s, `validation` 17,4 s, `pr-impact` 12,5 s, `impact`
|
|
80
|
+
7,7 s and `explain` 4,4 s — and `modernize`, carried as *did not finish* since
|
|
81
|
+
4.10.4, is a measurement again at **9,1 s**.
|
|
82
|
+
- **And they cannot go stale silently again.** Every field figure now carries
|
|
83
|
+
`field_measured_version`, the build it was taken on. A figure from an earlier
|
|
84
|
+
release is still published — a measurement at that size beats silence — but it
|
|
85
|
+
arrives labelled *"measured on 4.10.4, not re-measured on 5.0.0"* wherever it is
|
|
86
|
+
read, and `ask cache model --json` publishes `field_currency` naming every row
|
|
87
|
+
in that state. This is the mechanism `REFERENCE_MEASURED_VERSION` already gave
|
|
88
|
+
the reference figures; the field anchors, which are the ones that decide how a
|
|
89
|
+
command is offered, had none.
|
|
90
|
+
- **The front page paraphrased the table instead of deriving it (CL-21).** *"Repo-wide/deep
|
|
91
|
+
compositions can take minutes … use deep jobs nightly"* was written in `cli`
|
|
92
|
+
beside the model it described, so it aged separately from the anchors it
|
|
93
|
+
paraphrased. It is generated from `cache_model.cost_sentence()` now: refreshing
|
|
94
|
+
a measurement refreshes the prose, and a battery asserts the front page contains
|
|
95
|
+
exactly what the model generates.
|
|
96
|
+
- **The performance gate had no baseline to compare against (C3-98).** F-AP shipped
|
|
97
|
+
the detector in 4.13.0 and it has run nightly since, self-testing that a
|
|
98
|
+
synthetic 3× regression would fail — against `docs/perf/baselines/gate-latest`,
|
|
99
|
+
a directory that was never created. Every run ended in the gate refusing to
|
|
100
|
+
report green (*"a gate that cannot be red is not evidence"*), which is why eight
|
|
101
|
+
consecutive field evaluations found no evidence that any benchmark gates a
|
|
102
|
+
release. The baseline is committed: six cells on BroadleafCommerce, warm, five
|
|
103
|
+
runs each, captured on the runner at 4.18.0, with provenance and a refresh
|
|
104
|
+
procedure beside them. First real comparison passed with `regressions: []`, and
|
|
105
|
+
the observed runner noise floor — ±5 %, widest on the shortest cell — is
|
|
106
|
+
published next to the 20 % threshold it has to be read against.
|
|
107
|
+
- **The gate's exclusion list quoted a deleted cost (C3-99).** `risk` was excluded
|
|
108
|
+
because it took *54 minutes* on the gate repository. Since C3-96 it takes
|
|
109
|
+
**68 s** there. The reason now says so, and names the only thing still keeping
|
|
110
|
+
it out: no baseline cell exists for it yet.
|
|
111
|
+
- **Stale cost claims elsewhere in the documentation.** README (the proof table's
|
|
112
|
+
caveat and the problem statement), `USER_GUIDE` (the "Start here" framing and
|
|
113
|
+
the spinner paragraph), `docs/CACHE.md` (regenerated), `docs/perf/REGRESSION-GATE.md`
|
|
114
|
+
§3, and the module docstrings of `execution_plan`, `phased_run` and `detach`,
|
|
115
|
+
where a 408 s / 2 351 s cost was narrated in the present tense.
|
|
116
|
+
|
|
117
|
+
**Deliberately not in this release:** the `chunk-file -c` remap. The guide says the
|
|
118
|
+
short form moves from `--chunk` to `--copy` "at the next major"; this major
|
|
119
|
+
changes no invocation, and breaking a working command line as a side effect of a
|
|
120
|
+
documentation-truth release would be the wrong trade. It waits for a major that
|
|
121
|
+
changes the command surface on purpose.
|
|
122
|
+
|
|
123
|
+
**Not changed:** any analysis, any payload, any schema. Every rule, every count and
|
|
124
|
+
every verdict this build produces is byte-identical to 4.18.0's.
|
|
125
|
+
|
|
5
126
|
## [4.18.0] — 2026-08-10
|
|
6
127
|
|
|
7
128
|
**A field battery over the test repositories, run against 4.17.0 and aimed first
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.1
|
|
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`**
|
|
@@ -54,7 +54,7 @@ Description-Content-Type: text/markdown
|
|
|
54
54
|
|
|
55
55
|
## The problem
|
|
56
56
|
|
|
57
|
-
Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On
|
|
57
|
+
Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On a large Java/Spring monolith that is thousands of files of parsing per turn, repeated for every question asked about the same unchanged tree. Multiply it by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
|
|
58
58
|
|
|
59
59
|
ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, later invocations reuse pre-built context whenever their command can consume the warmed layers. The repo doesn't change? The cache doesn't expire.
|
|
60
60
|
|
|
@@ -69,7 +69,7 @@ ASK Engine solves this with a persistent structural cache keyed on file content
|
|
|
69
69
|
| Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
|
|
70
70
|
| BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
|
|
71
71
|
|
|
72
|
-
These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most
|
|
72
|
+
These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most, and inventory commands scale with file count. What a repository-wide analysis costs tracks the build more than the file count: on one 3,342-file monolith, at one commit, `spring-audit` measured 2,351s on 4.11.0 and **8.4s on 4.18.0** with a byte-identical payload — so ASK publishes measured anchors and the release each was taken on, and never projects a duration for your repository. `ask cache model` prints both anchors per command, and `risk` — the one composition still measured in the tens of seconds at that size — is the one to give a budget or a detached run.
|
|
73
73
|
|
|
74
74
|
With the right command class, ASK Engine becomes **constant infrastructure** inside agent loops — call the fast/context surfaces before edits and reserve deep compositions for the points where their evidence is worth the runtime.
|
|
75
75
|
|
|
@@ -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
|
|
129
|
+
ask version # ask 5.0.1 — 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`**
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
## The problem
|
|
18
18
|
|
|
19
|
-
Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On
|
|
19
|
+
Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On a large Java/Spring monolith that is thousands of files of parsing per turn, repeated for every question asked about the same unchanged tree. Multiply it by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
|
|
20
20
|
|
|
21
21
|
ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, later invocations reuse pre-built context whenever their command can consume the warmed layers. The repo doesn't change? The cache doesn't expire.
|
|
22
22
|
|
|
@@ -31,7 +31,7 @@ ASK Engine solves this with a persistent structural cache keyed on file content
|
|
|
31
31
|
| Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
|
|
32
32
|
| BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
|
|
33
33
|
|
|
34
|
-
These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most
|
|
34
|
+
These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most, and inventory commands scale with file count. What a repository-wide analysis costs tracks the build more than the file count: on one 3,342-file monolith, at one commit, `spring-audit` measured 2,351s on 4.11.0 and **8.4s on 4.18.0** with a byte-identical payload — so ASK publishes measured anchors and the release each was taken on, and never projects a duration for your repository. `ask cache model` prints both anchors per command, and `risk` — the one composition still measured in the tens of seconds at that size — is the one to give a budget or a detached run.
|
|
35
35
|
|
|
36
36
|
With the right command class, ASK Engine becomes **constant infrastructure** inside agent loops — call the fast/context surfaces before edits and reserve deep compositions for the points where their evidence is worth the runtime.
|
|
37
37
|
|
|
@@ -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
|
|
91
|
+
ask version # ask 5.0.1 — and, on a build that has aged,
|
|
92
92
|
# how many releases have probably shipped since
|
|
93
93
|
```
|
|
94
94
|
|
|
@@ -33,7 +33,13 @@ import sys
|
|
|
33
33
|
from pathlib import Path
|
|
34
34
|
|
|
35
35
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
|
|
36
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
36
37
|
from sourcecode import perf # noqa: E402
|
|
38
|
+
# The directory a repository is checked out under is the harness's fact, not a
|
|
39
|
+
# second one this script or a workflow may restate: CI cloned the gate repo into
|
|
40
|
+
# `fleet/broadleaf` while the harness looked for `fleet/BroadleafCommerce`, so
|
|
41
|
+
# every nightly measured zero cells. `--print-config` now publishes the one name.
|
|
42
|
+
from perf_harness import FLEET # noqa: E402
|
|
37
43
|
|
|
38
44
|
|
|
39
45
|
def load_cells(directory: Path) -> dict[str, dict]:
|
|
@@ -98,6 +104,8 @@ def _print_config() -> int:
|
|
|
98
104
|
"threshold": perf.RELEASE_GATE_THRESHOLD,
|
|
99
105
|
"repository": perf.RELEASE_GATE_REPO,
|
|
100
106
|
"repository_url": perf.RELEASE_GATE_REPO_URL,
|
|
107
|
+
# Where the harness will look for that checkout, under the fleet root.
|
|
108
|
+
"fleet_subdir": FLEET.get(perf.RELEASE_GATE_REPO, perf.RELEASE_GATE_REPO),
|
|
101
109
|
"repository_scale": perf.RELEASE_GATE_REPO_SCALE,
|
|
102
110
|
"mode": perf.RELEASE_GATE_MODE,
|
|
103
111
|
"min_runs": perf.RELEASE_GATE_MIN_RUNS,
|
|
@@ -122,6 +130,11 @@ def main() -> int:
|
|
|
122
130
|
ap.add_argument("--allow-incomparable", action="store_true",
|
|
123
131
|
help="Do not fail cells whose env/host differ. Off by default: "
|
|
124
132
|
"an incomparable cell is an unmeasured one.")
|
|
133
|
+
ap.add_argument("--require-baseline", action="store_true",
|
|
134
|
+
help="Fail when the baseline holds no cells. A run with nothing "
|
|
135
|
+
"to compare against records every cell as `new` and passes; "
|
|
136
|
+
"that is a recording, not a gate, and CI must not read it "
|
|
137
|
+
"as one.")
|
|
125
138
|
ap.add_argument("--report", type=Path, help="Write the perf-gate-v1 report here.")
|
|
126
139
|
ap.add_argument("--table", type=Path, help="Write the release-notes markdown table here.")
|
|
127
140
|
ap.add_argument("--self-test", action="store_true",
|
|
@@ -143,6 +156,12 @@ def main() -> int:
|
|
|
143
156
|
f"which the gate reads as a failure, not a pass.", file=sys.stderr)
|
|
144
157
|
return 1
|
|
145
158
|
baseline = load_cells(args.baseline) if args.baseline else {}
|
|
159
|
+
if args.require_baseline and not baseline:
|
|
160
|
+
where = args.baseline if args.baseline else "<no --baseline given>"
|
|
161
|
+
print(f"no baseline cells in {where} — every cell would be recorded as "
|
|
162
|
+
f"`new` and the run would pass without comparing anything. A gate "
|
|
163
|
+
f"that cannot be red is not evidence.", file=sys.stderr)
|
|
164
|
+
return 1
|
|
146
165
|
|
|
147
166
|
report = perf.gate_report(
|
|
148
167
|
baseline, current,
|