Lifecycle & Drift Detection
Tuff is built around capability lifecycle management, not just file installation.
The core loop is:
- create or add a capability into an agent
- record the install-time baseline
- allow the repo to customize the emitted files
- detect drift relative to the recorded baseline
- make that drift visible through listing, diffing, checking, and updates
This is the main reason Tuff exists. Teams need project-owned capabilities that can evolve without losing provenance, source metadata, or update behavior.
Tuff and Git
Section titled “Tuff and Git”Git is still the system of record for repository history. Tuff adds a different layer of state.
Git can tell you that a file changed. Tuff also records:
- which capability produced that file
- which agent emitted it
- which baseline version it came from
- whether it was installed from a local source or git source
- which upstream revision it was pinned to
That extra metadata is the part plain Git history does not carry.
It also means teams can relate capability version changes to downstream effects such as:
- agent behavior changes
- review outcomes
- prompt quality shifts
- performance or evaluation metrics tracked outside Tuff
Tuff does not replace Git. It versions the capability lifecycle metadata around the files Git is already storing.
Baseline, local, and upstream
Section titled “Baseline, local, and upstream”Tuff models every tracked emitted file as up to three states:
| Version | Source |
|---|---|
| Baseline | Content recorded at last install, import, or update |
| Local | Current file in .agents/ or .claude/ |
| Upstream | Latest file content from the git source, if the capability was installed from git |
Drift states
Section titled “Drift states”When Tuff compares local files against the recorded baseline, the common states are:
| State | Meaning |
|---|---|
clean | Installed content matches the recorded baseline |
modified | Local content differs from the recorded baseline |
missing | A tracked emitted file no longer exists |
Local capability lifecycle
Section titled “Local capability lifecycle”For local capabilities, the typical flow is:
tuff create skill my-skilltuff listtuff diff my-skillCreation initializes tracking automatically. It uses the configured default
agent; pass --agent claude to create
the scaffold under .claude/ instead.
If the drift is intentional and should become the new baseline:
tuff update my-skillCleanup
Section titled “Cleanup”Cleanup is explicit about file ownership. For a capability Tuff installed by copying files into an agent, delete only the generated agent files:
tuff delete my-skillFor a capability added from an existing .agents/ or .claude/ directory,
remove Tuff tracking without touching the files:
tuff untrack my-skillBoth commands use the configured default agent unless -a/--agent is provided.
delete refuses in-place added capabilities and requires --force for locally modified generated files. untrack removes the
target lock entry and baseline while preserving the capability files and MCP
configuration. The original source directory is never
deleted by delete.
See the CLI Reference for cleanup flags and explicit agent selection.
Git-sourced capability lifecycle
Section titled “Git-sourced capability lifecycle”For git-backed capabilities, Tuff can compare baseline, local, and upstream together:
tuff outdatedtuff diff rust-implement --upstreamtuff update rust-implement --checktuff update rust-implementUpdate behavior
Section titled “Update behavior”The update path for git-sourced capabilities works like this:
| Local | Upstream | Behavior |
|---|---|---|
| clean | unchanged | No-op |
| clean | changed | Apply upstream, refresh baseline |
| modified | unchanged | Keep local state, report drift |
| modified | changed | Attempt three-way merge |
| conflict | changed | Report conflicts and preserve local files |
If you want to replace the local customized copy with upstream output, use:
tuff update <id> --forceCommands in the lifecycle
Section titled “Commands in the lifecycle”| Command | Purpose |
|---|---|
tuff list | Show drift status and agent paths |
tuff diff <id> | Show local changes against baseline |
tuff diff <id> --upstream | Show upstream changes against baseline |
tuff check | Fail CI when tracked files drift |
tuff outdated | Show whether git-sourced capabilities have newer revisions |
tuff update <id> | Accept local edits or reconcile git-backed changes |
tuff delete <id> | Delete Tuff-generated files for the default agent |
tuff untrack <id> | Remove tracking while preserving files for the default agent |
Capability Metadata
Section titled “Capability Metadata”The important difference is not just that Tuff detects drift. It keeps the capability metadata attached to the emitted files for the whole lifecycle:
- source
- version
- agent
- baseline
- scope
- update path
That makes the capability observable over time instead of becoming another copied file in the repo.