Skip to content

Updates#1

Merged
alxxjohn merged 10 commits into
mainfrom
updates
Jul 10, 2026
Merged

Updates#1
alxxjohn merged 10 commits into
mainfrom
updates

Conversation

@alxxjohn

Copy link
Copy Markdown
Contributor

Summary

Brings merger in line with its devr-tools siblings (codeguard, cleanr) so it can be governed, versioned, distributed, consumed as a library, and driven by agents — while keeping the control-plane services as the scaled deployment mode.

Previously merger was a two-daemon service with strong CI but none of the ecosystem's distribution, governance, or installable-tool surface. This PR adds all of it, and makes merger

What changed

Governance & scaffolding — Apache-2.0 LICENSE, SECURITY.md, CONTRIBUTING.md, CHANGELOG.md, CLAUDE.md + .claude/knowledge/,
internal/version, .golangci.yml + make lint.

Release & distribution — .goreleaser.yaml (multi-arch archives + GHCR images for all three binaries), Dockerfile.release, branch-driven cd.yml + reusable release.yml, Release Please config/manifest, Makefile release/release-check/release-snapshot/deploy/commit, and scripts/commit.sh.

User-facing CLI (cmd/merger) — version, init, vali analysis pipeline offline against a diff (via -diff or a -base-ref git range), classifies mutations, resolves runtime impact, scores risk, evaluates policy, and assigns a merge lane, with text/json output and a -fail-on-lane CI gate. New internal/scan reuses the same engines as the services with a filesystem content loader (no GitHub/bus/store deps); .merger/ config auto-discovery via internal/resolve.

SDK (pkg/merger) — Scan(ctx, ScanOptions), LoadPolicy, DefaultLanes, so callers run the pipeline as a library without importing internal/.

Agent-native + Action + Homebrew — merger mcp (std_scan/merger_validate), a composite GitHubaction.yml, homebrew-validation.yml, and a sync-homebrew-formula release job.

codeguard gate — merger now runs codeguard in CI (.codeguard/codeguard.yaml + baseline) in diff mode. Generated code excluded,
codeguard's govulncheck disabled (merger's own secented waiver for the reviewed git diff exec, andpre-existing findings baselined.

Breaking change

The Go module path changed from github.com/mergerhq/merger to github.com/devr-tools/merger to match the GitHub home (required for go install and Homebrew to resolve). All import paths change accordingly. This is the refactor!: commit.

Verification

Full local CI-parity sweep passes (7/7): fmt, vet, coverage 67.3% (gate 60%), and codeguard (4sections pass, 0 findings, 31 suppressed). CLI, SDK, and MCP server were each exercised end-to-end. Note: GitHub-hosted workflows and goreleaser check were validated as config only — this PR's CI run is their first live execution.

Operational prerequisites / follow-ups

  • Repo secret RELEASE_PLEASE_TOKEN must be set fornc flows; packages: write for GHCR.
  • One-time: seed Formula/merger.rb in devr-tools/homebrew-tap before the first automated formula sync.
  • Deferred (documented in docs/release-automation..

alxxjohn and others added 10 commits July 10, 2026 12:18
Bring merger in line with the devr-tools tool family (codeguard, cleanr)
so it can be governed, versioned, and distributed the same way.

Governance & table stakes:
- Apache-2.0 LICENSE (matches siblings)
- internal/version package (var Number, ldflags-injectable + release-please marker)
- .golangci.yml (v2) and `make lint`
- SECURITY.md, CONTRIBUTING.md, CHANGELOG.md
- CLAUDE.md + .claude/knowledge/ area files

Distribution:
- .goreleaser.yaml: multi-arch archives + GHCR images for both daemons
- Dockerfile.release bundling merger-ingest and merger-controlplane
- cd.yml (branch-driven CD) + reusable release.yml publisher
- Release Please config + manifest pinned to 0.1.0
- Makefile release/release-check/release-snapshot/deploy/commit verbs
- scripts/commit.sh conventional-commit helper
- docs/release-automation.md

Homebrew/npm/pip distribution are intentionally deferred until the
user-facing `merger` CLI binary lands, since those channels ship a CLI
rather than the control-plane daemons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
Give merger the installable CLI face of its devr-tools siblings while
keeping the control-plane services as the scaled deployment mode.

- cmd/merger: version, init, validate, scan subcommands
- internal/scan: offline pipeline reusing the mutations, runtime-graph,
  risk, policy, and lane engines against a raw unified diff, with a
  filesystem-backed content loader (no GitHub/bus/store dependencies)
- internal/cli: config auto-discovery (.merger/), report rendering
  (text/json), and a -fail-on-lane CI gate
- scan reads a diff from -diff <file|-> or a -base-ref git range
- tests: black-box coverage for internal/scan and internal/cli
  (internal coverage 67.4%, above the 60% gate)
- README + CHANGELOG document the CLI

This unblocks Homebrew/npm/pip distribution (Phase 3), which attach to
the CLI binary rather than the daemons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
The GoReleaser config predated the CLI. Build cmd/merger and add it to
the release archive so tagged releases and `go install` ship the CLI
alongside the ingest and control-plane daemons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
Expose merger.Scan(ctx, ScanOptions) plus merger.LoadPolicy and
merger.DefaultLanes so callers can run the analysis pipeline as a library
without importing internal packages. Re-uses the existing domain type
aliases in pkg/merger.

- pkg/merger/scan.go: Scan, LoadPolicy, DefaultLanes, Scan/Policy/Lanes option aliases
- tests/merger: black-box SDK coverage
- README SDK section + docs/sdk.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
The module was declared as github.com/mergerhq/merger while the repository
lives at github.com/devr-tools/merger. That mismatch broke the ecosystem's
primary install path — `go install github.com/devr-tools/merger/cmd/merger`
resolves against the module path in go.mod — and would break the Homebrew
formula and Go-based installs.

Rename the module to match the GitHub home, aligning with the sibling tools
(github.com/devr-tools/{codeguard,cleanr}). Mechanical rewrite of all imports,
the GoReleaser ldflags paths, and the proto go_package option.

BREAKING CHANGE: import paths change from github.com/mergerhq/merger/... to
github.com/devr-tools/merger/...

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
- action.yml: composite action that installs merger and runs `merger scan`
  against a base ref, with an optional -fail-on-lane workflow gate
- homebrew-validation.yml: builds and tests Formula/merger.rb from source on
  every PR (ubuntu + macos)
- release.yml: sync-homebrew-formula job opens a formula-update PR against
  devr-tools/homebrew-tap on stable releases
- README install now lists `brew install devr-tools/tap/merger`
- docs/release-automation.md documents Homebrew, the Action, and the one-time
  tap-seeding step; CHANGELOG updated

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
Expose merger's offline analysis to agents over the Model Context Protocol.

- internal/mcpserver: hand-rolled stdio JSON-RPC 2.0 server (same shape as the
  sibling tools) with merger_scan and merger_validate tools; panics are
  contained and ordinary failures return as isError results
- cmd/merger: new `merger mcp` subcommand
- internal/resolve: extract config auto-discovery, policy resolution, and
  scan-option assembly out of internal/cli so both the CLI and the MCP server
  resolve configuration identically (mcpserver can't import cli without a cycle)
- tests/mcpserver: initialize/tools-list/tools-call coverage
- docs/mcp.md + README/CHANGELOG; internal coverage 67.3%

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
Add codeguard (the sibling devr-tools checks tool) to merger's CI so it
runs against its own codebase, matching how cleanr consumes it.

- .codeguard/codeguard.yaml: quality/security/ci checks, generated code
  (**/*.pb.go) excluded, codeguard's govulncheck disabled (merger's own
  `security` job covers it), and a documented waiver for the reviewed
  `git diff` exec in `merger scan`
- .codeguard/baseline.json: pre-existing findings captured at adoption so
  the gate fails only on new issues (fingerprint-based, line-stable)
- ci.yml: `codeguard` job (needs vet+gocyclo) via devr-tools/codeguard@v0.8.1
  in diff mode on PRs
- .gitignore: track only the config and baseline; caches are generated

Verified locally: `codeguard scan -config .codeguard` -> 4 pass, 0 fail,
0 findings, 31 suppressed (exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
SHELL was hardcoded to /bin/zsh, which exists on macOS but not on the
Linux CI runners, so every make-based CI step failed with exit 127
(`make: /bin/zsh: No such file or directory`) — including fmt-check,
which surfaced as the formatting job failing before it ran gofmt.

/bin/bash is present on both macOS and Linux and the recipes use no
zsh-specific syntax. Verified fmt-check/vet/gocyclo/smoke run locally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
The semgrep job (--config auto --error) flagged the workflow files this
PR introduces. Address all three finding types:

- run-shell-injection (action.yml): route inputs through `env:` and
  reference them as "$VAR" in run: steps instead of interpolating
  `${{ inputs.* }}` directly into the shell.
- secrets-inherit (cd.yml): stop passing all repo secrets to the
  reusable release workflow; declare RELEASE_PLEASE_TOKEN on
  release.yml's workflow_call and pass only that. GITHUB_TOKEN remains
  available to reusable workflows automatically.
- mutable-action-tag: exclude this one rule in the semgrep step. merger
  intentionally pins actions to version tags (matching the sibling
  devr-tools tools), not commit SHAs; the rest of semgrep still runs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Alex Wilkerson John <alex.w@linktr.ee>
@alxxjohn alxxjohn merged commit 45c69ea into main Jul 10, 2026
17 checks passed
@alxxjohn alxxjohn deleted the updates branch July 10, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant