Auto-commit per turn

Every turn that touches files lands as its own attributed git commit.

When to use it

Auto-commit-per-turn is the default for a reason: it gives every charm a clean, attributed history without the human in the loop having to remember to commit. Three concrete moments where it earns its keep:

How it works

Two hooks fire around every conversation-loop turn when state.git_auto_commit is on (the default):

  1. Pre-cantrip commit. If the working tree is dirty when the user types, Cantrip commits the dirty state first as chore(pre-cantrip): save in-progress work. This means your hand-edits never get squashed into the agent's commit. Untracked files participate too — the pre-commit runs git add -A.
  2. Agent commit. After the final assistant message lands, Cantrip walks the turn's tool calls for write_file / edit_file / multi_edit, stages the touched paths explicitly via git add -- <paths> (no catch-alls), and commits with a Cantrip co-author trailer. The subject line is generated by the light provider when one is configured; without one we fall back to agent: <truncated user message>.

Commit message shape

feat(charm): add ops-tracing integration

Prompt: Add ops-tracing to src/charm.py so we can trace hook execution
in the dev model.

Touched:
  - src/charm.py
  - charmcraft.yaml

Co-Authored-By: Cantrip <noreply@aotearoa.dev>

Subject line is capped at 72 characters, prompt is capped at ~280 characters, the touched-file list truncates after 20 entries with a "and N more" hint.

Disabling auto-commit

Three ways:

When auto-commit is off, agent edits stay in the working tree until you commit them yourself. The pre-cantrip dirty-commit also skips, so a turn that starts with a dirty tree just runs the agent against that state.

Interaction with /undo

/undo restores the working tree from the snapshot taken just before the user turn. Because snapshots and the user's repo are independent, the auto-commit's contents are still in git log after /undo — HEAD points at the agent commit but the working tree no longer matches it.

To reconcile, run one of:

What auto-commit is not