feat(0.2): report pr --fail-on + report impact --explain-selection (Tracks 3.1/3.2)#143
Open
pmclSF wants to merge 1 commit intofeat/0.2.1-gate-flagsfrom
Open
feat(0.2): report pr --fail-on + report impact --explain-selection (Tracks 3.1/3.2)#143pmclSF wants to merge 1 commit intofeat/0.2.1-gate-flagsfrom
pmclSF wants to merge 1 commit intofeat/0.2.1-gate-flagsfrom
Conversation
…racks 3.1/3.2) Two of the five "load-bearing centerpiece" Track 3 deliverables that turn the unified pitch into something the binary actually delivers. Track 3.1 — `terrain report pr --fail-on <severity>` Defends the pitch claim "Gate changes based on that system as a whole." Pre-fix, --fail-on existed only on `analyze`; the gating flow (`analyze && report pr`) silently lost the gate at the second step. Implementation reuses the same severityGateBlocked helper that PR #134 introduced for analyze. Added prSeverityBreakdown(severities []string) that converts a PR's NewFindings + AI BlockingSignals into the same SignalBreakdown shape `analyze.SignalSummary` uses, so the gate decision logic is shared, not duplicated. Wired through both the legacy `terrain pr` command (deprecated alias of `terrain report pr`) and the canonical `terrain report pr` namespace dispatcher. Same render-then-gate pattern as analyze: every output format (json, markdown, comment, annotation, default text) renders before the gate decision returns through the error channel. So `--json --fail-on=high` produces a valid JSON document on stdout AND exits with code 6 if the gate fired — the property the launch- readiness review's "JSON stdout purity" gate test asks for. Tests: - TestPRSeverityBreakdown: empty / mixed bag / case-insensitive / unknown-severities-dropped-silently table - cli_smoke_test.go updated for the new runPR signature Track 3.2 — `terrain report impact --explain-selection` Defends the pitch claim "See which tests matter for a PR — and why." Pre-fix, `report impact` showed selected tests but not the reason chains; the "and why" half of the pitch wasn't deliverable. Implementation reuses the existing internal/explain.ExplainSelection + reporting.RenderSelectionExplanation (already shipping for `terrain explain selection`). When --explain-selection is set, runImpact computes the selection explanation and renders it with verbose=true so per-test evidence (selection reasons, code unit matches, confidence) appears. Wired through both `terrain impact` (legacy) and `terrain report impact` (canonical). --json + --explain-selection emits the SelectionExplanation JSON structure for tooling consumption. Pillar parity impact: Track 3.1 + 3.2 are the centerpiece work that the plan calls "highest-priority track — every pitch claim must be directly verifiable in the CLI output before 0.2.0 ships." This PR closes two of the five Track 3 items; 3.3 (integration-test classification rigor), 3.4 (E2E attribution), and 3.5 (unified PR-comment audit) are separate follow-ups. Verification: go build ./... clean go test ./cmd/terrain/ green (4 new TestPRSeverityBreakdown cases; existing TestCLISmoke_PRCommand updated for new signature) go test ./... full suite green go test ./internal/testdata/ golden + CLI suite green Plan link: /Users/pzachary/.claude/plans/kind-mapping-turing.md (Tracks 3.1 / 3.2). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two of the five Track-3 "load-bearing centerpiece" deliverables. These are what turn pitch claims into binary behavior.
Base branch: `feat/0.2.1-gate-flags` (PR #134, which adds the severity gate primitives this PR reuses). Will rebase onto main after #134 merges.
Track 3.1 — `terrain report pr --fail-on `
Pitch claim defended: "Gate changes based on that system as a whole."
Pre-fix, `--fail-on` existed only on `analyze`. The two-step primary workflow (`analyze && report pr`) silently lost the gate at the second step.
Implementation reuses the same `severityGateBlocked` helper #134 introduced. Added `prSeverityBreakdown(severities []string) analyze.SignalBreakdown` that converts a PR's `NewFindings` + `AI.BlockingSignals` into the same shape `analyze.SignalSummary` uses, so the gate decision logic is shared, not duplicated.
Same render-then-gate pattern as analyze: every output format renders before the gate decision returns through the error channel. `--json --fail-on=high` produces a valid JSON document on stdout AND exits with code 6 if the gate fired — the JSON-stdout-purity property #134 introduced.
Wired through both the legacy `terrain pr` command and the canonical `terrain report pr` namespace dispatcher.
Track 3.2 — `terrain report impact --explain-selection`
Pitch claim defended: "See which tests matter for a PR — and why."
Pre-fix, `report impact` showed selected tests but not the reason chains. The "and why" half of the pitch wasn't deliverable.
Implementation reuses `internal/explain.ExplainSelection` + `reporting.RenderSelectionExplanation` (already shipping for `terrain explain selection`). When the flag is set, runImpact computes the selection explanation and renders it with `verbose=true` so per-test evidence (selection reasons, code unit matches, confidence) appears.
`--json --explain-selection` emits the structured `SelectionExplanation` for tooling consumption.
Wired through both `terrain impact` and `terrain report impact`.
Test plan
Plan link
`/Users/pzachary/.claude/plans/kind-mapping-turing.md` (Tracks 3.1 / 3.2). Three Track 3 items remain — 3.3 (integration-test classification), 3.4 (E2E attribution), 3.5 (unified PR-comment audit) — as separate follow-ups.
🤖 Generated with Claude Code