Pedantic backend pre-commit + atomic-commit skill for Django/Optimo repos that enforces local repo rules, pre-commit hooks, and security helpers (no AI signatures in commit messages).
Enforces Django backend pre-commit rules, runs security checks, and prepares atomic commits without AI signatures.
/plugin marketplace add diversioteam/agent-skills-marketplace/plugin install backend-atomic-commit@diversiotechThis skill is limited to using the following tools:
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:
AGENTS.md / CLAUDE.md rules..pre-commit-config.yaml expectations..security/ diff helpers (ruff and local imports)./backend-atomic-commit:atomic-commit – to run the same checks plus:
/backend-atomic-commit:commit – to run atomic-commit, then create the
commit once all gates are green (no bypassing commit-msg hooks)./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].”/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, active type gate checks, Django checks, and relevant pytest
subsets, then propose a ticket-prefixed commit message with no AI
signature and clearly mark any [BLOCKING] issues.”/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,
active type gate checks, and Django checks are happy."optimo_* changes, run
/backend-atomic-commit:atomic-commit --auto to:
TypedDict payloads,.security/* scripts,
and then tell me whether the commit is ready and what the commit message
should be.”/backend-atomic-commit:commit to run all gates on my staged changes,
then create the commit once everything is green. If something fails, keep
fixing and re-running until it commits or you have a clear [BLOCKING]
reason it can’t.”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.
This Skill behaves differently based on how it is invoked:
pre-commit mode – invoked via /backend-atomic-commit:pre-commit:
atomic-commit mode – invoked via /backend-atomic-commit:atomic-commit:
pre-commit mode.commit mode – invoked via /backend-atomic-commit:commit:
atomic-commit mode.The command markdown sets the mode. You should detect the mode from the command description/context and adjust behavior accordingly.
Emulate Monty’s backend engineering and review taste, tuned for pre-commit:
date +%Y-%m-%d or Python datetime — never compute
dates manually. Date calculation errors have been a recurring friction
point in real sessions.AGENTS.md and CLAUDE.md as the source
of truth when present; this Skill is a default baseline..security/* helpers, and
.pre-commit-config.yaml hooks as documented, not ad-hoc commands.TypedDict/dataclasses,
and structured logging over untyped dicts and log soup.git log.Always prioritize [BLOCKING] issues over style and nits.
When this Skill runs, you should first gather context using Bash, Read,
Glob, and Grep:
git status --porcelaingit branch --show-currentgit diff --cached --statgit diff --cached --name-onlygit log --oneline -10AGENTS.md and CLAUDE.md (if present) for repo-specific rules..pre-commit-config.yaml..security/ scripts, especially:
./.security/gate_cache.sh./.security/ruff_pr_diff.sh./.security/local_imports_pr_diff.shmanage.py / Django project layout.uv and .bin/ wrappers:
.bin/ruff, .bin/ty, .bin/pyright, .bin/mypy, .bin/django,
.bin/pytest.uv run or plain python / pytest / ruff where necessary.docs/python-typing-3.14-best-practices.md, TY_MIGRATION_GUIDE.md) and
follow them over this default.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).
If ./.security/gate_cache.sh exists, treat it as the canonical wrapper for
heavy deterministic checks. Use it by default for type gates and Django checks.
./.security/gate_cache.sh --gate ty-check --scope index -- .bin/ty check .
./.security/gate_cache.sh --gate django-system-check --scope index -- uv run python manage.py check --fail-level WARNING
Use scope=index for commit-focused gating and scope=working when results are
expected to depend on unstaged edits. Do not bypass cache unless explicitly
requested or debugging:
CHECK_CACHE_BUST=1 ./.security/gate_cache.sh --gate ty-check --scope index -- .bin/ty check .
./.security/gate_cache.sh --clear-this-checkout
For Ruff/local-import diff helpers, call the scripts directly. They already use cache-aware execution internally and include local staged/unstaged tracked files. Prefer running them through pre-commit hooks first; call scripts directly only for targeted diagnosis or when a matching hook is missing/disabled.
In both pre-commit and atomic-commit modes, follow this pipeline:
git status and git diff --cached:
optimo_*, dashboardapp, survey, etc.)..pre-commit-config.yaml, pyproject.toml,
requirements*.txt).Run pre-commit first (primary execution path)
.pre-commit-config.yaml exists, run hooks on the intended file set
before any direct per-tool commands.atomic-commit mode:
pre-commit run --files $(git diff --cached --name-only --diff-filter=ACMR)
pre-commit mode:
CHANGED_FILES="$(
{
git diff --name-only --diff-filter=ACMR
git ls-files --others --exclude-standard
} | sed '/^$/d' | sort -u
)"
pre-commit run --files $CHANGED_FILES
Direct command fallback (targeted, non-duplicative)
CHECKS_ALLOW_FETCH_SKIP=1 when a local skip is explicitly acceptable../.security/ruff_pr_diff.sh./.security/local_imports_pr_diff.shorigin/<base>..HEAD,
staged, and unstaged tracked Python changes.Type checking with active repository gate (ty-first)
ty if configured ([tool.ty], ty.toml, .bin/ty, or CI/pre-commit).pyright if configured.mypy if configured.# ty example - staged files (atomic-commit mode):
.bin/ty check $(git diff --cached --name-only --diff-filter=ACMR | grep '\.py$')
# ty example - all modified files (pre-commit mode):
.bin/ty check $(git diff --name-only --diff-filter=ACMR | grep '\.py$')
# pyright example - staged files (atomic-commit mode):
.bin/pyright $(git diff --cached --name-only --diff-filter=ACMR | grep '\.py$')
# pyright example - all modified files (pre-commit mode):
.bin/pyright $(git diff --name-only --diff-filter=ACMR | grep '\.py$')
# mypy example - staged files (atomic-commit mode):
.bin/mypy $(git diff --cached --name-only --diff-filter=ACMR | grep '\.py$')
# mypy example - all modified files (pre-commit mode):
.bin/mypy $(git diff --name-only --diff-filter=ACMR | grep '\.py$')
_
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.[BLOCKING]
for atomic-commit mode or [SHOULD_FIX] for pre-commit mode.Django system checks
./.security/gate_cache.sh --gate django-system-check --scope index -- uv run python manage.py check --fail-level WARNING.bin/django check or equivalent:
uv run python manage.py check --fail-level WARNING.pytest subsets based on changed apps:
dashboardapp/ changes → pytest dashboardapp/tests/.[SHOULD_FIX] and often [BLOCKING] for
atomic-commit.Interaction with pre-commit hooks
.pre-commit-config.yaml exists:
git status and restage modified files as
appropriate.check_prepare_commit_msg_hook.py
referenced but not present), do not crash:
[SHOULD_FIX] issue stating which hook is missing and why it
matters.Convergence loop (do not stop early)
git status and restage only the
intended files (atomic commits should not accidentally grow).You are stuck on a check when any of these are true:
When stuck:
[BLOCKING] with:
Do not use TodoWrite or TaskCreate to track individual gate results.
This is a fixed, known sequence — not an open-ended task list. Tracking ruff/
djlint/type-check failures as todo items wastes tokens and context window. Report
results directly in the final output using the existing severity-tagged
sections (Checks run, Needs changes, etc.).
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.
from myapp.models import MyModel inside functions or methods just
to dodge cyclic imports..security/local_imports_pr_diff.sh as the first line of defense.from __future__ import annotations) when needed.[SHOULD_FIX].logger.info("optimo_event", extra={"company_uuid": str(company.uuid)}).logger.info("Company %s did %s", company.name, something).optimo_* apps, treat unstructured logging as at least [SHOULD_FIX].assignment.employee.email; this is enforced by
pre-commit hooks already, but you should also conceptually check.logger.exception for expected error paths; use error or warning
with explicit messages.try/except blocks:
try body to only the lines that can raise.except: or except Exception: with specific exceptions
whenever possible.[BLOCKING] for
behaviorally important code.getattr/hasattr as a crutch:
hasattr() when truly needed (e.g. cross-version adapters) and
document why.Any as much as possible; prefer precise types and generics."OptimoRiskQuestionBank"; use real types
and proper imports.optimo_*, dashboardapp, and other core apps.Dict[str, Any] or ad-hoc dict payloads with TypedDict or
dataclasses when the shape is stable and local.AGENTS.md (e.g. responses
in survey tests, company/survey fixtures that respect multi-tenant
relationships).TestCase classes in optimo_* apps; use
pytest + fixtures.[BLOCKING] when they affect
correctness.company.surveys.all() to Survey.objects.filter(company=company)
when it avoids extra imports and is idiomatic.[SHOULD_FIX] for hot paths or performance-sensitive code.print(...), pdb.set_trace(), ipdb.set_trace(), breakpoint() in
non-test code.[SHOULD_FIX] and suggest either deleting them or moving
rationale into docs.TODO / FIXME without ticket IDs:
TODO(GH-123): ... or
TODO(27pfu0): ...) or moving the note into ClickUp.% formatting or .format() with f-strings when not blocked
by translation/i18n constraints.atomic-commit mode, they
are usually [BLOCKING].style="..."):
{% block content %} ... {% endblock content %}{% endblock %} when the repo’s linting expects names.djlint --lint --check <file> when that’s what the repo uses), fix, and re-run until
clean.afterEdit hook for *.html in .claude/settings.json to run
djlint on the edited file, using the repo's wrapper (.bin/djlint, uv run djlint, etc.) when available.[tool.djlint] in pyproject.toml or a standalone .djlintrc
file for project-specific settings (profile, indent, max_line_length,
custom rules, ignored rules). Respect these when they exist..pre-commit-config.yaml, note this as [SHOULD_FIX] — the project
should have explicit djlint configuration to avoid ambiguity.djlint --reformat (or the repo's reformat hook) before
running djlint --lint --check. Reformatting resolves most lint issues
automatically.git add <file>)
before running the lint check.[BLOCKING] and suggest using environment variables and 1Password..env, google_creds.json, google_drive_creds.json, etc..gitignore updates where appropriate.[BLOCKING] and recommend a two-step rollout:
[SHOULD_FIX] or [BLOCKING] depending on risk.AGENTS.md:
Query() module-level constants that break parameter
resolution (e.g. Q_INCLUDE_INACTIVE = Query(False, ...)).OptimoEmployeeSurvey or employee_survey.[BLOCKING].In atomic-commit mode (invoked via /backend-atomic-commit:atomic-commit),
you must be very strict:
Atomicity of staged changes
git diff --cached --name-only, determine if staged changes belong
to one coherent change:
survey/ plus an unrelated optimo bugfix and docs tweak.[BLOCKING] if the staged set is clearly multiple logical changes.[SHOULD_FIX] for minor opportunistic cleanups that could be split.All gates must be green
./.security/ruff_pr_diff.sh./.security/local_imports_pr_diff.sh.bin/ruff check / ruff formatty/pyright/mypy).bin/django check / manage.py checkpytest subsets for risky changes.pre-commit-config.yaml./.security/gate_cache.sh
instead of ad-hoc direct invocation.--auto style usage, you may skip conversational confirmation, but
you must not relax these gates.[SHOULD_FIX] and usually [BLOCKING].Commit message generation (no AI signature)
clickup_<ticket_id>_...AGENTS.md: <ticket_id>: Description.commit_msg_hook.py exist:
[SHOULD_FIX] and follow
the documented AGENTS.md convention for suggestions.Your atomic-commit output should include:
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.[BLOCKING] items.You should never encourage the user to run git commit as-is if any
[BLOCKING] issues remain.
In pre-commit mode (invoked via /backend-atomic-commit:pre-commit):
.security/*, active type gate, Django
checks, tests as appropriate).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.
Always structure findings using severity tags and sections:
[BLOCKING] – must be fixed before a commit is considered ready:
.security scripts or pre-commit hooks.AGENTS.md (e.g., Ninja Query constants, legacy
survey models).atomic-commit mode.[SHOULD_FIX] – important, strongly recommended changes:
[NIT] – minor cleanups:
Output shape for both modes:
What’s alignedNeeds changesChecks runProposed 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.
This Skill is designed to work with both Claude Code and OpenAI Codex.
plugins/backend-atomic-commit/commands/).name: backend-atomic-commit.For installation, see this repo's README.md.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.