$ outdatty check [ stale ] feature source changed: src/feature.rs review dependent: docs/feature.mdx review dependent: tests/feature.rs confirm with: outdatty update --group feature outdatty: 1 of 4 groups out of date (exit 1) $ outdatty update --group feature updated feature $ outdatty check outdatty: 4 groups up to date (exit 0)
# How it works
No commands run, no build graph.
One question: did a source change without its dependents being confirmed?
Declare
A YAML manifest groups source files with the dependents that must stay in sync with them.
Confirm
outdatty update records a blake3 hash of every file into a committed outdatty.lock.
Check
outdatty check recomputes hashes in CI. A changed source with stale dependents fails with exit 1.
Re-confirm
Update the dependents, run outdatty update to re-lock, and the group is green again.
# The manifest
Language- and format-agnostic: code, docs, .docx, configs — anything with bytes.
Globs are gitignore-aware by default.
# yaml-language-server: $schema=https://raw.githubusercontent.com/mlavrinenko/outdatty/main/schema/outdatty.schema.json require_tracked: ["**", "!vendor/**"] # every file must belong to a group; !excludes groups: - name: feature source: [src/feature.rs] # literal paths or globs like src/**/*.rs dependents: [docs/feature.mdx, tests/feature.rs] # bidirectional: true # also flag when a dependent changes
require_tracked (default ["**"]) fails
check when a brand-new file belongs to no group — so
nothing slips in untracked.
Rather keep the pair in .config/? Add
root: .. to .config/outdatty.yaml and every
path and lock key resolves from the repo root, just as before.
outdatty finds that manifest without a --manifest flag.
A group you rename or drop leaves its hashes in the lock, and
check fails on them until a plain
outdatty update prunes them.
# Why not…
outdatty sits between two categories and does neither's job.
Build systems
Task, Bazel, Buck2 run commands to produce output. outdatty runs nothing — it only flags drift.
Integrity monitors
AIDE hashes files in isolation. outdatty models dependencies between files.
Doc linters
Tied to one language or format. outdatty couples any bytes to any other bytes.
# Install
# run without installing $ nix run github:mlavrinenko/outdatty -- check # or add it to your flake inputs inputs.outdatty.url = "github:mlavrinenko/outdatty";
$ cargo install outdatty
Download a pre-built binary from the latest release.
Gate CI
# .github/workflows/outdatty.yml
- run: outdatty check --format quiet
Review drift
# pipe changed sources into your own diff tool $ outdatty status --format=paths0 | xargs -0 -r git diff --
Merge the lock
# branches that record different groups merge without a conflict $ git config merge.outdatty.driver 'outdatty merge-lock %O %A %B' $ echo 'outdatty.lock merge=outdatty' >> .gitattributes