# Commit

> [Git] Use when asked to "commit", "stage and commit", "save changes", or after completing implementation tasks. Flag: --push (a.k.a. "commit and push") stages + commits + pushes to remote in one shot.

- Skill: `duc01226/commit` (Agent Skill)
- Install (CLI): `npx skillmds@latest add duc01226/commit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/duc01226/commit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: duc01226 (https://skillmd.com/u/duc01226)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/duc01226/commit

---


> Codex compatibility note:
>
> - Invoke repository skills with `$skill-name` in Codex; this mirrored copy rewrites legacy Claude `/skill-name` references.
> - Task tracker mandate: BEFORE executing any workflow or skill step, create/update task tracking for all steps and keep it synchronized as progress changes.
> - User-question prompts mean to ask the user directly in Codex.
> - Ignore Claude-specific mode-switch instructions when they appear.
> - Strict execution contract: when a user explicitly invokes a skill, execute that skill protocol as written.
> - Subagent authorization: when a skill is user-invoked or AI-detected and its protocol requires subagents, that skill activation authorizes use of the required `spawn_agent` subagent(s) for that task.
> - Do not skip, reorder, or merge protocol steps unless the user explicitly approves the deviation first.
> - For workflow skills, execute each listed child-skill step explicitly and report step-by-step evidence.
> - If a required step/tool cannot run in this environment, stop and ask the user before adapting.

<!-- CODEX:PROJECT-REFERENCE-LOADING:START -->

## Codex Project-Reference Loading (No Hooks)

Codex uses static project-reference loading instead of runtime-injected project docs.
When coding, planning, debugging, testing, or reviewing, open project docs explicitly using this routing.

**Always read:**

- `docs/project-config.json` (project-specific paths, commands, modules, and workflow/test settings)
- `docs/project-reference/docs-index-reference.md` (routes to the full `docs/project-reference/*` catalog)
- `docs/project-reference/lessons.md` (always-on guardrails and anti-patterns)

**Missing/stale context route:** If `docs/project-config.json`, the docs index, `lessons.md`, `CLAUDE.md`, `AGENTS.md`, or any task-required reference doc is missing or stale, auto-run `$project-init` or the narrow setup route (`$project-config`, `$docs-init`, `$scan-all`, `$scan --target=<key>`, `$claude-md-init`) before ordinary project-specific work. If Codex mirrors or `AGENTS.md` are missing/stale, ask the user to run `$sync-codex`; do not auto-run it.

**Situation-based docs:**

- Project structure/architecture/tech-stack/deployment/setup (any layer — backend, frontend, or infra): `project-structure-reference.md`
- Backend/CQRS/API/domain/entity changes: `backend-patterns-reference.md`, `domain-entities-reference.md`
- Frontend/UI/styling/design-system: `frontend-patterns-reference.md`, `scss-styling-guide.md`, `design-system/README.md`
- Spec authoring, `docs/specs/` pathing, or TC format: `feature-spec-reference.md`, `spec-system-reference.md`, `spec-principles.md`
- Behavior/public-contract changes or spec-test-code sync: `workflow-spec-test-code-cycle-reference.md` plus the spec docs above
- Derived spec indexes/ERDs/reimplementation guides: `spec-system-reference.md` and source Feature Specs under `docs/specs/`
- Integration test implementation/review: `integration-test-reference.md`
- E2E test implementation/review: `e2e-test-reference.md`
- Code review/audit work: `code-review-rules.md` plus domain docs above based on changed files

Do not read all docs blindly. Start from `docs-index-reference.md`, then open only relevant files for the task.

<!-- CODEX:PROJECT-REFERENCE-LOADING:END -->

## Quick Summary

**Goal:** Stage changes and create well-structured git commits following Conventional Commits format — and, when code changed, gate the commit on a user decision to verify (via `$workflow-integration-test-green`, which drives the suite to green), confirm already-verified, or explicitly skip (default: verify first). Every commit message body OPENS with a mandatory `Estimate:` line carrying the derived story points and AI man-days for that staged diff.

**Summary:** (read-this-if-nothing-else digest — purpose + ALL main steps + gates)

- **PURPOSE** — produce a commit whose message a future reader can act on WITHOUT opening the diff: conventional subject, an `Estimate:` first body line, a purpose→what→how body, and a per-area Reviewers block. Three things are computed BEFORE the message exists (reviewers, estimate, doc triage) because they must live INSIDE it.
- **STEP 0 — BYPASS MARKER.** Create `tmp/claude-temp/.commit-skill-active` before any `git add`/`git commit`, and **ALWAYS remove it afterwards** — success or failure.
- **STEP 1-2 — ANALYZE + STAGE.** `git status` / `git diff --cached` / `git diff` / `git log --oneline -5`, then stage.
- **STEP 2.5 — DOCS TRIAGE.** Staged files matching doc-impact patterns → run `$docs-update`, re-stage the doc changes.
- **STEP 2.7 — IDENTIFY REVIEWERS** (pre-commit, read-only): last author per staged file vs `HEAD`, commit author EXCLUDED, grouped BY AREA with the focus each owns.
- **STEP 2.9 — DERIVE THE ESTIMATE** via the carried `SYNC:estimation-framework` against the STAGED diff (or reuse the implemented plan/PBI/story frontmatter with `(source: <path>)`). SP is DERIVED from `likely_days`, never eyeballed; discount generated/lockfile/docs churn first.
- **STEP 3 — GENERATE MESSAGE.** Subject `type(scope): description`; body OPENS with the Estimate line, then purpose/kind → what changed → how it works, then the Reviewers block.
- **STEP 3.5 — TEST-VERIFY GATE (BLOCKING when code changed).** ask the user directly, default **verify** via `$workflow-integration-test-green`. Only an explicit **Yes — already verified** or **Skip** proceeds; NEVER choose skip on the user's behalf. If the gate mutates the staged set, **re-stage AND re-derive the estimate**.
- **STEP 4 — COMMIT** with the HEREDOC form (subject → blank → Estimate → body → Reviewers → footer).
- **STEP 5 — VERIFY** via `git status` + `git log`; confirm the first body line IS the Estimate line, then re-present the reviewer assignment.
- **STEP 6 — REFRESH THE CODE GRAPH (post-commit, BACKGROUND, non-blocking).** Only when `.code-graph/` exists: fire `$graph-build --scope=sync` in the background so the commit that just moved HEAD is re-parsed AND the graph's `last_synced_commit` advances with it. NEVER blocks or gates the commit; a failure is reported, never retried inline.
- **FLAG** — `--push` (a.k.a. "commit and push") stages + commits + pushes via `git-manager`. Without it: **STOP after the commit**; NEVER push unprompted.

**Workflow:**

1. **Analyze Changes** — Run git status/diff to understand staged and unstaged changes
2. **Stage Changes** — Add relevant files (specific or all)
3. **Identify Reviewers** — from git history, list relevant reviewers (last author per touched file vs `HEAD`, excluding the commit author) and the area each must focus on — computed BEFORE the commit so the block can be embedded in the message body
4. **Derive Estimate** — Apply the carried `SYNC:estimation-framework` to the staged diff (or reuse the frontmatter of the plan/PBI/story this commit implements) to derive `story_points` + `man_days_ai` — computed BEFORE the message so the numbers can head the body
5. **Generate Message** — Detect type (feat/fix/refactor/etc.), extract scope from paths, write subject, open the body with the **Estimate** line from step 4, add a detailed body structured as **purpose/kind → what changed → how it works**, and append the **Reviewers** block from step 3
6. **Test-Verify Gate** — When staged changes include code that might need tests, ask the user (ask the user directly, default **verify**) to verify via `$workflow-integration-test-green`, confirm **Yes — already verified**, or explicitly **Skip**. Default = verify first, and verify means drive the suite to green, not merely report it
7. **Commit** — Create commit with HEREDOC (title + Estimate line + detailed summary + Reviewers block + attribution footer)
8. **Verify** — Confirm with git status and git log

**Key Rules:**

- **Stamp the estimate on the FIRST body line** — every commit message opens its body with `Estimate: <n> SP | man_days_ai: <x>d | man_days_traditional: <y>d`. Story points and AI man-days are MANDATORY and DERIVED bottom-up per the carried `SYNC:estimation-framework` (or reused from the plan/PBI/story frontmatter this commit implements); the number describes THIS staged diff only
- Write a detailed body — **purpose/kind → what changed → how it works** — so the next human reading `git log`/`git blame` understands the change without opening the diff. As detailed as the change needs (wrap ~72 chars); no title-only commits for non-trivial changes
- Embed a **Reviewers** block in the commit message — the per-area reviewers (last author per touched file vs `HEAD`, commit author excluded) — computed BEFORE committing so it lives in the message body, not just as a side report
- When staged changes include code that might need tests, **gate the commit on test verification** — ask the user to verify via `$workflow-integration-test-green` (default), confirm already-verified, or explicitly skip; only an explicit **Yes** or **Skip** proceeds straight to commit, and the agent NEVER chooses skip on the user's behalf
- Stop after the commit; push only when the user explicitly requests it (or passes `--push` / says "commit and push" → stage + commit + push via `git-manager`)
- Never commit secrets, credentials, or .env files
- Never use `--amend` or `--no-verify` unless explicitly requested
- Include `Generated with [Claude Code]` attribution footer

**Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence percentages (Idea should be more than 80%).**

# Git Commit Skill

Stage changes and create well-structured git commits following Conventional Commits format.

## IMPORTANT: Bypass git-commit-block Hook

Before running any `git add` or `git commit` commands, create the marker file to bypass the `git-commit-block` hook:

```bash
PROJ=$(git rev-parse --show-toplevel) && mkdir -p "$PROJ/tmp/claude-temp" && touch "$PROJ/tmp/claude-temp/.commit-skill-active"
```

After committing (success or failure), **always** clean up the marker:

```bash
rm -f "$(git rev-parse --show-toplevel)/tmp/claude-temp/.commit-skill-active"
```

## Workflow

### Step 1: Analyze Changes

```bash
# Check current status (never use -uall flag)
git status

# See staged changes
git diff --cached

# See unstaged changes
git diff

# Check recent commit style
git log --oneline -5
```

### Step 2: Stage Changes

```bash
# Stage all changes
git add .

# Or stage specific files
git add <file-path>
```

### Step 2.5: Docs-Update Triage

Before committing, check if staged files impact documentation:

1. Run `git diff --name-only --cached` to list staged files
2. Check if any staged file matches doc-impact patterns (resolve the concrete backend/frontend source paths from the project's structure reference / `docs/project-config.json`):
    - changes under the backend service source paths (per project config) → may impact `docs/specs/`
    - `.claude/skills/**` → may impact `.claude/docs/skills/`
    - `.claude/hooks/**` → may impact `.claude/docs/hooks/`
    - `.claude/workflows.json` → may impact `CLAUDE.md` workflow table
    - changes under the frontend app source paths (per project config) → may impact frontend pattern docs
3. If matches found: invoke `$docs-update` skill, then re-stage any doc changes with `git add`
4. If no matches: skip (log "No doc-impacting files staged")

> `$docs-update`'s Phase 1 already runs `$prompt-enhance <doc>` on every `docs/project-reference/**` doc it PATCHES (see `docs-update` Step 1.3), keeping the doc concise yet AI-valuable before commit re-stages it — do not invoke `$prompt-enhance` again here.

### Step 2.7: Identify Reviewers (pre-commit — feeds the message)

Runs **BEFORE** the commit so the result can be embedded in the commit message body (see Step 3). Read-only (git log/blame only) — it NEVER blocks the commit and never messages anyone.

For each **staged** file, find the **LAST author who touched it** (against `HEAD`, the soon-to-be parent) — that author is the natural reviewer for the area.

Rules:

- **EXCLUDE the commit author** from the "ask to review" list (you don't ask yourself to review) — but still surface files where the author is the only prior toucher as **author-owned, no external reviewer**.
- **Brand-new files (no prior history)** → mark `NEW FILE — reviewer = owner of its source/sibling file`.
- **GROUP reviewers by change AREA** (which feature/subsystem each owns) and state WHICH AREA each must focus on — not a flat name list.
- Fetch each reviewer's email for tagging.

Collect the raw last-author-per-staged-file data:

```bash
# Staged files in this pending commit
git diff --cached --name-only \
  | while read -r f; do
      author=$(git log -1 --format='%an' HEAD -- "$f" 2>/dev/null)
      email=$(git log -1 --format='%ae' HEAD -- "$f" 2>/dev/null)
      date=$(git log -1 --format='%ad' --date=short HEAD -- "$f" 2>/dev/null)
      [ -z "$author" ] && author="(NEW FILE — reviewer = source/sibling owner)" && date="-"
      printf '%s\t%s\t%s\t%s\n' "$author" "$email" "$date" "$f"
    done
```

Then: collapse by author, map each author's files to the change area, drop the commit author, and render the **Reviewers** block to embed in the commit message (Step 3) and to present to the user:

| Reviewer | Email | Focus area | Files |
| -------- | ----- | ---------- | ----- |

Follow the table with a short **recommended review assignment by feature** list (area → reviewer). The skill does NOT auto-message anyone — this is the user's deliverable.

### Step 2.9: Derive the Estimate (pre-commit — feeds the message)

Runs **BEFORE** the commit so `story_points` and `man_days_ai` can head the message body (Step 3). Apply the **`SYNC:estimation-framework`** block this skill carries (see below) to the **OBSERVED staged scope** — post-hoc, with full diff visibility.

**Source of the numbers — prefer an approved artifact over a fresh guess:**

| Situation                                                                          | Source of `story_points` / `man_days_ai`                                                  |
| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Commit implements a plan / PBI / story whose frontmatter already carries estimates | REUSE its `story_points` + `man_days_ai`; append `(source: <path>)` to the Estimate line  |
| Commit is a PARTIAL slice of such an artifact                                      | Derive the slice bottom-up — NEVER copy the whole artifact's number onto a partial commit |
| No estimate artifact exists                                                        | Derive bottom-up from the staged diff per the framework                                   |

**Derivation (bottom-up — SP is DERIVED, never eyeballed):**

1. **Blast-radius pass** on `git diff --cached --stat` — touched areas, complex files (>500 LOC / central / multi-handler), downstream consumers, shared/common code.
2. Sum the **Reuse-vs-Create** tiers across UI + backend + tests → `bottom_up_hours`.
3. `likely_days = ceil(bottom_up_hours / 6) × productivity_factor`.
4. `story_points` = closest **SP→Days** bucket. Disagreement >50% → trust bottom-up and downgrade SP.
5. `man_days_ai` = the AI likely column for that SP (1≈0.25d · 2≈0.35d · 3≈0.65d · 5≈1.0d · 8≈1.5d · 13≈2.0d), reconciled against the bottom-up result; it already includes the 30% review overhead.
6. `man_days_traditional` = the no-AI likely column (1≈0.5d · 2≈1d · 3≈2d · 5≈4d · 8≈6d · 13≈10d), same reconciliation.

**Anti-inflation (discount BEFORE estimating — same guardrail `$git-developer-performance` applies):** generated code, lockfiles, ORM/designer snapshots, i18n re-sorting, bulk reformatting, and pure docs/spec churn earn **no** story points. A 4 000-line lockfile bump is 1 SP, not 8.

**Scope of the number:** the estimate describes **THIS commit's staged diff only** — not the branch, not the whole feature it belongs to. A `--push` run does not change this.

> **Never block on the estimate.** It is derived from evidence already on disk (the staged diff), so it never asks the user and never gates the commit. If the diff is genuinely unestimable (e.g. a pure merge commit with no resolved content), emit `Estimate: 0 SP | man_days_ai: 0d — integration only, no authored change` rather than omitting the line.

### Step 3: Generate Commit Message

Analyze staged changes and generate message following **Conventional Commits**:

```
<type>(<scope>): <subject>

Estimate: <story_points> SP | man_days_ai: <x>d | man_days_traditional: <y>d

<detailed summary of changes>

Reviewers:
- <area>: <Reviewer Name> <email> — focus on <what they own>
```

#### Type Detection

| Change Pattern          | Type       |
| ----------------------- | ---------- |
| New file/feature        | `feat`     |
| Bug fix, error handling | `fix`      |
| Code restructure        | `refactor` |
| Documentation only      | `docs`     |
| Tests only              | `test`     |
| Dependencies, config    | `chore`    |
| Performance improvement | `perf`     |
| Formatting only         | `style`    |

#### Scope Rules

Extract from file paths:

- `{configured-source-root}/auth/` → `auth`
- `.claude/skills/` → `claude-skills`
- `libs/{shared-lib}/` → `{shared-lib}`
- Multiple unrelated areas → omit scope

#### Subject Rules

- Imperative mood ("add" not "added")
- Lowercase start
- No period at end
- Max 50 characters

#### Estimate Line (MANDATORY — the FIRST line of the body)

```
Estimate: <story_points> SP | man_days_ai: <x>d | man_days_traditional: <y>d
```

- Placed **immediately after the blank line that follows the subject** — above purpose/what/how. NEVER in the footer, NEVER folded into the subject (the subject stays imperative, lowercase, ≤50 chars per Conventional Commits), NEVER omitted.
- `story_points` — Fibonacci `1 | 2 | 3 | 5 | 8 | 13 | 21`, DERIVED per Step 2.9. **Required.** `0` is the ONE value outside that set, reserved for the unestimable case Step 2.9 names (a pure merge/integration commit with no authored content) — NEVER as a rounding-down of real work.
- `man_days_ai` — AI-assisted man-days for this staged diff (Claude Code + project context, review overhead included). **Required.**
- `man_days_traditional` — the no-AI baseline (3–5yr dev, 6 productive hrs/day). **Recommended** — include it whenever derived — why: alone, `man_days_ai` is an absolute figure nobody can calibrate, while the pair makes the AI leverage on THIS diff readable straight from `git log`. Written for a human reader: `$git-developer-performance` derives its own numbers from the diff rather than reading this line (its `git log` format stops at `%s` — `.claude/skills/git-developer-performance/scripts/git-developer-performance.cjs:290`), so the pair earns its place by what a person reads, not by what a tool consumes.
- **Ranges** are allowed and preferred once `likely_days ≥3`: `man_days_ai: 1.0-1.5d | man_days_traditional: 4-6d`.
- Append ` (source: <path>)` when the numbers were REUSED from a plan/PBI/story frontmatter instead of derived from the diff.
- SP ≥13 on a single commit → the commit is doing too much; say so in the body ("SHOULD have been split") rather than quietly shipping the number.

#### Body Rules (MANDATORY) — write so a human understands fastest

> Body is the deliverable. Optimize for the next person running `git log` / `git blame` — they understand the change **without opening the diff**. As detailed as the change needs; no artificial brevity limit — wrap ~72 chars, stop once nothing new said. Title-only commit FORBIDDEN for any non-trivial change. — why: the diff shows WHAT; the body must carry WHY + HOW, which the diff cannot.

Three parts (omit one only when genuinely empty):

1. **Purpose / kind** — name the kind AND why it exists: feature · bug fix (state the symptom removed) · enhancement · refactor (state behaviour-preserving) · perf · security · chore. 1–2 sentences answering _"what problem does this solve?"_.
2. **What changed** — concrete edits grouped by **behaviour**, never by file. Each bullet specific — NEVER "update code", "fix stuff", "minor fixes".
3. **How it works / why this way** — the part reviewers need: mechanism, key logic, invariants relied on, edge cases preserved, and any non-obvious decision ("did X instead of obvious Y because Z"). Focus the non-obvious; NEVER narrate boilerplate. Ordering/timing/security invariant or subtle failure mode → call it out explicitly.

> **Teach-the-reader mindset (from the `understand` skill):** cover BOTH high-level motivation (why it matters) AND low-level logic (business rules, edge cases). Surface what a reader would NOT guess from the diff — write the explanation you would want to receive.

**Detail dial — scale body to the change:**

| Change size                         | Body depth                                                                                                          |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Trivial (typo, rename, formatting)  | Purpose line + 1 bullet; skip "how it works"                                                                        |
| Normal (feature/fix, single area)   | Purpose + 2–5 "what" bullets + a short "how it works"                                                               |
| Complex (cross-cutting, subtle bug) | Purpose + grouped "what" + a full "how it works" that spells out the key invariant / edge case / why-this-over-that |

### Step 3.5: Test-Verify Gate (blocking — only when code changed)

Decide whether the staged changes carry **code that might need tests** — why: this gate is the only thing standing between an untested behaviour change and permanent history.

**Trigger detection** — run `git diff --cached --name-only` and classify the staged files:

- **Code that might need tests** → any change to production/source code: backend service source, frontend app source, shared libraries, scripts, hooks (`.cjs`), or other executable logic (resolve concrete source roots from `docs/project-config.json` / the project structure reference).
- **NOT a trigger (skip the gate)** → the staged set is _only_ docs (`docs/**`, `*.md`), specs (`docs/specs/**`), test-spec/config text, changelog, or other non-executable content with no source-code change.

**If the gate is NOT triggered:** log `Test-Verify Gate: skipped (no code changes staged)` and continue to Step 4.

**If the gate IS triggered:** STOP and ask the user with ask the user directly (default option is **No**):

> Header: `Test verify`
> Question: `Staged code changes may need tests. Verify before committing, or skip?`
> Options (in order — first is the default):
>
> 1. `Verify now — run $workflow-integration-test-green` (Recommended) — do NOT commit yet; activate the `workflow-integration-test-green` workflow, which verifies the suite AND drives any failure to green (verify → adjudicate → fix → review → re-verify) before returning. Proceed to Step 4 only once the whole suite is green; if it escalates instead of converging, surface that and stop (no commit).
> 2. `Yes — already verified` — the user confirms the integration tests were run and passed; proceed directly to Step 4 (Commit).
> 3. `Skip — commit without verifying` — the user's explicit, recorded decision to commit unverified code; proceed to Step 4 and note `Test-Verify Gate: skipped by user` in the response (never in the commit message).

Rules:

- **Default is option 1 (verify).** If the user does not actively choose "Yes" or "Skip", treat it as verify-first — never commit unverified code on assumption.
- **Verify routes to `workflow-integration-test-green`, not to a bare verify run** — why: a bare `integration-test-verify` only reports the failures, leaving the user to hand-carry each one; the workflow owns the converge-to-green loop, so choosing "verify" actually clears the suite instead of just describing it.
- **Yes is an explicit user assertion** that the integration tests were run and passed; honour it and commit.
- **Skip is the user's call, and it is theirs alone to make.** Offer it, never recommend it, and NEVER select it yourself — why: an agent that can skip its own gate has no gate.
- Re-run this gate only once per commit; after a `verify → green`, proceed to commit without re-asking.
- **If the verify branch changed ANY file, re-stage and RE-DERIVE before Step 4.** Option 1 can land test or source fixes AFTER Step 2.9 already ran, so the diff the estimate described is no longer the diff being committed. Mirror Step 2.5: re-stage the new changes with `git add`, then re-run Step 2.9 over the updated `git diff --cached` and put the fresh numbers in the message. Options 2 and 3 mutate nothing, so the original Step 2.9 numbers stand.
- This gate is independent of `--push`: it runs before the commit in every mode.

### Step 4: Commit

Use HEREDOC for proper formatting:

```bash
git commit -m "$(cat <<'EOF'
type(scope): subject

Estimate: 3 SP | man_days_ai: 0.65d | man_days_traditional: 2d

- summarize key change 1 with intent
- summarize key change 2 with impact

Reviewers:
- <area>: Reviewer Name <reviewer@email> — focus on <what they own>

Generated by AI
EOF
)"
```

> The **Estimate** line comes from Step 2.9 — re-derived after Step 3.5 if that gate changed the staged set — and is ALWAYS the first line of the body.
> The **Reviewers** block comes from Step 2.7 (last author per staged file vs `HEAD`, commit author excluded, grouped by area). Omit the block only when every staged file is brand-new or author-owned with no external reviewer — in that case state `Reviewers: none (author-owned / new files)`.

### Step 5: Verify

```bash
git status
git log -1
```

Confirm the committed body's FIRST line IS the **Estimate** line from Step 2.9 (`Estimate: <n> SP | man_days_ai: <x>d …`) — missing → the message is non-conformant; re-derive and record it, NEVER leave it out. Then confirm the body carries the **Reviewers** block from Step 2.7 (or the explicit `Reviewers: none (author-owned / new files)` line). Re-present the per-area reviewer assignment to the user as the final deliverable — why: they need it to request the right reviewers on the resulting PR.

### Step 6: Refresh Code Graph (post-commit — background, non-blocking)

**Skip entirely (silently) when `.code-graph/` does not exist** — the project has no knowledge graph and there is nothing to refresh.

When it does exist, fire `$graph-build --scope=sync` **in the background** immediately after Step 5 verifies the commit — one Bash call with `run_in_background: true`, so the commit never waits on it:

```bash
if [ -d ".code-graph" ]; then python .claude/scripts/code_graph sync --json; fi
```

- **Why after the commit, not before:** a commit MOVES `HEAD`. `sync` diffs the graph's stored `last_synced_commit` against the current `HEAD`, so running it AFTER `git commit` re-parses exactly the files this commit introduced. Run it before and `HEAD` has not moved yet, so there is nothing for it to see.
- **Why `sync` and not `update`:** `sync` is the HEAD-movement verb — it advances the stored `last_synced_commit` as well as the nodes. `update` only re-parses the working tree and leaves that bookkeeping pointing at the PRE-commit HEAD, which then reads as stale to `graph-prompt-sync` and forces a redundant re-sync on the next prompt. Committing is a HEAD move, so it takes the HEAD-move verb.
- **Why background:** the `graph-auto-update` PostToolUse hook only fires on `Edit|Write|MultiEdit`, so a commit leaves the graph's node set stale for any file the session did not itself edit (merges, checkouts, externally-changed files) — but graph freshness is an accelerator, NEVER a commit gate. It MUST NOT block, delay, or fail the commit.
- **Report** the background result briefly when it returns (files synced/added/deleted, or `up_to_date`). If it errors (Python/deps missing, lock held by a concurrent update), state the error in one line and stop — NEVER retry inline and NEVER treat it as a commit failure.

> **Safety net, not the only net.** If this step is skipped or fails, the `graph-prompt-sync` UserPromptSubmit hook detects the moved HEAD on the next prompt and syncs then. Step 6 exists so the graph is already current for the rest of THIS session, not because the commit is the only chance to catch it.

> The `--push` path pushes first, then refreshes the graph — the push is the user-visible operation and must not wait on graph work either.

## Examples

```
feat(order): add warehouse filter to list

Estimate: 3 SP | man_days_ai: 0.65d | man_days_traditional: 2d

- add warehouse query parameter in order list endpoint
- wire frontend filter control to request payload
- update tests for filtered and unfiltered list behavior

Reviewers:
- order backend: Jane Doe <jane@acme.com> — focus on the list endpoint query change
- order UI: Bob Lee <bob@acme.com> — focus on the filter control wiring

Generated by AI

fix(validation): handle empty date range

Estimate: 1 SP | man_days_ai: 0.25d | man_days_traditional: 0.5d

- guard null/empty date inputs before parsing
- return validation message instead of throwing format exception

Reviewers: none (author-owned / new files)

Generated by AI
```

## Critical Rules

- **ALWAYS stage all unstaged changes** before committing — run `git add .` (or specific files) so nothing is left behind
- **Test-Verify Gate (Step 3.5):** when staged changes include code that might need tests, ask the user to verify via `$workflow-integration-test-green` (default — it converges the suite to green), confirm already-verified, or explicitly skip; only an explicit **Yes** or user-chosen **Skip** commits without verifying, and the agent NEVER picks skip itself. Bypass the gate entirely only when the staged set is docs/specs/config with no source-code change
- **Estimate line is MANDATORY and comes FIRST in the body** — `Estimate: <n> SP | man_days_ai: <x>d | man_days_traditional: <y>d`, derived bottom-up per the carried `SYNC:estimation-framework` against the STAGED diff (Step 2.9), or reused from the implemented plan/PBI/story frontmatter with `(source: <path>)`. Story points and AI man-days are required; discount generated/lockfile/docs churn before estimating
- **Stop after the commit; push** to remote only when the user explicitly requests it
- **Refresh the code graph after committing (Step 6)** — when `.code-graph/` exists, fire `$graph-build --scope=sync` in the BACKGROUND (`run_in_background: true`) so the commit that moved HEAD is re-parsed and `last_synced_commit` advances with it; skip silently when the dir is absent. Non-blocking by design: it NEVER gates, delays, or fails the commit
- **Review staged changes** before committing
- **Never commit** secrets, credentials, or .env files
- **Never use** `git commit --amend` unless explicitly requested AND the commit was created in this session AND not yet pushed
- **Never skip** hooks with `--no-verify` unless explicitly requested
- Commit message MUST include a Conventional Commit title AND a detailed body — **purpose/kind → what changed → how it works**. As detailed as the change needs (wrap ~72 chars); title-only commit FORBIDDEN for non-trivial changes
- Optimize body for the next human reading `git log` / `git blame` — surface the non-obvious (key logic, invariants, edge cases, why-this-over-that), not just a list of touched files
- Include attribution footer: `Generated by AI`
- **Embed reviewers in the commit message** — BEFORE committing (Step 2.7), surface the last author per staged file vs `HEAD` (exclude the commit author), grouped by focus area, and write it as a `Reviewers:` block in the message body so the right reviewers travel with the commit/PR. Read-only; never blocks the commit.

## Push & PR Operations

**Arg `--push` (a.k.a. "commit and push"):** stage + commit + push in one shot — spawn `git-manager` immediately after committing. The former standalone stage-commit-push entry point, folded in; it adds no logic beyond the push delegation below.

This skill handles **commit** by default. Push-to-remote and PR creation delegate to the `git-manager` sub-agent (`agent_type: "git-manager"`), which enforces conventional-commit validation, prevents `--no-verify` bypass, and creates PRs with structured summaries.

Spawn `git-manager` after committing when the user says "push", "create PR", or "open PR".

## Sub-Agent Type Override

> **MANDATORY:** Push and PR operations spawn `git-manager` sub-agent (`agent_type: "git-manager"`), NOT the main agent.
> **Rationale:** `git-manager` enforces conventional commits, prevents hook bypasses, and handles PR creation with structured summaries.

## Related

- `changelog`
- `branch-comparison`

---

> **[IMPORTANT]** Use task tracking to break ALL work into small tasks BEFORE starting — including tasks for each file read. This prevents context loss from long files. For simple tasks, AI MUST ATTENTION ask user whether to skip.

<!-- SYNC:sub-agent-selection -->

> **Sub-Agent Selection** — Full routing contract: `.claude/skills/shared/sub-agent-selection-guide.md`
> **Rule:** Route specialized domains (architecture, security, performance, DB, E2E, integration-test, git) to the matching specialist agent (see guide above) — NEVER use `code-reviewer` for these. — why: `code-reviewer` lacks each domain's checklist, so specialized issues slip through.

<!-- /SYNC:sub-agent-selection -->

<!-- SYNC:ai-mistake-prevention -->

> **AI Mistake Prevention** — Failure modes to avoid on every task:
>
> **Re-read files after context changes.** Context compaction, resume, or long-running work can make memory stale; verify current files before acting.
> **Verify generated content against source evidence.** AI hallucinates APIs, names, claims, and document facts. Check the relevant source before documenting or referencing.
> **Check downstream references before deleting or renaming.** Removing an artifact can stale docs, generated mirrors, configs, and callers; map references first.
> **Trace the full impact chain after edits.** Changing a definition can miss derived outputs and consumers. Follow the affected chain before declaring done.
> **Verify ALL affected outputs, not just the first.** One green check is not all green checks; validate every output surface the change can affect.
> **Assume existing values are intentional — ask WHY before changing OR flagging one as a defect.** Before changing or reporting a constant, limit, flag, cutoff, wording, or pattern, read nearby context and history, the CALLER's ordering, and 2+ sibling call sites of the same convention. A doc stating WHAT without WHY is missing rationale, not proof of a missing guard.
> **Surface ambiguity before acting — don't pick silently.** Multiple valid interpretations require an explicit question or stated assumption with risk.
> **Assert the outcome your system owns, not the intermediate state your infrastructure owns.** When verifying async work, assert the final business state — never the delivery/retry bookkeeping held in shared infrastructure that any co-running process can write. Such a check passes when run alone and flakes the moment anything else shares that infrastructure.
> **Keep shared guidance role-relevant.** Universal guidance must help every receiving skill or agent; code-specific obligations belong only in code-specific protocols.

<!-- /SYNC:ai-mistake-prevention -->

<!-- SYNC:estimation-framework -->

> **Estimation Framework** — Bottom-up first; SP DERIVED; output min-max range when likely ≥3d. Stack-agnostic. Baseline: 3-5yr dev, 6 productive hrs/day. AI estimate assumes Claude Code + project context.
>
> **Method:**
>
> 1. **Blast Radius pass** (below) — drives code AND test cost
> 2. Decompose phases → hours/phase → `bottom_up_hours = Σ phase_hours`
> 3. `likely_days = ceil(bottom_up_hours / 6) × productivity_factor`
> 4. Sum **Risk Margin** (base + add-ons) → `max_days = likely_days × (1 + margin)`
> 5. `min_days = likely_days × 0.9`
> 6. Output as range when `likely_days ≥3`; single point allowed `<3` (still record margin)
> 7. `man_days_ai` = same range × AI speedup
> 8. `story_points` DERIVED from `likely_days` via SP-Days — NEVER driver. Disagreement >50% → trust bottom-up
>
> **Productivity factor:** 0.8 strong scaffolding+codegen+AI hooks · 1.0 mature default · 1.2 weak patterns · 1.5 greenfield
>
> **Cost Driver Heuristic (apply BEFORE work-type row):**
>
> - **UI dominates** in CRUD/business apps — 1.5-3x backend (states, validation, responsive, a11y, polish)
> - **Backend dominates ONLY:** multi-aggregate invariants, cross-service contracts, schema migrations, heavy query/perf, new event flows
>
> **Reuse-vs-Create axis (PRIMARY lever, per layer):**
>
> | UI tier                                      | Cost     |
> | -------------------------------------------- | -------- |
> | Reuse component on existing screen           | 0.1-0.3d |
> | Add control/column to existing screen        | 0.3-0.8d |
> | Compose components into NEW screen           | 1-2d     |
> | NEW screen, custom layout/states/validation  | 2-4d     |
> | NEW shared/common component (themed, tested) | 3-6d+    |
>
> | Backend tier                                         | Cost      |
> | ---------------------------------------------------- | --------- |
> | Reuse query/handler from new place                   | 0.1-0.3d  |
> | Small update existing handler/entity                 | 0.3-0.8d  |
> | NEW query on existing repo/model                     | 0.5-1d    |
> | NEW command/handler on existing aggregate (additive) | 1-2d      |
> | NEW aggregate/entity (repo, validation, events)      | 2-4d      |
> | NEW cross-service contract OR schema migration       | 2-4d each |
> | Multi-aggregate invariant / heavy domain rule        | 3-5d      |
>
> **Rule:** Sum tiers across UI+backend+tests, apply productivity factor. Reuse short-circuits tiers — call out.
>
> **Test-Scope drivers (compute test_count EXPLICITLY — "+tests" hand-wave is #1 failure):**
>
> | Driver                            | Count                                                  |
> | --------------------------------- | ------------------------------------------------------ |
> | Happy-path journeys               | 1 per story / AC main flow                             |
> | State-machine transitions         | reachable transitions × allowed actors                 |
> | Multi-entity state combos         | state(A) × state(B) — REACHABLE only, not Cartesian    |
> | Authorization matrix              | (owner, non-owner, elevated, unauth) × each mutation   |
> | Validation rules                  | 1 per required field / boundary / format / cross-field |
> | UI states (per new screen/dialog) | happy, loading, empty, error, partial — present only   |
> | Negative paths / invariants       | 1 per violatable business rule                         |
>
> | Test tier (Trad, incl. setup+assert+flake) | Cost     |
> | ------------------------------------------ | -------- |
> | 1-5 cases, fixtures reused                 | 0.3-0.5d |
> | 6-12 cases, 1 new fixture                  | 0.5-1d   |
> | 13-25 cases, multi-entity setup            | 1-2d     |
> | 26-50 cases OR new state-machine coverage  | 2-3d     |
> | >50 cases OR full E2E journey              | 3-5d     |
>
> **Test multipliers:** new fixture/seed harness +0.5d · cross-service/bus assertion +0.3d each · UI E2E ×1.5 · each new role +1-2 cases
>
> **Blast Radius (mandatory pre-pass — affects code AND test):**
>
> 1. Files/components directly modified — count
> 2. Of those, "complex" (>500 LOC, multi-handler, central, frequently-modified) — count
> 3. Downstream consumers (callers, event subscribers, cross-service) — list
> 4. Shared/common code touched (multi-app blast) —

…(truncated)
