backend-atomic-commit by aiskillstore
>
Content & Writing
85 Stars
2 Forks
Updated Jan 19, 2026, 04:39 AM
Why Use This
This skill provides specialized capabilities for aiskillstore's codebase.
Use Cases
- Developing new features in the aiskillstore repository
- Refactoring existing code to follow aiskillstore standards
- Understanding and working with aiskillstore's codebase structure
Install Guide
2 steps- 1
Skip this step if Ananke is already installed.
- 2
Skill Snapshot
Auto scan of skill assets. Informational only.
Valid SKILL.md
Checks against SKILL.md specification
Source & Community
Skill Stats
SKILL.md 484 Lines
Total Files 1
Total Size 0 B
License NOASSERTION
---
name: backend-atomic-commit
description: >
Pedantic backend pre-commit and atomic commit Skill for Django/Optimo-style
repos. Enforces local AGENTS.md / CLAUDE.md, pre-commit hooks, .security/*
helpers, and Monty’s backend engineering taste – with no AI signatures in
commit messages.
allowed-tools:
- Bash
- Read
- Edit
- Glob
- Grep
---
# Backend Atomic Commit Skill
## When to Use This Skill
Use this Skill in backend/Django repos (especially the Diversio monolith
backend) when you want:
- `/backend-atomic-commit:pre-commit` – to **actively fix** the current code
(formatting, imports, type hints, logging, etc.) so that it matches:
- Local `AGENTS.md` / `CLAUDE.md` rules.
- `.pre-commit-config.yaml` expectations.
- `.security/` diff helpers (ruff and local imports).
- Monty’s backend taste.
- `/backend-atomic-commit:atomic-commit` – to run the same checks plus:
- Enforce that the **staged changes are atomic** (one coherent change).
- Ensure all quality gates are green (no shortcuts).
- Propose a strict, ticket-prefixed commit message **without** any Claude or
AI signatures.
## Example Prompts
- “Run `/backend-atomic-commit:pre-commit` on this repo and actively fix all
files in `git status` so they obey backend `AGENTS.md`, `.pre-commit-config.yaml`,
`.security/*` helpers, and Monty’s taste (no local imports, strong typing,
structured logging). Then summarize what you changed and what’s still
`[BLOCKING]`.”
- “Use `/backend-atomic-commit:atomic-commit` to prepare an atomic commit for
the staged changes in `backend/`. Enforce all pre-commit hooks and
`.security` scripts, run Ruff, ty, Django checks, and relevant pytest
subsets, then propose a ticket-prefixed commit message with **no AI
signature** and clearly mark any `[BLOCKING]` issues.”
- “Treat my current backend changes as one logical bugfix and run
`/backend-atomic-commit:pre-commit` in a strict mode: eliminate local
imports, fix type hints (no `Any`, no string-based annotations), clean up
debug statements, and ensure Ruff, `.security/local_imports_pr_diff.sh`,
ty, and Django checks are happy."
- “Before I commit these `optimo_*` changes, run
`/backend-atomic-commit:atomic-commit --auto` to:
- enforce structured logging with `TypedDict` payloads,
- ensure no PII in logs,
- verify tests and `.security/*` scripts,
and then tell me whether the commit is ready and what the commit message
should be.”
If you’re not in a backend repo (no `manage.py`, no backend-style `AGENTS.md`,
no `.pre-commit-config.yaml`), this Skill should say so explicitly and fall
back to a lighter “generic Python pre-commit” behavior.
## Modes
This Skill behaves differently based on how it is invoked:
- `pre-commit` mode – invoked via `/backend-atomic-commit:pre-commit`:
- Actively applies changes to make the working tree and staged files conform
to repo standards and pre-commit requirements.
- Runs all relevant static checks and auto-fixers.
- Does **not** propose or drive a commit.
- `atomic-commit` mode – invoked via `/backend-atomic-commit:atomic-commit`:
- Runs everything from `pre-commit` mode.
- Enforces atomicity of staged changes.
- Requires all gates to be green.
- Proposes a commit message, but **must never** add AI signatures or plugin
branding to the message.
The command markdown sets the mode. You should detect the mode from the command
description/context and adjust behavior accordingly.
## Core Priorities
Emulate Monty’s backend engineering and review taste, tuned for pre-commit:
1. **Correctness & invariants** – multi-tenancy, time dimensions, and security
constraints come first.
2. **Safety & reviewability** – avoid dangerous schema changes, large risky
try/except blocks, hidden PII, or untyped payloads.
3. **Atomic commits** – one commit should represent one coherent change; split
unrelated work.
4. **Local repo rules first** – treat `AGENTS.md` and `CLAUDE.md` as the source
of truth when present; this Skill is a default baseline.
5. **Tooling alignment** – use uv wrappers, `.security/*` helpers, and
`.pre-commit-config.yaml` hooks as documented, not ad-hoc commands.
6. **Type and structure** – prefer precise type hints, `TypedDict`/dataclasses,
and structured logging over untyped dicts and log soup.
7. **No AI signatures in commits** – commit messages must look like a human
wrote them; this Skill should be invisible from `git log`.
Always prioritize `[BLOCKING]` issues over style and nits.
## Environment & Context Gathering
When this Skill runs, you should first gather context using `Bash`, `Read`,
`Glob`, and `Grep`:
- Git context:
- `git status --porcelain`
- `git branch --show-current`
- `git diff --cached --stat`
- `git diff --cached --name-only`
- `git log --oneline -10`
- Repo configuration:
- Read `AGENTS.md` and `CLAUDE.md` (if present) for repo-specific rules.
- Detect `.pre-commit-config.yaml`.
- Detect `.security/` scripts, especially:
- `./.security/ruff_pr_diff.sh`
- `./.security/local_imports_pr_diff.sh`
- Detect `manage.py` / Django project layout.
- Tool availability:
- `uv` and `.bin/` wrappers:
- `.bin/ruff`, `.bin/ty`, `.bin/django`, `.bin/pytest`.
- Fallback to `uv run` or plain `python` / `pytest` / `ruff` where necessary.
If the repo clearly isn’t the Diversio backend / Django4Lyfe style, say so and
adjust expectations (but you can still run generic Python pre-commit checks).
## Checks in Both Modes
In **both** `pre-commit` and `atomic-commit` modes, follow this pipeline:
1. **Scope changed files**
- Start from files reported by `git status` and `git diff --cached`:
- Distinguish staged vs unstaged vs untracked.
- Categorize by type:
- Python (src vs tests; `optimo_*`, `dashboardapp`, `survey`, etc.).
- Templates (Django HTML).
- Config (YAML, JSON, `.pre-commit-config.yaml`, `pyproject.toml`,
`requirements*.txt`).
- Docs/markdown.
2. **Static formatting/linting**
- Ruff:
- Run `./.security/ruff_pr_diff.sh` if present.
- Run `.bin/ruff check --fix` on changed Python files.
- Run `.bin/ruff format` on those files.
- **IMPORTANT**: For any file you touch, you must resolve **ALL** ruff
errors in that file—not just the ones you introduced. CI runs ruff on
modified files, so pre-existing errors in touched files will cause CI
failures. Do **not** dismiss errors as "pre-existing" if the file is in
your diff.
- Templates:
- Run `djlint-reformat-django` and `djlint-django` on changed templates
when configured in `.pre-commit-config.yaml`.
- Generic pre-commit hooks:
- Respect hook definitions in `.pre-commit-config.yaml`; run
`pre-commit run` on relevant files when possible.
3. **Backend-specific .security gates**
- Run `.security` scripts where present:
- `./.security/ruff_pr_diff.sh` – Ruff on changed files vs base branch.
- `./.security/local_imports_pr_diff.sh` – check for local imports.
- Treat failures as at least `[SHOULD_FIX]` and usually `[BLOCKING]` for
`atomic-commit`.
4. **Type checking with ty**
- Run `ty` on **modified Python files only** to catch type errors before CI:
```bash
# For staged files (atomic-commit mode):
.bin/ty check $(git diff --cached --name-only --diff-filter=ACMR | grep '\.py$')
# For all modified files (pre-commit mode):
.bin/ty check $(git diff --name-only --diff-filter=ACMR | grep '\.py$')
```
- This scoped approach avoids triggering baseline errors in **unmodified**
files while matching CircleCI's `ty` check behavior.
- **IMPORTANT**: For any file you touch, you must resolve **ALL** `ty` errors
in that file—not just the ones you introduced. CI runs `ty` on modified
files, so pre-existing errors in touched files will cause CI failures.
Do **not** dismiss errors as "pre-existing" if the file is in your diff.
- Common pitfall: Fixing ruff ARG002 (unused argument) by prefixing with `_`
may satisfy ruff but break `ty` if the method signature must match a parent
class (e.g., Django admin methods). Always run both checks together.
- Treat **any** `ty` errors in modified files as `[BLOCKING]` for
`atomic-commit` mode or `[SHOULD_FIX]` for `pre-commit` mode.
5. **Django system checks**
- Run `.bin/django check` or equivalent:
- `uv run python manage.py check --fail-level WARNING`.
- For risky changes (models, migrations, core logic), run **targeted**
`pytest` subsets based on changed apps:
- Example: `dashboardapp/` changes → `pytest dashboardapp/tests/`.
- If tests cannot be run (e.g. env not set up), say so explicitly and treat
“tests not run” as at least `[SHOULD_FIX]` and often `[BLOCKING]` for
`atomic-commit`.
6. **Interaction with pre-commit hooks**
- If `.pre-commit-config.yaml` exists:
- Expect hooks to run and modify files (ruff, djlint, interrogate,
custom scripts).
- After hooks run, re-check `git status` and restage modified files as
appropriate.
- If a hook executable is missing (e.g. `check_prepare_commit_msg_hook.py`
referenced but not present), do **not** crash:
- Record a `[SHOULD_FIX]` issue stating which hook is missing and why it
matters.
## Monty Backend Taste – Auto-Fix Rules
When running in `pre-commit` mode, you are allowed and expected to **actively
edit code** to align with Monty’s backend taste where it is clearly safe. In
`atomic-commit` mode, you may still fix things, but be more conservative and
always summarize edits.
### Imports & local imports
- Enforce **no local imports at any cost**:
- Avoid `from myapp.models import MyModel` inside functions or methods just
to dodge cyclic imports.
- Use `.security/local_imports_pr_diff.sh` as the first line of defense.
- Prefer:
- Module-level imports.
- Refactoring helpers to avoid cycles.
- Type-only imports (e.g. `from __future__ import annotations`) when needed.
- If moving imports risks true cyclic import problems:
- Suggest structural changes (splitting modules, relocating helpers).
- Never silently reintroduce local imports; call out unresolved cycles as
`[SHOULD_FIX]`.
### Logging (especially in optimo_* apps)
- Enforce structured logging:
- Prefer structured payloads over single log strings:
- Good: `logger.info("optimo_event", extra={"company_uuid": str(company.uuid)})`.
- Avoid: `logger.info("Company %s did %s", company.name, something)`.
- In `optimo_*` apps, treat unstructured logging as at least `[SHOULD_FIX]`.
- PII in logs:
- Never log PII such as `assignment.employee.email`; this is enforced by
pre-commit hooks already, but you should also conceptually check.
- Prefer logging UUIDs/IDs instead of emails or names.
- Log levels:
- Avoid `logger.exception` for expected error paths; use `error` or `warning`
with explicit messages.
### Try/except and error handling
- Avoid large, catch-all `try/except` blocks:
- Shrink the `try` body to only the lines that can raise.
- Replace bare `except:` or `except Exception:` with specific exceptions
whenever possible.
- Never swallow exceptions silently:
- Always log or re-raise; returning silently on failure is `[BLOCKING]` for
behaviorally important code.
- Avoid overusing `getattr`/`hasattr` as a crutch:
- Only use `hasattr()` when truly needed (e.g. cross-version adapters) and
document why.
### Types, hints, and data structures
- Be pedantic about type hints:
- Avoid `Any` as much as possible; prefer precise types and generics.
- No string-based type hints like `"OptimoRiskQuestionBank"`; use real types
and proper imports.
- Add missing annotations on new/changed functions, especially in
`optimo_*`, `dashboardapp`, and other core apps.
- Prefer structured data:
- Replace `Dict[str, Any]` or ad-hoc dict payloads with `TypedDict` or
dataclasses when the shape is stable and local.
- Avoid shape-changing dicts where keys appear/disappear across branches;
suggest a typed structure instead.
### Tests and fixtures
- Avoid repeating fixtures or introducing fixture collisions:
- Prefer existing rich fixtures described in `AGENTS.md` (e.g. `responses`
in survey tests, company/survey fixtures that respect multi-tenant
relationships).
- Do not introduce new Django `TestCase` classes in `optimo_*` apps; use
pytest + fixtures.
- Watch for multi-tenant fixture mismatches (e.g. survey from one company,
user from another); highlight these as `[BLOCKING]` when they affect
correctness.
- When touching tests:
- Prefer pytest fixtures and helper factories.
- Avoid local imports inside tests; use module-level imports.
### ORM and query patterns
- Use reverse relations where it reduces imports and improves clarity:
- Prefer `company.surveys.all()` to `Survey.objects.filter(company=company)`
when it avoids extra imports and is idiomatic.
- Watch for N+1 queries in obvious loops:
- Flag them as `[SHOULD_FIX]` for hot paths or performance-sensitive code.
### Commented / dead code and debug artifacts
- Remove obvious debug leftovers:
- `print(...)`, `pdb.set_trace()`, `ipdb.set_trace()`, `breakpoint()` in
non-test code.
- Remove clearly obsolete commented-out blocks:
- Old versions of code commented around a new implementation.
- For ambiguous commented sections:
- Flag them as `[SHOULD_FIX]` and suggest either deleting them or moving
rationale into docs.
- `TODO` / `FIXME` without ticket IDs:
- Suggest converting to ticket-tagged comments (e.g. `TODO(GH-123): ...` or
`TODO(27pfu0): ...`) or moving the note into ClickUp.
### String / formatting style
- Migrate to f-strings where it improves clarity:
- Replace old `%` formatting or `.format()` with f-strings when not blocked
by translation/i18n constraints.
- Avoid giant f-strings with logic:
- Suggest splitting into intermediate variables when readability suffers.
### Security & secrets
- Detect obvious secrets checked into code or fixtures:
- Hardcoded tokens, passwords, API keys.
- Flag as `[BLOCKING]` and suggest using environment variables and 1Password.
- Avoid staging obvious secret-heavy files:
- `.env`, `google_creds.json`, `google_drive_creds.json`, etc.
- Recommend un-staging and `.gitignore` updates where appropriate.
### Migrations and schema changes
- Do **not** change migration behavior automatically; instead:
- Detect destructive schema changes (dropping fields/tables) combined with
code changes that still expect those fields:
- Mark as `[BLOCKING]` and recommend a two-step rollout:
- PR 1: remove usage in code, keep schema.
- PR 2: drop the field/table once code is clean.
- Detect new non-nullable fields with defaults on large/hot tables:
- Mark as `[SHOULD_FIX]` or `[BLOCKING]` depending on risk.
- Suggest the safer pattern:
- Add nullable field with no default.
- Backfill in batches.
- Then add default for new rows only.
- Detect volatile defaults (UUIDs, timestamps) used in migrations:
- Warn against backfilling large tables inside a single atomic migration;
recommend batched or non-atomic backfills.
### Critical backend patterns from AGENTS.md
- Watch for new instances of patterns explicitly banned in backend `AGENTS.md`:
- Django Ninja `Query()` module-level constants that break parameter
resolution (e.g. `Q_INCLUDE_INACTIVE = Query(False, ...)`).
- Legacy survey models like `OptimoEmployeeSurvey` or `employee_survey`.
- Any other CRITICAL warnings spelled out in that file.
- Treat any new usage of these patterns as `[BLOCKING]`.
## Atomic-Commit Mode – Extra Strictness
In `atomic-commit` mode (invoked via `/backend-atomic-commit:atomic-commit`),
you must be **very strict**:
1. **Atomicity of staged changes**
- From `git diff --cached --name-only`, determine if staged changes belong
to one coherent change:
- Example of non-atomic:
- Refactor in `survey/` plus an unrelated optimo bugfix and docs tweak.
- Emit:
- `[BLOCKING]` if the staged set is clearly multiple logical changes.
- `[SHOULD_FIX]` for minor opportunistic cleanups that could be split.
- You may suggest a split (e.g. “extract the optimo fix into a separate
commit”) but must not label a non-atomic set as “ready”.
2. **All gates must be green**
- The commit is **not** ready if any of these fail:
- `./.security/ruff_pr_diff.sh`
- `./.security/local_imports_pr_diff.sh`
- `.bin/ruff check` / `ruff format`
- `.bin/ty check <staged_python_files>` (scoped to modified files only)
- `.bin/django check` / `manage.py check`
- Relevant `pytest` subsets for risky changes
- Pre-commit hooks defined in `.pre-commit-config.yaml`
- In `--auto` style usage, you may skip conversational confirmation, but
you **must not** relax these gates.
- If tests or checks are skipped for any reason, clearly state that and
treat it as at least `[SHOULD_FIX]` and usually `[BLOCKING]`.
3. **Commit message generation (no AI signature)**
- Extract ticket ID from branch name using repo conventions:
- For the Diversio backend:
- Branch name: `clickup_<ticket_id>_...`
- Commit format per `AGENTS.md`: `<ticket_id>: Description`.
- If commit message hooks like `commit_msg_hook.py` exist:
- Avoid double-prefixing ticket IDs.
- If hooks and docs disagree, call that out as `[SHOULD_FIX]` and follow
the documented `AGENTS.md` convention for suggestions.
- Generate a concise, human-looking subject line:
- Summarize what changed and why in one line.
- Do **not** mention Claude, AI, this Skill, or plugin names.
- Do **not** add any footer or signature:
- No “via Claude Code”.
- No “Generated by backend-atomic-commit”.
- Commit messages must look like a human wrote them.
4. **Final preview and verdict**
Your `atomic-commit` output should include:
- A short summary of what was checked.
- `Checks run` – listing each gate and its status.
- `What’s aligned` – strengths and good patterns in the staged changes.
- `Needs changes` – bullets with `[BLOCKING]`, `[SHOULD_FIX]`, `[NIT]`.
- `Proposed commit` – suggested commit message and list of files.
- An explicit verdict:
- “✅ Commit ready” only if there are **no `[BLOCKING]` items**.
- Otherwise:
- “❌ Not ready to commit” with concrete next steps.
You should **never** encourage the user to run `git commit` as-is if any
`[BLOCKING]` issues remain.
## Pre-Commit Mode – Fixing Without Committing
In `pre-commit` mode (invoked via `/backend-atomic-commit:pre-commit`):
- You may aggressively auto-fix:
- Formatting, linting, local imports, obvious type hints, logging patterns,
removal of debug code, and consistent fixtures.
- You must:
- Run the same gates described above (Ruff, `.security/*`, ty, Django
checks, tests as appropriate).
- Re-run or re-stage files modified by tools or hooks.
- You do **not** propose a commit or check atomicity.
- Your output should focus on:
- `Fixes applied` – concrete edits you made.
- `Remaining issues` – with severity tags.
- `Checks run` – which gates passed/failed.
This mode is the “make my working tree clean and standards-compliant” helper
before running an atomic commit.
## Severity Tags & Output Shape
Always structure findings using severity tags and sections:
- `[BLOCKING]` – must be fixed before a commit is considered ready:
- Failing `.security` scripts or pre-commit hooks.
- New banned patterns from `AGENTS.md` (e.g., Ninja Query constants, legacy
survey models).
- Obvious multi-tenant or security regressions.
- Non-atomic staged changes in `atomic-commit` mode.
- `[SHOULD_FIX]` – important, strongly recommended changes:
- Style/structure that harms readability or maintainability.
- Missing type hints where types are clear.
- Ambiguous commented code or TODOs without tickets.
- Missing tests for non-trivial new behavior.
- `[NIT]` – minor cleanups:
- Docstring tone/punctuation.
- Minor naming and formatting nits not covered by Ruff.
Output shape for both modes:
- 1–3 sentence summary of what was checked.
- Sections (when appropriate):
- `What’s aligned`
- `Needs changes`
- `Checks run`
- `Proposed commit` (only in atomic-commit mode)
Be direct, specific, and actionable in each bullet, pointing to file/area and
suggesting concrete corrections. Never hide behind vague "consider improving"
phrases when you can be precise.
## Compatibility Notes
This skill is designed to work with both **Claude Code** and **OpenAI Codex**.
For Codex users:
- Install via skill-installer with `--repo DiversioTeam/agent-skills-marketplace
--path plugins/backend-atomic-commit/skills/backend-atomic-commit`.
- Use `$skill backend-atomic-commit` to invoke.
For Claude Code users:
- Install via `/plugin install backend-atomic-commit@diversiotech`.
- Use `/backend-atomic-commit:atomic-commit` or `/backend-atomic-commit:pre-commit` to invoke.
Name Size