Documentation
¶
Overview ¶
Package review implements "agent diff review": checking a changeset for boundary violations, secret-shaped values, API compatibility breaks, protected-path edits, and missing changelog obligations, per ADR-0032 (Jira MOD-65). It depends on verify for CheckSpec/Run and on provenance for VerificationResult/VerificationCategory, so its output is exactly what `modulex agent handoff` consumes.
Checks re-declares verify.FullGates' boundary/compatibility/changelog targets under review-specific categories (VerificationBoundary etc. instead of VerificationFull), since verify's job is "what must pass before push" and this package's is "what this diff needs reviewed." Those checks inspect the working tree, not the diff; only the secret scan and CheckProtectedPaths are genuinely diff-scoped.
Index ¶
- Variables
- func ChangedFiles(ctx context.Context, dir, baseRef, headRef string) ([]string, error)
- func CheckProtectedPaths(ctx context.Context, dir, baseRef, headRef string, protectedPaths []string) provenance.VerificationResult
- func Review(ctx context.Context, dir, baseRef, headRef string, ...) []provenance.VerificationResult
- func ScanSecrets(ctx context.Context, dir, baseRef, headRef string) provenance.VerificationResult
Constants ¶
This section is empty.
Variables ¶
var Checks = []verify.CheckSpec{ { Name: "check-consumer-boundary", Command: "make check-consumer-boundary", Category: provenance.VerificationBoundary, Reason: "verifies a consumer importing only the core package does not compile in an integration adapter as a build dependency", RequiredTool: "go", }, { Name: "check-module-boundary", Command: "make check-module-boundary", Category: provenance.VerificationBoundary, Reason: "runs the modboundary analyzer against examples/deployment to enforce feature-module boundaries", RequiredTool: "go", }, { Name: "check-api-compat", Command: "make check-api-compat", Category: provenance.VerificationCompatibility, Reason: "reports public API changes since the latest git tag", RequiredTool: "go", }, { Name: "check-changelog", Command: "make check-changelog", Category: provenance.VerificationChangelog, Reason: "verifies CHANGELOG.md is updated when required (working tree vs origin/main)", RequiredTool: "git", }, }
Checks is the fixed list of diff-review checks executed by Review via verify.Run. The secret scan and protected-paths check aren't included here since they need baseRef/headRef, not a shell command; see ScanSecrets and CheckProtectedPaths. Exported so a caller can iterate the canonical list, mirroring verify.FullGates. Treat it as read-only.
Functions ¶
func ChangedFiles ¶ added in v0.8.0
ChangedFiles returns the file paths changed between baseRef and headRef (`git diff --name-only`). Exported so other packages (CheckProtectedPaths below, find_affected_modules) can reuse it.
func CheckProtectedPaths ¶ added in v0.8.0
func CheckProtectedPaths(ctx context.Context, dir, baseRef, headRef string, protectedPaths []string) provenance.VerificationResult
CheckProtectedPaths reports whether any file changed between baseRef and headRef matches one of protectedPaths (contract.Contract.ProtectedPaths), returning one provenance.VerificationResult with Category VerificationProtectedPaths.
Patterns are matched with path.Match against "/"-separated paths, giving "*" single-segment glob semantics. CHANGELOG.md and go.mod get a file-scoped exception matching docs/planning/agent-safety-policy.md: adding to CHANGELOG.md's "## [Unreleased]" section is allowed, and only go.mod's `retract` directives are protected — see changelogEditIsWithinUnreleased and goModEditTouchesOnlyNonRetractLines. Every other path keeps plain "any change is a hit" matching.
A pattern that fails to compile as a path.Match glob (an unmatched "[") cannot protect anything, so it is reported as a StatusFail naming the pattern rather than silently treated as "never matches" — the remaining valid patterns are still enforced in the same pass.
Empty protectedPaths passes trivially (no contract, or none declared). A `git diff` failure reports StatusUnavailable, not a pass or fail.
func Review ¶
func Review(ctx context.Context, dir, baseRef, headRef string, tools []discovery.ToolStatus, allowNetwork bool, protectedPaths []string) []provenance.VerificationResult
Review runs Checks (via verify.Run), then ScanSecrets and CheckProtectedPaths over baseRef..headRef, returning one provenance.VerificationResult per check in that order.
dir is the repository root every check runs against (empty means the calling process's own cwd, unchanged from before dir existed as a parameter). tools gates RequiredTool as verify.Run documents. allowNetwork is forwarded to verify.Run. protectedPaths is contract.Contract.ProtectedPaths, if the caller has one; nil is normal, not an error.
func ScanSecrets ¶
func ScanSecrets(ctx context.Context, dir, baseRef, headRef string) provenance.VerificationResult
ScanSecrets runs a best-effort secret scan over the lines added between baseRef and headRef (git's "A...B" triple-dot form: everything reachable from headRef but not from baseRef's merge-base — the same diff scope scripts/check-changelog.sh uses), returning one provenance. VerificationResult with Category VerificationSecretScan.
Only added (+) lines are scanned, using redactLine: provenance. RedactHighConfidenceSecrets (AWS/PEM/GitHub/JWT — precise, low-noise shapes) plus this package's own strictGenericSecretPattern (a quote-required variant of provenance's looser generic catch-all, tuned for source code rather than command output; see that pattern's doc comment for why). Scanning is diff-scoped deliberately: see the package doc comment's "Boundary and compatibility checks are not diff-scoped" for why a repository-wide scan would be worse, not better, here.
A line containing nosecretMarker ("nosecret", case-insensitive) is never flagged, regardless of pattern matches — see its doc comment.
A finding's Message never contains the raw secret value: each reported line is passed through redactLine before being included, so only the redacted form is ever recorded. Findings are capped at maxSecretFindings; a diff with more reports the first maxSecretFindings plus a count of the rest.
If `git diff` itself fails (e.g. baseRef or headRef does not exist, or this is not a git repository), ScanSecrets returns provenance.StatusUnavailable rather than treating an inability to compute the diff as either a pass or a fail.
dir, if non-empty, is the repository gitDiff runs `git -C dir diff ...` against; empty leaves off -C entirely, so git resolves the repository from ScanSecrets' own calling process's current working directory — unchanged from this function's behavior before dir existed as a parameter.
Types ¶
This section is empty.