template-jj/docs/building.md
Sid 7fa52772b3 docs: add reference docs for both binaries + consolidated build guide
* docs/building.md — how to build jj-commitd and planctl from source,
  requirements, `go install` recipes, reproducible-build flags
  (`-trimpath -ldflags="-buildid="` per planctl PRD R7.3), test +
  benchmark commands, cross-compile, CI matrix link.
* docs/planctl.md — full command reference beyond --help: plan-dir
  discovery cases A-D, all 9 classification codes with severity and
  meaning, tag-grammar spec (including paren-aware annotations + the
  tag-unclosed recovery semantics), the five EARS regexes and the
  bold-prefix exemption, JSON schema, worked examples for pre-commit
  / CI / multi-plan / JSON consumers.
* docs/jj-commitd.md — architecture diagram, socket event protocol
  (session-start, post-edit, session-end, shutdown, status) with
  field tables, all env vars (REPO_ROOT, JJ_HOOK_DEBOUNCE_SEC,
  JJ_HOOK_STALE_MIN, JJ_HOOK_AUTO_SQUASH), baked-in timing constants,
  socket / log paths, fallback mode, troubleshooting.
* README.md — expanded the jj-commitd bullets and linked to each
  reference from a new "Documentation" section; kept top-level
  summaries terse.
2026-04-21 21:38:01 -06:00

4.1 KiB

Building from source

This repo ships two Go binaries under cmd/:

Binary Purpose Path
jj-commitd Debounced commit daemon for Claude Code sessions (optional). cmd/jj-commitd/
planctl Lint tool for spec-driven plan directories. cmd/planctl/

Both are pure-Go, standard-module-layout, and require no system libraries at runtime. jj-commitd shells out to the jj CLI; planctl has no runtime dependencies beyond the Go standard library and the one compiled-in github.com/yuin/goldmark module.

Requirements

  • Go 1.22 or newer on PATH. The repo's go.mod pins a higher toolchain (go 1.26.1) for development, but both binaries compile on 1.22 per PRD R7.1 and the CI matrix in .forgejo/workflows/planctl.yml.
  • jj — only needed at runtime for jj-commitd. Not a build dependency.
  • No other tools needed for a vanilla build.

Places the binary at $GOBIN (falls back to $GOPATH/bin, defaulting to ~/go/bin/). Make sure that directory is on your PATH.

# From anywhere:
go install forgejo.zerova.net/sid/template-jj/cmd/planctl@latest
go install forgejo.zerova.net/sid/template-jj/cmd/jj-commitd@latest

# Pin a specific tag or commit:
go install forgejo.zerova.net/sid/template-jj/cmd/planctl@v1.0.0
go install forgejo.zerova.net/sid/template-jj/cmd/planctl@<commit-sha>

Both binaries are tagged in lockstep with the repo.

Building from a checkout

git clone https://forgejo.zerova.net/sid/template-jj.git
cd template-jj

# Binaries to ./bin/
go build -o bin/planctl    ./cmd/planctl/
go build -o bin/jj-commitd ./cmd/jj-commitd/

go build without -o emits the binary into the current directory using the package directory name — useful for one-off checks:

cd cmd/planctl && go build && ./planctl --version

Reproducible builds

Per PRD R7.3 for planctlgo build -trimpath -ldflags="-buildid=" produces byte-stable binaries given the same source.

go build -trimpath -ldflags="-buildid=" -o bin/planctl ./cmd/planctl/

-trimpath strips the absolute checkout path from the binary; -buildid= zeroes the per-build Go toolchain fingerprint. The output is suitable for deterministic distribution and CI caching.

Verifying the build

./bin/planctl --version
# planctl 0.1.0-dev

./bin/jj-commitd status  # over an existing socket — see docs/jj-commitd.md

Run the test suite:

go test ./cmd/planctl/...
go test ./cmd/jj-commitd/...

planctl also has a benchmark:

go test -bench=. -benchtime=3x -run=^$ ./cmd/planctl/

Expected output on a 2023-era machine: ~1 ms per Benchmark_Lint_BigPlan invocation (the ~90 KB testdata/perf/big-plan fixture), well under the PRD success metric M3 ceiling of 100 ms.

CI matrix

planctl is exercised in .forgejo/workflows/planctl.yml across:

  • os: ubuntu-latest, macos-latest, windows-latest
  • go: 1.22, stable

A dedicated benchmark job runs once per push on ubuntu-latest + stable. jj-commitd has no CI cell yet — it's covered by its own package tests and integration in practice.

Binary sizes

On darwin/arm64 with Go 1.26.1, stripped with -ldflags="-s -w":

  • planctl: ~5 MB (includes goldmark).
  • jj-commitd: ~3 MB (stdlib only).

Both well under any practical size budget.

Cross-compiling

Standard Go cross-compile:

GOOS=linux GOARCH=amd64 go build -o bin/planctl-linux-amd64 ./cmd/planctl/
GOOS=windows GOARCH=amd64 go build -o bin/planctl.exe ./cmd/planctl/

No cgo dependencies; cross-builds work on any platform with the Go toolchain.

See also