Skip to content
predictable-labsPublic

About

Tools for managing git PRs built with AI

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

gait

gait logo

AI-native git workflow tooling — component-scoped commits, ordered by dependency, with semantic conflict resolution.

gait — a homophone for gate, a mashup of git and AI, and a literal description of how code should move through the repository.


The Problem

AI coding sessions break traditional git workflows. A single session produces a diff spanning multiple directories simultaneously — semantically coherent but physically wide. Left unconstrained, both humans and AI assistants revert to git add . && git commit: a single blob commit that is impossible to review, impossible to resolve when it collides with another session's changes, and a violation of the principle that commits should be atomic units of change.

gait makes the right commit behaviour the path of least resistance for both humans and AI coding assistants.

What gait does

gait reads a gait.toml file at the repo root that defines the architectural structure of the repository:

  • Layers — the horizontal technical stack (e.g. proto, contracts, api, frontend). Defines commit ordering: lower-order layers are committed first because higher layers depend on them.
  • Features — vertical business slices (e.g. auth, billing, workflow). Defines semantic context for AI.

Every file in the repo belongs to exactly one layer and zero or one feature. gait uses this map to:

  1. Enforce component boundaries at commit time (pre-commit hook) — skeleton layers (cross-boundary contracts) must be committed separately from implementation changes.
  2. Decompose a wide diff into an ordered commit plan — gait decompose proposes the right sequence of commits.
  3. Stage by feature or layer — gait add <feature> or gait add --layer <layer> stages exactly the right files.
  4. Structure session-end workflows — gait session-end runs save → decompose → push.
  5. Provide an audited escape hatch — gait-override commit --reason "..." bypasses the guard and logs the reason.

Skeleton architecture

gait's skeleton = true flag is a direct operationalization of the skeleton architecture pattern described by Patrick Farry in Working with Code Assistants: the Skeleton Architecture (InfoQ, Feb 2026).

The core insight: a codebase has two fundamentally different kinds of code.

Skeleton Tissue
What it is Cross-boundary contracts: API schemas, DB migrations, proto definitions, abstract base classes, build config Vertical feature slices: the concrete business logic that implements those contracts
Who owns it Human architect — reviewed carefully, changed rarely AI coding assistant — generated freely within the boundaries the skeleton sets
What breaks if it drifts Every other layer that depends on the contract Only the feature being changed
Review standard Separate PR, peer approval Normal feature review

Farry's summary: "Vertical slices give the AI focus, the skeleton gives the human control."

How gait maps to this:

  • Features ([[features]]) are the vertical slices — they scope each AI coding session to a coherent unit of business logic.
  • Skeleton layers (skeleton = true) are the skeleton — they mark the cross-boundary contracts that the AI should not silently modify.

When an AI session touches both a skeleton layer and tissue layers, gait decompose splits them into separate, ordered commits. The pre-commit hook blocks mixed commits outright. This transforms the architectural governance from a code-review suggestion into a physical constraint baked into the git workflow.

Installation

pip install gait

Then, in your repo root, run:

gait install

This installs:

  • A shell function that intercepts git add/commit/push and prompts you to use gait instead
  • A pre-commit hook that enforces skeleton layer separation

Quick start

  1. Create a gait.toml at your repo root (see gait.toml.example).
  2. Run gait install.
  3. Use gait status to see your working tree organised by feature × layer.
$ gait status

  feature         layer       files
  ─────────────── ─────────── ──────────────────────────────
  auth            backend     src/auth/jwt.py  +74 -12
  auth            api         api/src/auth/handler.py  +42 -0
  auth            frontend    web/src/features/auth/LoginPage.tsx  +88 -3
  billing         contracts   api/schemas/invoice.json  +15 -2  [skeleton ⚠]
  billing         backend     src/billing/invoice.py  +33 -0

The [skeleton ⚠] flag tells you the billing/contracts change must ship in its own commit — gait will block a mixed commit at the pre-commit hook.

Commands

Command Description
gait status Show changed files by feature × layer
gait add <feature> Stage a feature's files
gait add --layer <layer> Stage a layer's files
gait commit -m <msg> Commit with skeleton guard
gait commit-all Stage + commit every decompose group in order
gait decompose Propose ordered commit plan
gait checkpoint Save a local snapshot before a major AI transformation
gait save Push all changes to shadow wip branch
gait sync Pull trunk into current branch (rebase, no push)
gait push Rebase on trunk and push
gait session-start Pull trunk, assert clean tree
gait session-end save → decompose instructions → push
gait reconcile <A> <B> Build AI-assisted conflict workspace
gait install Install shell functions + pre-commit hook
gait-override commit --reason <reason> Bypass skeleton guard (audited)

gait.toml

See gait.toml.example for a fully annotated template.

The example below shows a realistic fullstack SaaS service. Three skeleton layers (proto, contracts, config) form the cross-cutting contracts that must be committed separately and reviewed carefully. Everything else is implementation.

[gait]
version     = "1"
repo        = "my-service"
trunk       = "main"
release     = "main"
tag_pattern = "v*"

# ── Skeleton: gRPC definitions ────────────────────────────────────────────────
[[layers]]
name     = "proto"
order    = 1
skeleton = true
paths    = ["proto/", "api/proto/"]

# ── Skeleton: auto-generated stubs (derived from proto, do not edit) ──────────
[[layers]]
name      = "generated"
order     = 2
generated = true
paths     = ["src/generated/", "client/src/generated/"]

# ── Skeleton: API schema + DB migrations ─────────────────────────────────────
[[layers]]
name     = "contracts"
order    = 3
skeleton = true
paths    = ["api/openapi.yaml", "api/schemas/", "db/migrations/"]

# ── Skeleton: build graph config ─────────────────────────────────────────────
[[layers]]
name     = "config"
order    = 4
skeleton = true
paths    = [
  "pyproject.toml", "Cargo.toml", "Cargo.lock",
  "package.json", "package-lock.json",
  "docker-compose.yml", "Justfile",
]

# ── Implementation layers (ordered by dependency) ─────────────────────────────
[[layers]]
name  = "backend"
order = 5
paths = ["src/"]

[[layers]]
name  = "db-seed"
order = 6
paths = ["db/seed/", "db/fixtures/"]

[[layers]]
name  = "api"
order = 7
paths = ["api/src/"]

[[layers]]
name  = "clients"
order = 8
paths = ["client/", "sdk/"]

[[layers]]
name  = "frontend"
order = 9
paths = ["web/src/"]

[[layers]]
name  = "tests"
order = 10
paths = ["tests/", "e2e/"]

[[layers]]
name  = "docs"
order = 11
paths = ["docs/", "README.md", "CLAUDE.md"]

# ── Features ─────────────────────────────────────────────────────────────────
[[features]]
name  = "auth"
paths = [
  "src/auth/", "api/src/auth/",
  "web/src/features/auth/", "api/schemas/auth",
]

[[features]]
name  = "billing"
paths = [
  "src/billing/", "api/src/billing/",
  "web/src/features/billing/", "db/migrations/billing_",
]

[[features]]
name  = "notifications"
paths = ["src/notifications/", "api/src/notifications/", "web/src/features/notifications/"]

[[features]]
name  = "admin"
paths = ["src/admin/", "api/src/admin/", "web/src/features/admin/"]

When you run gait decompose on a wide AI diff, gait uses this map to propose commits in dependency order — skeleton changes first, then implementation layers, each labelled with its feature:

$ gait decompose

  Proposed commit order:

  1  [proto]     auth    proto/auth.proto  +24 -0         ← skeleton, review carefully
  2  [contracts] auth    api/schemas/auth_token.json +12  ← skeleton, review carefully
  3  [backend]   auth    src/auth/jwt.py  src/auth/oidc.py  +180 -5
  4  [api]       auth    api/src/auth/handler.py  +95 -2
  5  [frontend]  auth    web/src/features/auth/LoginPage.tsx  +210 -8
  6  [tests]     auth    tests/test_auth.py  +66 -0

Requirements

  • Python 3.11+
  • git
  • No external Python dependencies — uses only the standard library

License

MIT — see LICENSE.

About

Tools for managing git PRs built with AI

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages