v1.15.0
Four new surfaces. commitbrief leaks audits the working tree and git history for committed credentials with no provider call; commitbrief map draws the commit graph and shows exactly what a filter selected; commit-level filters (--author, --committer, --start-date, --end-date, --text) review a set of commits instead of one diff; and commitbrief upgrade updates the binary across every install method.
Added
-
commitbrief leaks— audit the working tree and git history for committed credentials (ADR-0036). The pre-send secret scanner is a gate: it only ever sees the one diff about to be sent, so it cannot answer “is there a key in my tree right now?” or “did anyone ever commit one?” — and a key that was committed and later removed is still in the history, still reachable in every clone and fork.leaksanswers both with the same eight built-in patterns plus yourguard.secret_patterns, deterministically: no provider call, no cache, no cost.commitbrief leaks # tracked files + last 200 commits commitbrief leaks --no-history # working tree only, fast commitbrief leaks main..HEAD --no-worktree # exactly that range commitbrief leaks --json | commitbrief guard --from-json -Both halves run by default (
--no-worktree/--no-historyswitch either off). The working-tree half reads every tracked file whole — untracked, gitignored files like.envare deliberately out of scope, since that is where a secret is supposed to live and it cannot leak through git. The history half scans the added lines of the commits ADR-0035’s filters select, attributing each hit to its commit, author and date, because that is what decides whether a key still needs rotating. Bounded by--max-commits(default 200), and truncation is always reported.It exits 1 on any hit, so it gates CI out of the box;
--fail-on nonereports without failing.--jsonemits the existing schema v1 withmeta.provider: "builtin", so the policy gate consumes it with no new plumbing. Findings carry a file, a line and the pattern names — never the matched text. Two limits are documented rather than hidden: it honors the ignore layers, so a key insidevendor/**is not reported, and it is regex-only, so a high-entropy blob with no recognizable prefix is invisible. -
commitbrief map— the commit graph, and what your filter actually selected (ADR-0037). The commit filters can pick a non-contiguous set from anywhere in the history, and the only feedback was a count (“12 commits matched”) — so a wrong filter silently reviewed the wrong code.mapdraws the DAG with matching commits highlighted and the rest dimmed as context, which makes a filter checkable before you pay for a review.--branchesswitches to a branch topology summary: where each branch sits relative to the base and how far ahead / behind. Deterministic, and always exits 0 — a viewer, not a gate. Rows clip to the terminal rather than wrapping, and colour plus box-drawing fall back together, so a pipe or--color=neveryields plain ASCII. No new dependencies: lane assignment is a pure function in a newinternal/graphpackage. -
Commit-level filters:
--author,--committer,--start-date,--end-date,--text(ADR-0035). Review a set of commits rather than a single diff.git diffhas no author or date options — those aregit logoptions — so setting any of these switches diff acquisition to a commit walk: pick the matching commits, then concatenate their patches. Different filter kinds are AND’d and multiple values of one kind are OR’d, so--author alice --author bob --start-date 2026-06-01means “(Alice or Bob) and since June”. Identity matching is a case-insensitive substring over both the name and the email.--end-dateis inclusive of the day named (git’s bare--untilstops at that day’s midnight and silently drops it).--textmatches the commit message and the name of a branch, in which case the commits unique to that branch are pulled in — best-effort by nature, since a squash- or rebase-merged branch no longer owns its commits.With no explicit range the walk covers
HEAD; a subcommand’s range bounds it (commitbrief diff main..develop --author alice). Two modifiers shape a walk but never start one, and are rejected if used alone:--max-commits N(default 200) caps the selection and always reports truncation rather than silently reviewing a subset, and--mergeskeeps merge commits, which are excluded by default.Available on the default review,
diff,summary,dry-run, the MCPreviewtool andguard. Rejected bycommit(it describes the staged index, which has no commits) and byremote pr(its diff comes fromgh pr diff, not local git). -
--exclude-file/--exclude-dirpath denylists. The inverse of--file/--dir, sharing their exact matching rules (literal path or gitignore-style glob) and applied after them, so an exclusion always wins:--dir internal --exclude-dir internal/cli. An invalid glob errors before any provider call, as it does for the allowlist. -
Path and commit filters are now reachable over MCP. The
reviewtool gainedfile,dir,exclude_file,exclude_dir,author,committer,start_date,end_date,text,max_commitsandmergesarguments.--file/--dirwere previously CLI-only in practice: the MCP seam resets the global flag state, so a host had no way to narrow a review by path.guardforwards the same set from its inherited persistent flags. -
meta.filtered_commitsin the JSON output. Optional andomitempty, so the schema stays1— the count of commits whose patches make up the reviewed diff.dry-rungains matchingCommits (walked)/Commits (matched)lines and an--exclude-file/--exclude-dirrow in its per-layer file accounting. -
commitbrief upgrade— in-tool updates across every install method (ADR-0034). Detects whether the running binary came from Homebrew, Scoop,go installor a GitHub Releases tarball. Package-managed installs are delegated to their own manager (brew upgrade/scoop update/go install …@latest), because overwriting a manager-owned binary desynchronizes its metadata; only a manual install is replaced in place, after its SHA-256 is verified against the releasechecksums.txt. An unwritable target aborts before anything is downloaded and prints the exact command to run — CommitBrief never invokessudoitself.--checkreports without installing and always exits 0;--jsonimplies--check. The version check runs only when you invoke the command: there is no automatic update check and no telemetry.
Changed
commitbrief list’s built-in command reference was several releases stale — it never listedcommit,guard,mcp,remote pr,doctor,providers,config,install-hookorupgrade. Rewritten to cover the whole surface, including the path and commit filters.--max-commitsand--mergesare usage errors on a review when no commit filter is set (nothing to modify), but ordinary bounds onleaksandmap, which always walk history.
Fixed
commitbrief remote prnow applies--file/--diron the posting path too. Only the--no-postpath honored them, so a narrowed run that commented on GitHub reviewed a different file set than the same command with--no-post.