Use when performing any git operation — commits, branching, pushing, stashing, or viewing history. Enforces signed commits, semantic format with scope, and file-change table in commit messages.
Standardize all git operations — commits, branching, pushing, and history — using GitKraken MCP tools and the project's mandatory commit format: signed, semantic prefix with scope, file-change table, and Author trailer.
Every commit MUST follow this exact structure:
<type>(<scope>): <short description>
| Area | Change |
|------------|-------------------------------------|
| models.py | Added Account frozen dataclass |
| service.py | Added calculate_net_worth_summary() |
Author: Prabhukumar Sivamorthy
First line — type(scope): description
<type> — commit category (see Semantic Commit Types below)<scope> — affected feature or module (e.g. budget_goals, net_worth, api, ingestion)<short description> — imperative, lowercase, no period, max 72 characters totalBlank line — Always separate the header from the body
File-change table — A markdown table listing each changed area and what changed
Area — file name or path relative to the feature (e.g. models.py, api/routers/, test_*.py)Change — specific description of what changed (not just "updated" or "modified")Blank line — Separate table from trailer
Author trailer — Author: Prabhukumar Sivamorthy
| Type | Description |
|---|---|
feat | New feature |
fix | Bug fix |
docs | Documentation changes |
style | Code style (formatting, no logic change) |
refactor | Code refactoring (no feature/fix) |
test | Adding or updating tests |
chore | Maintenance tasks, dependencies |
featfixdocsstylerefactortestchorefeat(net_worth): add account balance history tracking
| Area | Change |
|------------------|------------------------------------------|
| models.py | Added BalanceSnapshot frozen dataclass |
| repository.py | Added save_snapshot() and get_history() |
| service.py | Added compute_balance_trend() function |
| api/routers/ | Added GET /net-worth/history endpoint |
Author: Prabhukumar Sivamorthy
fix(ingestion): handle empty CSV files without crashing
| Area | Change |
|--------------|-----------------------------------------------|
| service.py | Added early return guard for empty DataFrame |
| test_*.py | Added regression test for empty file input |
Author: Prabhukumar Sivamorthy
refactor(payments): extract payment processing into dedicated service
| Area | Change |
|-------------------------------|-------------------------------------------------------|
| payments/service.py | Created PaymentService with process() and refund() |
| payments/processors.py | Extracted StripeProcessor and PayPalProcessor |
| orders/service.py | Replaced inline payment logic with PaymentService |
| test_payment_service.py | Added 15 unit tests for PaymentService |
| test_order_service.py | Updated 8 tests to use mocked PaymentService |
Author: Prabhukumar Sivamorthy
test(budget_goals): add edge case tests for budget limit calculation
| Area | Change |
|-------------------------------|----------------------------------------------------------------|
| test_budget_goals_service.py | Added 6 tests: zero budget, negative amounts, float precision |
| conftest.py | Added budget_goal_factory fixture |
Author: Prabhukumar Sivamorthy
chore(deps): upgrade FastAPI to 0.115.0
| Area | Change |
|-------------------|-----------------------------------------------|
| pyproject.toml | Bumped fastapi from 0.114.2 to 0.115.0 |
| uv.lock | Regenerated lock file |
Author: Prabhukumar Sivamorthy
docs(readme): update README with local development setup
| Area | Change |
|--------------------|---------------------------------------------------------------|
| README.md | Added Prerequisites, Installation, and Running Tests sections |
| docs/architecture.md | Created architecture overview with Mermaid diagram |
Author: Prabhukumar Sivamorthy
All git operations MUST use the GitKraken MCP tools. They produce structured, token-efficient output.
Before any commit or push, always rebase onto the latest origin/main to avoid conflicts and keep history clean.
git fetch origin && git rebase origin/main
If rebase conflicts occur, resolve them before proceeding. After rebasing, use git push --force-with-lease (never --force) to update the remote branch.
mcp__gitkraken__git_status(directory: ".")
Review untracked and modified files. Identify which files to stage.
mcp__gitkraken__git_log_or_diff(directory: ".", action: "log")
mcp__gitkraken__git_log_or_diff(directory: ".", action: "diff")
Confirm the diff matches intent. Check for secrets or .env files.
mcp__gitkraken__git_add_or_commit(
directory: ".",
action: "add",
files: ["path/to/file1.py", "path/to/file2.py"]
)
Never stage all files blindly. List each file explicitly.
mcp__gitkraken__git_add_or_commit(
directory: ".",
action: "commit",
message: "type(scope): concise description\n\n| Area | Change |\n|---|---|\n| file.py | What changed |\n\nAuthor: Prabhukumar Sivamorthy"
)
mcp__gitkraken__git_log_or_diff(directory: ".", action: "log")
Confirm the commit appears with the correct message format.
Always push after committing. Use --force-with-lease after rebasing (Step 1 already ensured the branch is up to date). Do not ask the user — just push.
mcp__gitkraken__git_push(directory: ".")
When the user asks to create a PR, review all commits on the branch and generate a comprehensive PR description.
git merge-base origin/main HEAD
mcp__gitkraken__git_log_or_diff(directory: ".", action: "log", revision_range: "origin/main..HEAD")
Read every commit message — not just the latest one. Each commit's Area | Change table is your source of truth.
mcp__gitkraken__git_log_or_diff(directory: ".", action: "diff", revision_range: "origin/main..HEAD")
Build the PR using this template:
## Summary
[2-3 sentences: what this PR does at a high level and why]
## Changes
| Area | Change |
|------|--------|
| [file/module] | [what changed — aggregated from all commits] |
| ... | ... |
## Commits
- `abc1234` type(scope): description
- `def5678` type(scope): description
- ...
## Test Plan
- [ ] Unit tests pass (`uv run pytest src/test/unit/ -q`)
- [ ] [Any specific manual verification steps]
- [ ] No regressions in existing features
type(scope): high-level description. Keep under 70 characters.gh pr create --title "type(scope): high-level description" --body "..."
Use a HEREDOC for the body to preserve formatting.
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
feat: add login | Missing scope | feat(auth): add login endpoint |
Updated files | Too vague | Describe the specific change per file |
| Missing table rows | Incomplete record | Every staged file gets a row |
feat(auth): Added login | Past tense | Use imperative: add, not Added |
| Summary says "modified" | Doesn't explain what changed | Describe the actual modification |
| No blank line after header | Breaks git formatting | Always blank line between header and body |
| Table without header row | Invalid markdown table | Always include ` |
| Line > 72 chars in header | Breaks git log formatting | Keep first line under 72 characters |
Before committing, verify:
origin/main (git fetch origin && git rebase origin/main)git_log_or_diff diff).env files in the staged changesuv run pytest src/test/unit/ -q)uv run pylint src/budget_analyser)type(scope): description format| Area | Change | columnsAuthor: Prabhukumar Sivamorthy