sourcecode 3.6.0__tar.gz → 3.7.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-3.6.0 → sourcecode-3.7.0}/CHANGELOG.md +139 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/PKG-INFO +1 -1
- {sourcecode-3.6.0 → sourcecode-3.7.0}/pyproject.toml +1 -1
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/change_plan.py +5 -1
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cli.py +214 -79
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/compare.py +5 -3
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/explain.py +11 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/output_budget.py +7 -2
- sourcecode-3.7.0/src/sourcecode/pipe_contract.py +208 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/repository_ir.py +18 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/serializer.py +93 -61
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_findings.py +86 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_impact.py +18 -1
- sourcecode-3.7.0/src/sourcecode/target_admission.py +168 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/verify_edit.py +32 -9
- {sourcecode-3.6.0 → sourcecode-3.7.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/.gitignore +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/.ruff.toml +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/CONTRIBUTING.md +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/LICENSE +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/README.md +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/SECURITY.md +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/raw +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/scripts/perf_harness.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/archetype.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/degradation.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/envelope.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/license.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/perf.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/posture.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/security_config.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/README.md +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-3.6.0 → sourcecode-3.7.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -1,5 +1,144 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.7.0] — 2026-08-01
|
|
4
|
+
|
|
5
|
+
**The exit-code contract and the C3 surface block.** Seven rows closed: the two the field named
|
|
6
|
+
as blocking for CI (exit codes over correct answers), the fourth and fifth appearance of a
|
|
7
|
+
curated list beside real data, and three surfaces that published a promise the payload did not
|
|
8
|
+
keep.
|
|
9
|
+
|
|
10
|
+
Minor and not patch, because a pipeline can see the difference: `plan` exits 1 where it exited 0
|
|
11
|
+
over a target it never resolved (C3-29), `ask <cmd> | head` exits 0 where a correct run used to
|
|
12
|
+
exit non-zero (C3-28), `--output FILE` carries the whole answer where it was silently trimmed
|
|
13
|
+
(C3-17), `--agent` publishes sections it used to omit (C3-10), and a path-shaped target that was
|
|
14
|
+
refused as ambiguous now resolves (C3-35).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A broken output pipe is no longer a failed run** (C3-28, **exit code changes for
|
|
19
|
+
`ask <cmd> | head`**). `ask repo-ir . --force | head -c 100` returned the correct bytes and
|
|
20
|
+
exit 1; under `set -e` that stops a pipeline with no error anywhere to explain it — the field
|
|
21
|
+
named it one of two blockers for CI. One authority now says what a closed stream means
|
|
22
|
+
(`pipe_contract.py`, installed at the entry point): **a broken output stream changes nothing
|
|
23
|
+
except where the remaining bytes go.** The descriptor is redirected to the null device on the
|
|
24
|
+
first broken write and the command finishes and exits on its own terms.
|
|
25
|
+
- **It does not overwrite the command's own verdict.** `ask impact <ambiguous target> | head`
|
|
26
|
+
still exits 1, because a consumer that stopped reading has no opinion about whether the
|
|
27
|
+
analysis resolved its target.
|
|
28
|
+
- Redirecting before the shutdown flush is what keeps Python from printing
|
|
29
|
+
`Exception ignored in: <_io.TextIOWrapper …>` and exiting 120 — the same defect wearing a
|
|
30
|
+
different number.
|
|
31
|
+
- **The wrapper covers `.buffer`, which is the whole fix**: payloads are written as bytes
|
|
32
|
+
through `sys.stdout.buffer` at the single emit seam, so a text-only wrapper sits beside the
|
|
33
|
+
one write this exists for. Measured: with the text wrapper alone, nothing changed.
|
|
34
|
+
- Only visible above a pipe buffer, which is why it looked intermittent: `endpoints` on a
|
|
35
|
+
small repository exits 0 either way, `repo-ir` on the same repository did not.
|
|
36
|
+
|
|
37
|
+
- **An unresolved target has one exit code across every command** (C3-29, **`plan` now exits 1
|
|
38
|
+
where it exited 0**). `plan <unknown> <repo>` ran to completion, emitted a plan-shaped payload
|
|
39
|
+
of zeros with `resolution: "not_found"` and exited **0**, while `impact` on the same input
|
|
40
|
+
exited 1 — so a gate could not tell "nothing to review" from "I never found what you asked
|
|
41
|
+
about". One authority (`target_admission.py`), four commands rebound (`impact`,
|
|
42
|
+
`impact-chain`, `plan`, `explain`), and the two other copies of the same literal set
|
|
43
|
+
(`compare`, `change_plan`) now read it instead of restating it.
|
|
44
|
+
- **Ambiguity is the same fact, and it was not in the field report.** A target matching
|
|
45
|
+
several classes returns `ambiguous_path`, empty results and a message asking for the full
|
|
46
|
+
FQN — the command declined to answer — and `impact` exited **0** on it. Measured on a
|
|
47
|
+
purpose-built two-class fixture, since no battery repository carries the shape.
|
|
48
|
+
- Unresolved is **1, not 2**: 2 is reserved by the `verify` family for a run that could not
|
|
49
|
+
look, and this run looked. Partial and expanded resolutions stay 0 — they are answers about
|
|
50
|
+
the target the caller named.
|
|
51
|
+
- `plan`'s `Note:` on stderr is gone with it: the payload already carries the statement, and
|
|
52
|
+
a successful-looking run should not be narrating on stderr (the `plan` half of C3-34).
|
|
53
|
+
|
|
54
|
+
- **`--help` reaches inside command groups** (C4-7). `ask cache model` — what a warm buys each
|
|
55
|
+
command, per layer, including the commands it buys nothing for — appeared in no help text at
|
|
56
|
+
all: the root catalogue was generated (C4-1/C4-2) but the Cache and Auth blocks under it were
|
|
57
|
+
three lines somebody typed by hand. The blocks are now built from the registered groups, so a
|
|
58
|
+
subcommand is listed the moment it is registered; a group too large to name in full (`retrieve`,
|
|
59
|
+
29 parked intents) publishes its **exact count** and a pointer, never silence. The battery
|
|
60
|
+
fails if a subcommand of a listed group is missing, or if a collapsed group's count drifts.
|
|
61
|
+
|
|
62
|
+
- **A successful run says nothing on stderr — measured over the commands, not over a list**
|
|
63
|
+
(C3-34, the `repo-ir` half). `ask repo-ir . --force` wrote an 82-byte size advisory on a run
|
|
64
|
+
that exited 0 with the IR on stdout, which PowerShell 5.1 raises as a `NativeCommandError`.
|
|
65
|
+
The advisory is terminal-gated now, like every other notice, and so is the `--exclude`
|
|
66
|
+
directory warning and the output-budget trim warning found beside it.
|
|
67
|
+
- **The list was the defect.** `tests/test_stderr_purity_matrix.py` enumerated 13 commands by
|
|
68
|
+
hand for the fourth time in three releases; the rows are now **discovered from the CLI**,
|
|
69
|
+
with every command either driven or carrying a written reason it cannot be. Nine more
|
|
70
|
+
commands are driven as a result, `cache` subcommands included.
|
|
71
|
+
- The `repo-ir` row builds a repository large enough for the advisory to actually fire and
|
|
72
|
+
**asserts it fired**, because a row that never reaches the branch proves nothing.
|
|
73
|
+
|
|
74
|
+
- **`--output FILE` is no longer trimmed to an agent's context window** (C3-17). The payload
|
|
75
|
+
budget exists because a context window is finite — it is a constraint on **stdout**. Written
|
|
76
|
+
to a file it cut the answer anyway, dropped `key_dependencies` entirely, and the note
|
|
77
|
+
explaining the cut advised `--output`, the flag already in use. Two of six call sites had the
|
|
78
|
+
rule and four did not (`prepare-context`, `modernize`, the cached-view rebuild, and `impact`
|
|
79
|
+
in part), so it now lives in one seam (`cli._apply_budget`) and a battery fails if a seventh
|
|
80
|
+
call site decides for itself.
|
|
81
|
+
- **The cache had the same defect one layer down**, found while field-checking the seam:
|
|
82
|
+
`prepare-context` stored the document *after* trimming, so the first stdout run poisoned the
|
|
83
|
+
cache and every later `--output FILE` hit received a stdout-sized answer. The cache stores
|
|
84
|
+
the analysis now and the budget is applied per run — measured on alfresco-community-repo:
|
|
85
|
+
stdout 5 files, cache hit to a file 26.
|
|
86
|
+
- **`--full` says what it does.** It raises the caps (boundaries and DTO mappers in full,
|
|
87
|
+
`file_relevance` to 40); it never removed them — under `--agent --full` the file list stayed
|
|
88
|
+
capped at 40 of 710 while the flag's help promised "remove truncation limits".
|
|
89
|
+
|
|
90
|
+
- **`--agent` cannot publish less than `--compact`** (C3-10). `--compact` documents
|
|
91
|
+
`security_surface` "when custom security annotations detected" and closes with "use `--agent`
|
|
92
|
+
for maximum signal", while `--agent` was assembled from its own hand-written list of sections:
|
|
93
|
+
measured on BroadleafCommerce it omitted `deployment` and `language_version` outright, and
|
|
94
|
+
nothing stopped the security surface going the same way. Both views now read one authority
|
|
95
|
+
(`serializer.JAVA_SPRING_SECTIONS`), and the battery fails on any section `--compact` publishes
|
|
96
|
+
that `--agent` does not.
|
|
97
|
+
|
|
98
|
+
- **A path that names one file resolves to that file** (C3-35). Every resolver reduced a
|
|
99
|
+
path-shaped target to its basename before anything looked at it, so
|
|
100
|
+
`ask impact src/main/java/com/a/Service.java` answered `ambiguous_path` and offered
|
|
101
|
+
`com.a.Service` **and** `com.b.Service` — being more specific made the answer worse. A path is
|
|
102
|
+
matched against the `source_file` each symbol came from, strongest tier first (exact, then
|
|
103
|
+
module-relative, then parent-relative), and nested types collapse to the type the file is about
|
|
104
|
+
(on eureka, `DiscoveryClient.java` declares its outer class and five inner ones). One authority
|
|
105
|
+
in `target_admission`, because three graphs answer target questions — the repo IR, and the CIR
|
|
106
|
+
that `explain` and `impact-chain` read, both of which used to answer `not_found` for a path.
|
|
107
|
+
Parity checked on eureka: by path and by name give byte-identical `stats`.
|
|
108
|
+
|
|
109
|
+
- **`verify-edit` stops paying for a diff it has already proved empty** (C3-32). It computed the
|
|
110
|
+
change set and then built the HEAD CIR *and* the working CIR unconditionally — on a clean tree
|
|
111
|
+
the second is the first by construction. Measured on a clean ofbiz-framework: **5.9 s -> 1.7 s**
|
|
112
|
+
warm. The shortcut is taken only when git actually answered: a failed `git diff` also returns an
|
|
113
|
+
empty list, and reading that as "nothing changed" would trade dead cost for a false green.
|
|
114
|
+
|
|
115
|
+
- **`spring-audit --compact`** (C3-31). The one analysis command with no summary mode: 1.99 MB for
|
|
116
|
+
14 findings in the field, *"a context overflow against an LLM with no filter in between"*. The
|
|
117
|
+
weight is not the findings — on BroadleafCommerce `security_posture.endpoints` is 113 KB of a
|
|
118
|
+
178 KB report, and the counts it supports are published beside it. `--compact` caps that list and
|
|
119
|
+
`findings` to their top 5, ordered by what asks something of the reader (`probably_exposed`
|
|
120
|
+
first; most severe first), and recomputes nothing: **178 KB -> 25 KB with every count
|
|
121
|
+
identical**. A flag changes how much is emitted, never the shape (C2-10) — each list stays a list
|
|
122
|
+
and the totals live in a `*_cap` sibling that exists only when the cap bit.
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
### Documentation
|
|
126
|
+
|
|
127
|
+
- **Field evaluation #6 of 3.5.0 recorded** (`.planning/FIELD-EVAL-6-2026-08-01.md`, defect
|
|
128
|
+
ledger, development roadmap). Full 27-command catalogue, repository left byte-identical,
|
|
129
|
+
scored 8/10. Every reported defect was re-measured on 3.6.0 before it was written down: two
|
|
130
|
+
do not reproduce (one closed here as C3-15, one by the 3.5.0 admission authority) and the
|
|
131
|
+
re-measurement found two the evaluation did not report.
|
|
132
|
+
- **New rows**: C1-18 (profile population differs per command, and the narrower one is what an
|
|
133
|
+
agent reads) · C3-28/C3-29 (**exit codes that lie over correct answers** — a broken pipe
|
|
134
|
+
exits non-zero on a successful run, `plan` exits 0 on a target it did not resolve while
|
|
135
|
+
`impact` exits 1) · C3-30 (`verify --init`) · C3-31…C3-34 · C4-7 (`cache model` in no help
|
|
136
|
+
panel) · P-4 (`baseline` history nobody automated) · CL-7 (non-coverage: no dataflow, no
|
|
137
|
+
secrets outside Java/YAML, filter order not reconstructed) · CL-8 (`posture --diff` answers
|
|
138
|
+
conditionally because the profile is decided outside the repository).
|
|
139
|
+
- **The executive roadmap gains what the product does *not* do**, published beside the
|
|
140
|
+
capabilities, and the evaluation table is current through eval #6.
|
|
141
|
+
|
|
3
142
|
## [3.6.0] — 2026-08-01
|
|
4
143
|
|
|
5
144
|
**The P0 block and the C1/C2 backlog.** Nine rows closed, three closed by measurement alone
|
|
@@ -88,7 +88,11 @@ def build_change_plan(
|
|
|
88
88
|
resolution = blast.get("resolution", "not_found")
|
|
89
89
|
|
|
90
90
|
# Unresolvable target → return a plan-shaped resolution notice (never crash).
|
|
91
|
-
|
|
91
|
+
# The set of resolutions that means "never found it" is one fact, and the CLI
|
|
92
|
+
# reads the same one to decide the exit code (C3-29).
|
|
93
|
+
from sourcecode.target_admission import is_unresolved
|
|
94
|
+
|
|
95
|
+
if is_unresolved(resolution) or not blast.get("matched_fqns"):
|
|
92
96
|
return {
|
|
93
97
|
"schema": CHANGE_PLAN_SCHEMA,
|
|
94
98
|
"target": target,
|