Help us shape the future of Go! Take the 2026 Go Developer Survey

diff-rationale

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 8, 2026 License: Apache-2.0

README

diffrat

Capture the why behind text changes, store it in git-adjacent records, and make it queryable by humans and agents ("why is this code the way it is?", "why does this paragraph say that?").

The goal: every changed line on a retained branch carries rationale — an answer, an exemption, or an explicit debt record. Coverage is measured, never enforced — check/status report what is unexplained; diffrat show answers from the records later.

Install

go install github.com/cameron-mcateer/diff-rationale/cmd/diffrat@latest

The only runtime dependency is git. Prebuilt binaries for Linux, macOS, and Windows are on the releases page.

The VS Code extension (diffrat-<version>.vsix) is attached to each release; install it with Extensions: Install from VSIX… or code --install-extension diffrat-<version>.vsix.

Try it

cd <your-repo>
diffrat init            # writes .rationale/ schema+config (commit those),
                        #   mints the epoch
# ...make a change, commit it...
diffrat check           # shows what still needs rationale
diffrat interview       # answer; records land on refs/rationale/records
diffrat show path.go:42 # ask why later

On any other clone: diffrat sync origin brings the store — records live on their own ref, which the CLI moves itself, so nothing comes down on git clone. The remote is a required argument; diffrat never picks one for you.

Or stage the rationale without a prompt — the path an in-session agent takes while it is still making the change:

diffrat add src/cache.go:41-58,L15-33 \
  -m motivation "why this change" -m alternatives "what was rejected" \
  --author "Agent Name <agent@example.com>"
# ...`add` prints the lines still uncovered; repeat until none...
git commit -am "..."
diffrat mint            # freezes the window; prints any lines left uncovered

Working with a coding agent

agents.md is a drop-in brief for LLM coding agents: paste it into your agent instructions and the agent stages rationale for its own changes with diffrat add as it works, then diffrat mint after the commit.

Documentation

The full manual is in docs/ — workflow guides (adopting, the daily loop, asking why, feature branches, rebasing, backfilling history, hotfix debt, where the records live) and one reference page per command. Every example there is real, generated output from the released binary.

License

Apache-2.0

Directories

Path Synopsis
cmd
diffrat command
Command diffrat captures the "why" behind text changes — staged records and interviews, voluntary by design — and makes the records queryable.
Command diffrat captures the "why" behind text changes — staged records and interviews, voluntary by design — and makes the records queryable.
internal
coverage
Package coverage owns the measure (design §1): coverage over changed lines, two-sided (added lines on head, deleted lines on base), computed with pinned diff settings — measured and reported, never enforced.
Package coverage owns the measure (design §1): coverage over changed lines, two-sided (added lines on head, deleted lines on base), computed with pinned diff settings — measured and reported, never enforced.
fsck
Package fsck is the store verification pass (design §9, format 3): it reads every window pair, places it on the retained branches' lines, and reports what it finds.
Package fsck is the store verification pass (design §9, format 3): it reads every window pair, places it on the retained branches' lines, and reports what it finds.
gc
Package gc selects abandoned pre-mint capture state for deletion (design §6, journal-ref GC).
Package gc selects abandoned pre-mint capture state for deletion (design §6, journal-ref GC).
gitx
Package gitx is the git facade (design §14, Implementation engine): all git access in the codebase routes through this package, implemented as git plumbing via child processes.
Package gitx is the git facade (design §14, Implementation engine): all git access in the codebase routes through this package, implemented as git plumbing via child processes.
interview
Package interview is the channel-agnostic engine (design §2, §5): a stateless function of (diff, prior answers) → next question | completed answers.
Package interview is the channel-agnostic engine (design §2, §5): a stateless function of (diff, prior answers) → next question | completed answers.
journal
Package journal is the mutable per-branch working state during a change's lifetime (design §6): which changed lines of the current net diff are covered by which answers.
Package journal is the mutable per-branch working state during a change's lifetime (design §6): which changed lines of the current net diff are covered by which answers.
manifest
Package manifest defines the per-window fact (window-manifest-format.md, format 3): a window is an annotation scope identified by the diff's two inputs — the (head tree, base tree) pair, stored only in the store path — and its manifest carries just the frozen diff-settings pin plus an advisory, append-only provenance list of the mint events observed against it.
Package manifest defines the per-window fact (window-manifest-format.md, format 3): a window is an annotation scope identified by the diff's two inputs — the (head tree, base tree) pair, stored only in the store path — and its manifest carries just the frozen diff-settings pin plus an advisory, append-only provenance list of the mint events observed against it.
mint
Package mint turns a merged journal into records (design §6): run once per landing on a retained branch, when SHAs stabilize.
Package mint turns a merged journal into records (design §6): run once per landing on a retained branch, when SHAs stabilize.
pending
Package pending holds records written toward a window that has not been minted yet (§7): mutable, local, resettable dev state under .git/rationale/pending/, deliberately not a ref — refsync never sees it and coverage reports never count it.
Package pending holds records written toward a window that has not been minted yet (§7): mutable, local, resettable dev state under .git/rationale/pending/, deliberately not a ref — refsync never sees it and coverage reports never count it.
query
Package query is the read path (design §11): scope overlap as the primary join, with line-range history traversal (git log -L) as the join primitive.
Package query is the read path (design §11): scope overlap as the primary join, with line-range history traversal (git log -L) as the join primitive.
record
Package record defines the envelope schema (design §3) and record serialization.
Package record defines the envelope schema (design §3) and record serialization.
refsync
Package refsync moves the tool's own ref — refs/rationale/records — between this clone and the remote (design §6, §9).
Package refsync moves the tool's own ref — refs/rationale/records — between this clone and the remote (design §6, §9).
teamschema
Package teamschema reads the team-owned files under .rationale/ (design §3, §14): schema.yaml (payload field taxonomy + question templates, pinned per-record by blob SHA) and config.yaml (retained branches, exemption patterns, journal GC, plugin commands).
Package teamschema reads the team-owned files under .rationale/ (design §3, §14): schema.yaml (payload field taxonomy + question templates, pinned per-record by blob SHA) and config.yaml (retained branches, exemption patterns, journal GC, plugin commands).
units
Package units computes the floor partition (design §5, design §5): one base..head diff's changed-line runs as one-sided, line-granular units.
Package units computes the floor partition (design §5, design §5): one base..head diff's changed-line runs as one-sided, line-granular units.
pkg
api
Package api defines rationale's stable machine-readable surface: the --json wire format of the CLI, which is the one supported integration contract — external tools consume the serialized envelope (design §14).
Package api defines rationale's stable machine-readable surface: the --json wire format of the CLI, which is the one supported integration contract — external tools consume the serialized envelope (design §14).
rationale
Package rationale is the facade the CLI's read commands render over: it returns the pkg/api types that --json serializes, so the wire contract is built in exactly one place.
Package rationale is the facade the CLI's read commands render over: it returns the pkg/api types that --json serializes, so the wire contract is built in exactly one place.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL