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.

Reverts

Create a fix: issue, revert on a feature branch, follow normal MR protocol.

Multi-MR Plans

  • Only the last MR of a plan updates .claude/CLAUDE.md status 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_branch on 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.adoc under Changed or Removed.

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.

Pre-release Labels

  • -alpha — feature-incomplete, API may change, not for production.

  • -beta — feature-complete for tagged scope, API stabilizing, suitable for evaluation.

  • -rc.N — release candidate, no known issues, final validation before stable.

Tagging Protocol

  • Tags are created on main after all CI checks pass.

  • Use annotated tags: git tag -a v0.1.0 -m "description".

  • Push tags explicitly: git push origin v0.1.0.

  • Create a GitLab Release from the tag with changelog highlights.

  • Every tag must have a corresponding entry in CHANGELOG.adoc.

Edit this page · latest