Git Workflow
On this page
Commit Signing (Required)
All commits must be GPG or EdDSA signed. Configure per-repository:
git config user.email "<your-email>"
git config user.signingkey <your-key-fingerprint>
git config commit.gpgsign true
Project-specific signing details (key fingerprint, email) belong in
.claude/CLAUDE.md, not here.
Branching
-
Feature branches:
feature/Branching, commits, signing, hooks, and versioning, merge to main via MR when all checks pass. -
Direct-to-main: allowed ONLY for docs-only changes that do not touch code. If protected-branch rules block direct pushes, use a branch + MR even for docs.
-
Merge conflicts: rebase onto main (
git rebase main), do NOT merge main into the branch.
Commit Messages
-
Imperative mood: "add gallery page" (not "added").
-
Type-prefixed:
feat:,fix:,chore:,refactor:,docs:,test:. -
Under 72 characters for the first line.
-
Co-Authored-By:trailer on every AI-assisted commit — required, as the last line(s) of the commit body, naming the actual model from the current system prompt (not a stale value or a hook’s suggested default). -
Example:
feat: add foster family resource page.
Bug Discovery
-
Bugs found during implementation: do NOT fix in the same MR.
-
Create a new
fix:issue, link with/relate, fix in a separate branch.
Multi-MR Plans
-
Only the last MR of a plan updates
.claude/CLAUDE.mdstatus tables. Earlier MRs update the project’s service docs. -
Update the plan’s status section after each step, not at end of session.
Work Claiming
-
Assign yourself before starting:
glab issue update <N> --assignee @me. -
Check assignee first — do not compete.
Code Review & Merge
-
CODEOWNERS approval required (self-merge acceptable for sole-developer projects until the team grows).
-
Preserve authorship on merge — merge with a regular merge commit; never squash-on-merge. Squashing rewrites the merged commit to the merging account (erasing the human author) and strips the original GPG/EdDSA signature. Keep
should_remove_source_branchon and leave squash off. -
API contract stability: after the first stable release (1.0.0+), response shapes are additive only — no field removals, type changes, or renamed endpoints. Pre-1.0, breaking changes are permitted but must be documented in
CHANGELOG.adocunderChangedorRemoved.
Git Hooks
Activate (and ensure the exec bit survives checkout):
git config core.hooksPath .githooks && chmod +x .githooks/*
Git silently skips a hook that is not executable, emitting only an
advice.ignoredHook hint. If you see that hint — or commits/pushes sail through
with no checklist — the exec bit was lost; re-run the chmod above.
Also re-verify git config core.hooksPath still returns .githooks. It can
silently reset to the default .git/hooks (e.g. after certain git operations or
tooling that rewrites git config), which bypasses every vendored hook with no
warning. Check it before committing — especially in a long-running session where
commits previously went through the gate but suddenly don’t.
Pre-Commit Hook (.githooks/pre-commit)
Token-gated reflection gate. On the first commit attempt the hook prints a one-time token and rejects; re-commit with the token:
PRECOMMIT_TOKEN=<token> git commit -m "feat: add feature"
The token is a single-use attestation + speed-bump that forces a pause — it is
NOT machine proof the checklist was worked; honesty is on the author. The hook
also greps SPDX headers on staged .rs files (the machine-checked item). The
reflection protocol agents work (J1–J8 / R1–R5, plus the fresh-subagent
meta-protocol) is the pre-commit-token-protocol rule in .claude/rules/.
Commit-Msg Hook (.githooks/commit-msg)
Validates the commit subject against the type-prefix vocabulary above
(feat / fix / chore / refactor / docs / test), an optional (scope),
and the <72-char subject rule, with carve-outs for
Merge/Revert/fixup!/squash!. Adding a type means adding it to this doc
first — it is the single source of truth.
Pre-Push Hook (.githooks/pre-push)
The sole functional-correctness gate — runs the full local test battery (CI runs only security scans + release). Specific checks are documented in testing. All must pass before push; bypassing it (or a lost exec bit) merges unvalidated code.
Versioning (SemVer 2.0.0)
-
MAJOR (
1.0.0): first production-ready release with stable API contracts. Incremented on breaking changes thereafter. -
MINOR (
0.2.0): new features, endpoints, or capabilities. No breaking changes. -
PATCH (
0.1.1): bug fixes, security patches, documentation-only changes.