Agent Harness · Reference sheet
The commit skill
Eight steps the agent runs before every commit, each tied to the incident it prevents. Print it and tick it while you test your own skill. These are one working set of steps; keep the ones your team needs and add your own.
The 8 steps
Run in order; any failure means stop and report, not work around. Tick them while you test the skill on a real slice.
- 1. See what is staged
git status --shortthengit diff --cached --stat. Nothing staged: list changed files, propose the slice, ask beforegit add. Nevergit add -Aorgit add .
Prevents: one real session put 1,089 files in one "Initial commit"; another put the whole project, 60 files, in one commit - 2. Refuse build output and local files
git diff --cached --name-only | grep -E '(^|/)(bin|obj|tmp)/|\.db$|(^|/)\.env$'. Any match: stop, list, proposegit restore --stagedand a.gitignoreentry
Prevents: that 1,089-file commit was mostly junk: a vendoredtmp/toolchain andobj/build output
Backed by:.githooks/pre-commitstep 1 - 3. Refuse secrets
Run both: the pattern checkgit diff --cached | grep -nEi '(key|secret|password|pwd|token)["' ]*[:=] *["'][^"' ]{8,}'andgitleaks git --pre-commit --staged --redact(if installed). gitleaks misses readable config secrets; the pattern catches them. On a hit: stop, show file and line redacted, point to an env var and.env.example
Prevents: a real session that committed"Jwt":{"Key":"SuperSecretAuthenticationKeyForFulfillmentService2026!"}inappsettings.json. gitleaks 8.23.3 and 8.30.1 both did not flag this low-entropy value (measured 2026-09-30); the pattern check does
Backed by:.githooks/pre-commitstep 3 - 4. Check identity
git config user.emailmust be your work address (@yourcompany.com; change it to your own domain). If not, ask the human to fix it; never set it yourself
Prevents: commits authored under a personal address
Backed by:.githooks/pre-commitstep 2; denygit config user.email *@* - 5. Draft the message from the diff, not from memory
git diff --cachedthentype(scope): summary, imperative, 72 characters or fewer. No AI co-author or "Generated with" line. More than one slice in the diff: propose splitting
Prevents: "Update the changes"; "First commit"; a 60-file commit described as "add tests"; AI co-author trailers on most of a session's commits
Backed by:.githooks/commit-msg;attributionsetting - 6. Show and wait
Print the staged file list and the full message, ask "Commit with this message?" and wait for an explicit yes. If the human edits it, use their version verbatim
Prevents: one real session where the agent committed unasked; the developer: "i did not want u to commit anything until I say so"
Backed by:askonBash(git commit *) - 7. Commit
git commit -m "<subject>" -m "<body>"then report the short hash. One slice, one commit, made when the slice is green
Prevents: 56 commits sharing one timestamp, a history replayed after the work, so it no longer shows the order of work (lesson 10) - 8. Never push
Never push, never amend a pushed commit, never rebase. Pushing is the human's job
Prevents: a session where the developer asked the agent to force-push and it ran it; only the git server's branch protection refused. Another developer committed a clicked-together allow list holdinggit rebase *
Backed by: denygit push --force*; the destructive guard
Skill and guard, togetherThe skill is the agent's checklist; .githooks/pre-commit and commit-msg run the same checks when anyone commits. The skill keeps the agent from trying; the hooks stop it if it tries.
Conventional Commit types
| Type | Use for |
|---|---|
feat | A new capability (an endpoint, a rule) |
fix | A bug fix |
docs | Docs only, including docs(plan): ... |
test | Tests only |
refactor | Restructure, no behaviour change |
perf | Faster, same behaviour |
build | Build system, packages, Directory.Build.props |
ci | CI configuration |
chore | Housekeeping, harness files: chore(harness): ... |
style | Formatting only |
revert | Undo an earlier commit, as a new commit |
Subject: type(scope): summary, imperative, at most 72 characters after the colon. Scope is the area: products, orders, harness, plan. Body (optional): why, in 1-3 lines, and any 1-3-1 decision the human made. The commit-msg hook enforces this with a shell regex; Merge and Revert subjects pass.
Where it lives
.agents/skills/commit/SKILL.md: the tool-neutral home (Codex and Antigravity read it)..claude/skills/commit: a per-skill symlink to it, for Claude Code.- Invoke with
/commit(Claude Code, Antigravity) or$commit(Codex), or let the description trigger it. - In Claude Code a personal skill beats a project skill with the same name, so check
~/.claude/skills/for a clashingcommit.
Good and bad messages
| Bad (from real sessions) | Why | Good |
|---|---|---|
Initial commit (1,089 files) | Says nothing; carries junk | chore: scaffold solution with .gitignore for bin/, obj/ and tmp/ |
First commit (the entire API) | Nobody can review, bisect or revert a slice | feat(products): CRUD endpoints with SKU uniqueness |
Update the changes | Which changes? | feat(orders): atomic placement with stock check |
Add ppt and pdf | Not a change to the product | docs: README, AI process log |
add tests (60 files, the whole project) | Describes a sliver of the diff; misleading | One commit per slice, each message describing that slice |
| One commit holding the plan and the code | Git cannot show the plan came first | docs(plan): low-stock endpoint, alone, first |
Appendix: the SKILL.md, verbatim
---
name: commit
description: Commit the current slice. Use whenever a slice has passed the quality gate and review and the work should be committed, or when the user says "commit". Drafts a Conventional Commit message from the staged diff, refuses secrets and build output, checks your work identity, and waits for human approval. Never pushes.
---
# Commit
Follow every step in order. If any check fails, stop and report; do not work around it.
1. **See what is staged.**
`git status --short` and `git diff --cached --stat`.
If nothing is staged, list the changed files, propose which belong to this slice, and ask the human
before running `git add`. Never use `git add -A` or `git add .`.
2. **Refuse build output and local files.**
`git diff --cached --name-only | grep -E '(^|/)(bin|obj|tmp)/|\.db$|(^|/)\.env$'`
If anything matches: stop, list the paths, and propose `git restore --staged <path>` plus a `.gitignore` entry.
3. **Refuse secrets.**
Run BOTH checks. gitleaks finds known key formats but misses readable config secrets (a JWT signing key
spelled as a plain English phrase, for example), and the pattern catches those:
- `git diff --cached -- . ':(exclude)ai-session' | grep -nEi '(key|secret|password|pwd|token)["'\'' ]*[:=] *["'\''][^"'\'' ]{8,}'`
- `gitleaks git --pre-commit --staged --redact` (if installed; it also scans `ai-session/` transcripts)
On any finding: stop, show the file and line (redacted), and explain where the value should live
(environment variable, documented in `.env.example`). Continue only if the human confirms it is not a secret.
4. **Check identity.**
`git config user.email` must be your work address (`@yourcompany.com`; change this to your own domain).
If not, stop and ask the human to run `git config user.email <their work email>`. Do not set it yourself.
5. **Draft the message from the diff, not from memory.**
Read `git diff --cached`. Write:
- Subject: `type(scope): summary`, imperative, 72 characters or fewer.
Types: feat, fix, docs, test, refactor, perf, build, ci, chore, style, revert.
Scope: the area (products, orders, harness, plan …).
- Body (optional): why, in 1–3 lines; mention any 1-3-1 decision the human made.
- **No** `Co-Authored-By`, "Generated with" or any other AI attribution line.
If the diff holds more than one slice, say so and propose splitting it instead of writing one message.
6. **Show and wait.** Print the staged file list and the full message. Ask: "Commit with this message?"
Wait for an explicit yes. If the human edits the message, use their version verbatim.
7. **Commit.** `git commit -m "<subject>" -m "<body>"`. Report the short hash.
8. **Never push**, never amend a pushed commit, never rebase. Pushing is the human's job.Sources: Claude Code skills · Codex skills · Antigravity skills · Conventional Commits 1.0.0 · gitleaks (v8.30.1, git --pre-commit --staged). Last verified 2026-09-30.
Taught in: Lesson 5: Skills · Lesson 7: Guards · Lesson 10: Evidence and honesty
Other sheets: AGENTS.md structure · The four guards · 1-3-1 · Glossary · Tool equivalents