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 (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.
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:
- Analyze Changes — Run git status/diff to understand staged and unstaged changes
- Stage Changes — Add relevant files (specific or all)
- 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
- 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
- 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
- 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
- Commit — Create commit with HEREDOC (title + Estimate line + detailed summary + Reviewers block + attribution footer)
- 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:
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:
rm -f "$(git rev-parse --show-toplevel)/tmp/claude-temp/.commit-skill-active"
Workflow
Step 1: Analyze Changes
# 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
# 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:
- Run
git diff --name-only --cached to list staged files
- 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
- If matches found: invoke
$docs-update skill, then re-stage any doc changes with git add
- 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:
# 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):
- Blast-radius pass on
git diff --cached --stat — touched areas, complex files (>500 LOC / central / multi-handler), downstream consumers, shared/common code.
- Sum the Reuse-vs-Create tiers across UI + backend + tests →
bottom_up_hours.
likely_days = ceil(bottom_up_hours / 6) × productivity_factor.
story_points = closest SP→Days bucket. Disagreement >50% → trust bottom-up and downgrade SP.
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.
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):
- 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?".
- What changed — concrete edits grouped by behaviour, never by file. Each bullet specific — NEVER "update code", "fix stuff", "minor fixes".
- 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):
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).
Yes — already verified — the user confirms the integration tests were run and passed; proceed directly to Step 4 (Commit).
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:
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
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:
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.
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.
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.
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:
- Blast Radius pass (below) — drives code AND test cost
- Decompose phases → hours/phase →
bottom_up_hours = Σ phase_hours
likely_days = ceil(bottom_up_hours / 6) × productivity_factor
- Sum Risk Margin (base + add-ons) →
max_days = likely_days × (1 + margin)
min_days = likely_days × 0.9
- Output as range when
likely_days ≥3; single point allowed <3 (still record margin)
man_days_ai = same range × AI speedup
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):
- Files/components directly modified — count
- Of those, "complex" (>500 LOC, multi-handler, central, frequently-modified) — count
- Downstream consumers (callers, event subscribers, cross-service) — list
- Shared/common code touched (multi-app blast) —
…(truncated)
1---2name: commit3description: [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.4---5
6> Codex compatibility note:
7>
8> - Invoke repository skills with `$skill-name` in Codex; this mirrored copy rewrites legacy Claude `/skill-name` references.
9> - Task tracker mandate: BEFORE executing any workflow or skill step, create/update task tracking for all steps and keep it synchronized as progress changes.
10> - User-question prompts mean to ask the user directly in Codex.
11> - Ignore Claude-specific mode-switch instructions when they appear.
12> - Strict execution contract: when a user explicitly invokes a skill, execute that skill protocol as written.
13> - 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.
14> - Do not skip, reorder, or merge protocol steps unless the user explicitly approves the deviation first.
15> - For workflow skills, execute each listed child-skill step explicitly and report step-by-step evidence.
16> - If a required step/tool cannot run in this environment, stop and ask the user before adapting.
17
18<!-- CODEX:PROJECT-REFERENCE-LOADING:START -->
19
20## Codex Project-Reference Loading (No Hooks)
21
22Codex uses static project-reference loading instead of runtime-injected project docs.
23When coding, planning, debugging, testing, or reviewing, open project docs explicitly using this routing.
24
25**Always read:**
26
27- `docs/project-config.json` (project-specific paths, commands, modules, and workflow/test settings)
28- `docs/project-reference/docs-index-reference.md` (routes to the full `docs/project-reference/*` catalog)
29- `docs/project-reference/lessons.md` (always-on guardrails and anti-patterns)
30
31**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.
32
33**Situation-based docs:**
34
35- Project structure/architecture/tech-stack/deployment/setup (any layer — backend, frontend, or infra): `project-structure-reference.md`
36- Backend/CQRS/API/domain/entity changes: `backend-patterns-reference.md`, `domain-entities-reference.md`
37- Frontend/UI/styling/design-system: `frontend-patterns-reference.md`, `scss-styling-guide.md`, `design-system/README.md`
38- Spec authoring, `docs/specs/` pathing, or TC format: `feature-spec-reference.md`, `spec-system-reference.md`, `spec-principles.md`
39- Behavior/public-contract changes or spec-test-code sync: `workflow-spec-test-code-cycle-reference.md` plus the spec docs above
40- Derived spec indexes/ERDs/reimplementation guides: `spec-system-reference.md` and source Feature Specs under `docs/specs/`
41- Integration test implementation/review: `integration-test-reference.md`
42- E2E test implementation/review: `e2e-test-reference.md`
43- Code review/audit work: `code-review-rules.md` plus domain docs above based on changed files
44
45Do not read all docs blindly. Start from `docs-index-reference.md`, then open only relevant files for the task.
46
47<!-- CODEX:PROJECT-REFERENCE-LOADING:END -->
48
49## Quick Summary
50
51**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.
52
53**Summary:** (read-this-if-nothing-else digest — purpose + ALL main steps + gates)
54
55- **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.
56- **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.
57- **STEP 1-2 — ANALYZE + STAGE.** `git status` / `git diff --cached` / `git diff` / `git log --oneline -5`, then stage.
58- **STEP 2.5 — DOCS TRIAGE.** Staged files matching doc-impact patterns → run `$docs-update`, re-stage the doc changes.
59- **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.
60- **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.
61- **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.
62- **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**.
63- **STEP 4 — COMMIT** with the HEREDOC form (subject → blank → Estimate → body → Reviewers → footer).
64- **STEP 5 — VERIFY** via `git status` + `git log`; confirm the first body line IS the Estimate line, then re-present the reviewer assignment.
65- **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.
66- **FLAG** — `--push` (a.k.a. "commit and push") stages + commits + pushes via `git-manager`. Without it: **STOP after the commit**; NEVER push unprompted.
67
68**Workflow:**
69
701. **Analyze Changes** — Run git status/diff to understand staged and unstaged changes
712. **Stage Changes** — Add relevant files (specific or all)
723. **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
734. **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
745. **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
756. **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
767. **Commit** — Create commit with HEREDOC (title + Estimate line + detailed summary + Reviewers block + attribution footer)
778. **Verify** — Confirm with git status and git log
78
79**Key Rules:**
80
81- **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
82- 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
83- 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
84- 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
85- 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`)
86- Never commit secrets, credentials, or .env files
87- Never use `--amend` or `--no-verify` unless explicitly requested
88- Include `Generated with [Claude Code]` attribution footer
89
90**Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence percentages (Idea should be more than 80%).**
91
92# Git Commit Skill
93
94Stage changes and create well-structured git commits following Conventional Commits format.
95
96## IMPORTANT: Bypass git-commit-block Hook
97
98Before running any `git add` or `git commit` commands, create the marker file to bypass the `git-commit-block` hook:
99
100```bash
101PROJ=$(git rev-parse --show-toplevel) && mkdir -p "$PROJ/tmp/claude-temp" && touch "$PROJ/tmp/claude-temp/.commit-skill-active"
102```
103
104After committing (success or failure), **always** clean up the marker:
105
106```bash
107rm -f "$(git rev-parse --show-toplevel)/tmp/claude-temp/.commit-skill-active"
108```
109
110## Workflow
111
112### Step 1: Analyze Changes
113
114```bash
115# Check current status (never use -uall flag)
116git status
117
118# See staged changes
119git diff --cached
120
121# See unstaged changes
122git diff
123
124# Check recent commit style
125git log --oneline -5
126```
127
128### Step 2: Stage Changes
129
130```bash
131# Stage all changes
132git add .
133
134# Or stage specific files
135git add <file-path>
136```
137
138### Step 2.5: Docs-Update Triage
139
140Before committing, check if staged files impact documentation:
141
1421. Run `git diff --name-only --cached` to list staged files
1432. 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`):
144 - changes under the backend service source paths (per project config) → may impact `docs/specs/`
145 - `.claude/skills/**` → may impact `.claude/docs/skills/`
146 - `.claude/hooks/**` → may impact `.claude/docs/hooks/`
147 - `.claude/workflows.json` → may impact `CLAUDE.md` workflow table
148 - changes under the frontend app source paths (per project config) → may impact frontend pattern docs
1493. If matches found: invoke `$docs-update` skill, then re-stage any doc changes with `git add`
1504. If no matches: skip (log "No doc-impacting files staged")
151
152> `$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.
153
154### Step 2.7: Identify Reviewers (pre-commit — feeds the message)
155
156Runs **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.
157
158For 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.
159
160Rules:
161
162- **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**.
163- **Brand-new files (no prior history)** → mark `NEW FILE — reviewer = owner of its source/sibling file`.
164- **GROUP reviewers by change AREA** (which feature/subsystem each owns) and state WHICH AREA each must focus on — not a flat name list.
165- Fetch each reviewer's email for tagging.
166
167Collect the raw last-author-per-staged-file data:
168
169```bash
170# Staged files in this pending commit
171git diff --cached --name-only \
172 | while read -r f; do
173 author=$(git log -1 --format='%an' HEAD -- "$f" 2>/dev/null)
174 email=$(git log -1 --format='%ae' HEAD -- "$f" 2>/dev/null)
175 date=$(git log -1 --format='%ad' --date=short HEAD -- "$f" 2>/dev/null)
176 [ -z "$author" ] && author="(NEW FILE — reviewer = source/sibling owner)" && date="-"
177 printf '%s\t%s\t%s\t%s\n' "$author" "$email" "$date" "$f"
178 done
179```
180
181Then: 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:
182
183| Reviewer | Email | Focus area | Files |
184| -------- | ----- | ---------- | ----- |
185
186Follow 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.
187
188### Step 2.9: Derive the Estimate (pre-commit — feeds the message)
189
190Runs **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.
191
192**Source of the numbers — prefer an approved artifact over a fresh guess:**
193
194| Situation | Source of `story_points` / `man_days_ai` |
195| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
196| 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 |
197| 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 |
198| No estimate artifact exists | Derive bottom-up from the staged diff per the framework |
199
200**Derivation (bottom-up — SP is DERIVED, never eyeballed):**
201
2021. **Blast-radius pass** on `git diff --cached --stat` — touched areas, complex files (>500 LOC / central / multi-handler), downstream consumers, shared/common code.
2032. Sum the **Reuse-vs-Create** tiers across UI + backend + tests → `bottom_up_hours`.
2043. `likely_days = ceil(bottom_up_hours / 6) × productivity_factor`.
2054. `story_points` = closest **SP→Days** bucket. Disagreement >50% → trust bottom-up and downgrade SP.
2065. `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.
2076. `man_days_traditional` = the no-AI likely column (1≈0.5d · 2≈1d · 3≈2d · 5≈4d · 8≈6d · 13≈10d), same reconciliation.
208
209**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.
210
211**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.
212
213> **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.
214
215### Step 3: Generate Commit Message
216
217Analyze staged changes and generate message following **Conventional Commits**:
218
219```
220<type>(<scope>): <subject>
221
222Estimate: <story_points> SP | man_days_ai: <x>d | man_days_traditional: <y>d
223
224<detailed summary of changes>
225
226Reviewers:
227- <area>: <Reviewer Name> <email> — focus on <what they own>
228```
229
230#### Type Detection
231
232| Change Pattern | Type |
233| ----------------------- | ---------- |
234| New file/feature | `feat` |
235| Bug fix, error handling | `fix` |
236| Code restructure | `refactor` |
237| Documentation only | `docs` |
238| Tests only | `test` |
239| Dependencies, config | `chore` |
240| Performance improvement | `perf` |
241| Formatting only | `style` |
242
243#### Scope Rules
244
245Extract from file paths:
246
247- `{configured-source-root}/auth/` → `auth`
248- `.claude/skills/` → `claude-skills`
249- `libs/{shared-lib}/` → `{shared-lib}`
250- Multiple unrelated areas → omit scope
251
252#### Subject Rules
253
254- Imperative mood ("add" not "added")
255- Lowercase start
256- No period at end
257- Max 50 characters
258
259#### Estimate Line (MANDATORY — the FIRST line of the body)
260
261```
262Estimate: <story_points> SP | man_days_ai: <x>d | man_days_traditional: <y>d
263```
264
265- 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.
266- `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.
267- `man_days_ai` — AI-assisted man-days for this staged diff (Claude Code + project context, review overhead included). **Required.**
268- `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.
269- **Ranges** are allowed and preferred once `likely_days ≥3`: `man_days_ai: 1.0-1.5d | man_days_traditional: 4-6d`.
270- Append ` (source: <path>)` when the numbers were REUSED from a plan/PBI/story frontmatter instead of derived from the diff.
271- 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.
272
273#### Body Rules (MANDATORY) — write so a human understands fastest
274
275> 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.
276
277Three parts (omit one only when genuinely empty):
278
2791. **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?"_.
2802. **What changed** — concrete edits grouped by **behaviour**, never by file. Each bullet specific — NEVER "update code", "fix stuff", "minor fixes".
2813. **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.
282
283> **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.
284
285**Detail dial — scale body to the change:**
286
287| Change size | Body depth |
288| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
289| Trivial (typo, rename, formatting) | Purpose line + 1 bullet; skip "how it works" |
290| Normal (feature/fix, single area) | Purpose + 2–5 "what" bullets + a short "how it works" |
291| 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 |
292
293### Step 3.5: Test-Verify Gate (blocking — only when code changed)
294
295Decide 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.
296
297**Trigger detection** — run `git diff --cached --name-only` and classify the staged files:
298
299- **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).
300- **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.
301
302**If the gate is NOT triggered:** log `Test-Verify Gate: skipped (no code changes staged)` and continue to Step 4.
303
304**If the gate IS triggered:** STOP and ask the user with ask the user directly (default option is **No**):
305
306> Header: `Test verify`
307> Question: `Staged code changes may need tests. Verify before committing, or skip?`
308> Options (in order — first is the default):
309>
310> 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).
311> 2. `Yes — already verified` — the user confirms the integration tests were run and passed; proceed directly to Step 4 (Commit).
312> 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).
313
314Rules:
315
316- **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.
317- **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.
318- **Yes is an explicit user assertion** that the integration tests were run and passed; honour it and commit.
319- **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.
320- Re-run this gate only once per commit; after a `verify → green`, proceed to commit without re-asking.
321- **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.
322- This gate is independent of `--push`: it runs before the commit in every mode.
323
324### Step 4: Commit
325
326Use HEREDOC for proper formatting:
327
328```bash
329git commit -m "$(cat <<'EOF'
330type(scope): subject
331
332Estimate: 3 SP | man_days_ai: 0.65d | man_days_traditional: 2d
333
334- summarize key change 1 with intent
335- summarize key change 2 with impact
336
337Reviewers:
338- <area>: Reviewer Name <reviewer@email> — focus on <what they own>
339
340Generated by AI
341EOF
342)"
343```
344
345> 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.
346> 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)`.
347
348### Step 5: Verify
349
350```bash
351git status
352git log -1
353```
354
355Confirm 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.
356
357### Step 6: Refresh Code Graph (post-commit — background, non-blocking)
358
359**Skip entirely (silently) when `.code-graph/` does not exist** — the project has no knowledge graph and there is nothing to refresh.
360
361When 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:
362
363```bash
364if [ -d ".code-graph" ]; then python .claude/scripts/code_graph sync --json; fi
365```
366
367- **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.
368- **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.
369- **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.
370- **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.
371
372> **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.
373
374> The `--push` path pushes first, then refreshes the graph — the push is the user-visible operation and must not wait on graph work either.
375
376## Examples
377
378```
379feat(order): add warehouse filter to list
380
381Estimate: 3 SP | man_days_ai: 0.65d | man_days_traditional: 2d
382
383- add warehouse query parameter in order list endpoint
384- wire frontend filter control to request payload
385- update tests for filtered and unfiltered list behavior
386
387Reviewers:
388- order backend: Jane Doe <jane@acme.com> — focus on the list endpoint query change
389- order UI: Bob Lee <bob@acme.com> — focus on the filter control wiring
390
391Generated by AI
392
393fix(validation): handle empty date range
394
395Estimate: 1 SP | man_days_ai: 0.25d | man_days_traditional: 0.5d
396
397- guard null/empty date inputs before parsing
398- return validation message instead of throwing format exception
399
400Reviewers: none (author-owned / new files)
401
402Generated by AI
403```
404
405## Critical Rules
406
407- **ALWAYS stage all unstaged changes** before committing — run `git add .` (or specific files) so nothing is left behind
408- **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
409- **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
410- **Stop after the commit; push** to remote only when the user explicitly requests it
411- **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
412- **Review staged changes** before committing
413- **Never commit** secrets, credentials, or .env files
414- **Never use** `git commit --amend` unless explicitly requested AND the commit was created in this session AND not yet pushed
415- **Never skip** hooks with `--no-verify` unless explicitly requested
416- 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
417- 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
418- Include attribution footer: `Generated by AI`
419- **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.
420
421## Push & PR Operations
422
423**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.
424
425This 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.
426
427Spawn `git-manager` after committing when the user says "push", "create PR", or "open PR".
428
429## Sub-Agent Type Override
430
431> **MANDATORY:** Push and PR operations spawn `git-manager` sub-agent (`agent_type: "git-manager"`), NOT the main agent.
432> **Rationale:** `git-manager` enforces conventional commits, prevents hook bypasses, and handles PR creation with structured summaries.
433
434## Related
435
436- `changelog`
437- `branch-comparison`
438
439---
440
441> **[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.
442
443<!-- SYNC:sub-agent-selection -->
444
445> **Sub-Agent Selection** — Full routing contract: `.claude/skills/shared/sub-agent-selection-guide.md`
446> **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.
447
448<!-- /SYNC:sub-agent-selection -->
449
450<!-- SYNC:ai-mistake-prevention -->
451
452> **AI Mistake Prevention** — Failure modes to avoid on every task:
453>
454> **Re-read files after context changes.** Context compaction, resume, or long-running work can make memory stale; verify current files before acting.
455> **Verify generated content against source evidence.** AI hallucinates APIs, names, claims, and document facts. Check the relevant source before documenting or referencing.
456> **Check downstream references before deleting or renaming.** Removing an artifact can stale docs, generated mirrors, configs, and callers; map references first.
457> **Trace the full impact chain after edits.** Changing a definition can miss derived outputs and consumers. Follow the affected chain before declaring done.
458> **Verify ALL affected outputs, not just the first.** One green check is not all green checks; validate every output surface the change can affect.
459> **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.
460> **Surface ambiguity before acting — don't pick silently.** Multiple valid interpretations require an explicit question or stated assumption with risk.
461> **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.
462> **Keep shared guidance role-relevant.** Universal guidance must help every receiving skill or agent; code-specific obligations belong only in code-specific protocols.
463
464<!-- /SYNC:ai-mistake-prevention -->
465
466<!-- SYNC:estimation-framework -->
467
468> **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.
469>
470> **Method:**
471>
472> 1. **Blast Radius pass** (below) — drives code AND test cost
473> 2. Decompose phases → hours/phase → `bottom_up_hours = Σ phase_hours`
474> 3. `likely_days = ceil(bottom_up_hours / 6) × productivity_factor`
475> 4. Sum **Risk Margin** (base + add-ons) → `max_days = likely_days × (1 + margin)`
476> 5. `min_days = likely_days × 0.9`
477> 6. Output as range when `likely_days ≥3`; single point allowed `<3` (still record margin)
478> 7. `man_days_ai` = same range × AI speedup
479> 8. `story_points` DERIVED from `likely_days` via SP-Days — NEVER driver. Disagreement >50% → trust bottom-up
480>
481> **Productivity factor:** 0.8 strong scaffolding+codegen+AI hooks · 1.0 mature default · 1.2 weak patterns · 1.5 greenfield
482>
483> **Cost Driver Heuristic (apply BEFORE work-type row):**
484>
485> - **UI dominates** in CRUD/business apps — 1.5-3x backend (states, validation, responsive, a11y, polish)
486> - **Backend dominates ONLY:** multi-aggregate invariants, cross-service contracts, schema migrations, heavy query/perf, new event flows
487>
488> **Reuse-vs-Create axis (PRIMARY lever, per layer):**
489>
490> | UI tier | Cost |
491> | -------------------------------------------- | -------- |
492> | Reuse component on existing screen | 0.1-0.3d |
493> | Add control/column to existing screen | 0.3-0.8d |
494> | Compose components into NEW screen | 1-2d |
495> | NEW screen, custom layout/states/validation | 2-4d |
496> | NEW shared/common component (themed, tested) | 3-6d+ |
497>
498> | Backend tier | Cost |
499> | ---------------------------------------------------- | --------- |
500> | Reuse query/handler from new place | 0.1-0.3d |
501> | Small update existing handler/entity | 0.3-0.8d |
502> | NEW query on existing repo/model | 0.5-1d |
503> | NEW command/handler on existing aggregate (additive) | 1-2d |
504> | NEW aggregate/entity (repo, validation, events) | 2-4d |
505> | NEW cross-service contract OR schema migration | 2-4d each |
506> | Multi-aggregate invariant / heavy domain rule | 3-5d |
507>
508> **Rule:** Sum tiers across UI+backend+tests, apply productivity factor. Reuse short-circuits tiers — call out.
509>
510> **Test-Scope drivers (compute test_count EXPLICITLY — "+tests" hand-wave is #1 failure):**
511>
512> | Driver | Count |
513> | --------------------------------- | ------------------------------------------------------ |
514> | Happy-path journeys | 1 per story / AC main flow |
515> | State-machine transitions | reachable transitions × allowed actors |
516> | Multi-entity state combos | state(A) × state(B) — REACHABLE only, not Cartesian |
517> | Authorization matrix | (owner, non-owner, elevated, unauth) × each mutation |
518> | Validation rules | 1 per required field / boundary / format / cross-field |
519> | UI states (per new screen/dialog) | happy, loading, empty, error, partial — present only |
520> | Negative paths / invariants | 1 per violatable business rule |
521>
522> | Test tier (Trad, incl. setup+assert+flake) | Cost |
523> | ------------------------------------------ | -------- |
524> | 1-5 cases, fixtures reused | 0.3-0.5d |
525> | 6-12 cases, 1 new fixture | 0.5-1d |
526> | 13-25 cases, multi-entity setup | 1-2d |
527> | 26-50 cases OR new state-machine coverage | 2-3d |
528> | >50 cases OR full E2E journey | 3-5d |
529>
530> **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
531>
532> **Blast Radius (mandatory pre-pass — affects code AND test):**
533>
534> 1. Files/components directly modified — count
535> 2. Of those, "complex" (>500 LOC, multi-handler, central, frequently-modified) — count
536> 3. Downstream consumers (callers, event subscribers, cross-service) — list
537> 4. Shared/common code touched (multi-app blast) —
538
539…(truncated)