Safe Commit Push CI
Use this skill when the goal is to ship local work safely to origin/dev, fix CI failures quickly, and repeat until required checks are green.
Hardcoded Safety Baseline (non-negotiable)
This skill must align with enforced repo controls, not just documentation:
.claude/hooks/pre-tool-use-git-safety.shscripts/agent-bin/gitscripts/git-hooks/require-writer-lock.shscripts/git-hooks/pre-push-safety.shscripts/git-hooks/prepare-commit-msg-safety.shscripts/git-hooks/pre-rebase-safety.shAGENTS.mddocs/git-safety.mdscripts/__tests__/git-safety-policy.test.ts
Hard-blocked command classes
Never use:
- destructive resets and cleans (
git reset --hard|--merge|--keep,git clean -f*) - history rewrite (
git rebase,git commit --amend, force-push variants) - hook bypass (
--no-verify,-n,-c core.hooksPath,git config core.hooksPath) - bulk discard (
git checkout -- ., directory/glob/multi-path checkout/restore,git switch --discard-changes,checkout -f) - stash mutation operations (
git stashbare,git stash push|pop|apply|drop|clear) git worktree(repo policy forbids worktrees for agent flow)
Bypass flags/env (human-only, never for agent flow)
Do not use:
SKIP_WRITER_LOCK=1SKIP_SIMPLE_GIT_HOOKS=1ALLOW_GIT_REBASE=1ALLOW_COMMIT_MSG_REUSE=1ALLOW_COMMIT_ON_PROTECTED_BRANCH=1--no-verify/-n
Always confirm first (model-layer gate — not covered by git hooks)
Even in fully autonomous / -a never mode, stop and ask the user explicitly before running:
wrangler deployto production (irreversible live deploy)prisma migrate deploy(irreversible schema migration)git branch -D <branch>(branch deletion, no hook fires)- Any
--forceor-fflag on destructive commands not already listed above
These are not blocked by git hooks or sandbox mode. The model must enforce this gate itself.
Safe sharp tools (allowed, still use carefully)
git reset HEAD <file>(unstage only)git restore --staged <file>(unstage only)git clean --dry-run/git clean -n(preview only)git stash list|show(read-only only; see stash policy)
Runtime Bounds
max_attempts: 3 push/fix loops per requestmax_duration: 90 minutes wall clock- On bound hit, stop and report blocker, attempted fixes, and next highest-leverage action
Required Execution Mode
In non-interactive agent mode, run each write-related command through integrator command mode:
scripts/agents/integrator-shell.sh -- <command> [args...]
This gives both:
- single-writer lock
- git guard wrapper
Do not use plain git commit/git push without integrator wrapper.
Workflow
1) Preflight
Run:
git status --short
git branch --show-current
git fetch origin --prune
Rules:
- default shipping branch is
dev - if current branch is
main,master, orstaging, switch todevbefore committing - never push directly to protected branches (
pre-push-safety.shblocks it anyway)
Optional mode:
dry-run: perform checks/analysis and propose fixes, but do not commit/push
2) Lock Readiness and Wait Handling
Before first write command:
scripts/git/writer-lock.sh status
If lock is held:
scripts/git/writer-lock.sh clean-stale # only if holder PID is dead on this host
Then proceed with integrator-shell write commands; it waits for lock availability.
If wait is unexpectedly long, re-check status and report lock holder details.
3) Mixed Local Edits and Stash Policy
Default policy is no new stashes.
Rationale:
- hard guards block all stash mutations (
stashbare,push|pop|apply|drop|clear) - creating a stash that cannot be safely restored/cleared creates hidden debt
Required behavior:
- stage only intended files with explicit paths
- leave unrelated edits unstaged and untouched
- if unrelated edits make safe shipping impossible, stop and ask user for direction
- if pre-existing stash entries exist, report them but do not mutate them
4) Stage Intended Changes
Use explicit paths:
scripts/agents/integrator-shell.sh -- git add <file1> <file2> ...
Avoid broad staging when unrelated work is present.
5) Validate Before Commit
Run:
bash scripts/validate-changes.sh
Default behavior is policy + typecheck + lint (VALIDATE_INCLUDE_TESTS=0). Required test gating is handled by GitHub Actions (Core Platform CI + Merge Gate).
Optional local targeted-test pass when needed:
VALIDATE_INCLUDE_TESTS=1 bash scripts/validate-changes.sh
If validation fails:
- Check Codex availability and delegate typecheck/lint fixes:
Ifnvm exec 22 codex --version >/dev/null 2>&1 && CODEX_OK=1 || CODEX_OK=0CODEX_OK=1: run/ops-ci-fix(reads.claude/skills/ops-ci-fix/SKILL.mdand offloads to Codex). IfCODEX_OK=0: fix root cause locally. - Re-run
bash scripts/validate-changes.shuntil green.
Testing guardrails while fixing:
- do not run unfiltered
pnpm test - use targeted tests and
--maxWorkers=2for broader test runs - check for orphaned test processes first (
ps aux | grep jest | grep -v grep)
6) Commit
Commit with integrator wrapper:
scripts/agents/integrator-shell.sh -- git commit -m "<message>"
If hooks fail (typecheck or lint):
- Check Codex availability and run
/ops-ci-fixif available (same CODEX_OK check as step 5). - Once ops-ci-fix reports clean, retry with a new commit (no amend flow).
7) Push
Push with integrator wrapper:
scripts/agents/integrator-shell.sh -- git push origin dev
If rejected (non-fast-forward), follow conflict-safe merge flow below.
8) Conflict-Safe Merge Flow (no-loss)
When remote advanced:
- Create a safety anchor:
git rev-parse HEAD
scripts/agents/integrator-shell.sh -- git branch "backup/pre-merge-$(date +%Y%m%d-%H%M%S)"
- Merge remote branch additively:
git fetch origin --prune
scripts/agents/integrator-shell.sh -- git merge --no-ff origin/dev
- If conflicts exist:
git diff --name-only --diff-filter=U
- resolve file-by-file manually
- do not use bulk ours/theirs checkout
- inspect 3-way content when needed:
git show :1:path/to/file # base
git show :2:path/to/file # ours
git show :3:path/to/file # theirs
- Lockfile conflicts:
- prefer regeneration over manual splice when appropriate (example:
pnpm-lock.yamlviapnpm install --lockfile-only) - re-run validation after regeneration
- Post-merge loss check:
git diff --name-status ORIG_HEAD..HEAD
If unexpected deletions or broad rewrites appear, stop and escalate.
- Re-run
bash scripts/validate-changes.sh, then push again.
9) CI Watch and Auto-Fix Loop
After each push:
- Capture pushed SHA:
git rev-parse HEAD
- Poll runs:
gh run list --branch dev --limit 50 --json databaseId,headSha,workflowName,status,conclusion,url
- Filter to
headSha == <current sha>only. - Ignore stale failures from older SHAs.
- Wait for required workflows for current SHA to finish.
On failure:
- fetch failed logs:
gh run view <run-id> --log-failed
- reproduce locally
- if the failure is typecheck or lint: run
/ops-ci-fix(delegates to Codex if available, falls back to inline) - if the failure is something else: implement fix manually
- run
bash scripts/validate-changes.sh - commit + push
- restart CI watch for new SHA
Exit only when required workflows for current SHA are green.
Required Workflow Policy
Evaluate required checks in this order:
- If
Merge Gateexists for current SHA, treat it as required gate. - Always require
Core Platform CIfor dev shipping. - Also require any of these if they ran for current SHA:
Deploy PrimeDeploy BriketteDeploy CMSDeploy SkylarDeploy Business OSDeploy Product PipelineDeploy XA (Stealth Staging)Validate ReceptionLighthouse CI
10) Failure Classification Policy
Classify before changing code:
code: deterministic test/lint/type/runtime failure reproducible locally- fix in code, validate, commit, push
infra: runner/network/cache/API timeout/transient platform issue- rerun once:
gh run rerun <run-id> --failed
- if same infra signature repeats, escalate with logs
unknown: cannot classify with confidence- gather logs + repro attempts, then escalate
Do not produce code churn for clear infra-only failures.
11) CI Improvement Scan
At completion (or bound hit), report top 3 CI improvement opportunities:
- repeated failure classes and where to shift-left checks
- flaky tests and stabilization options
- slowest workflows/jobs and cache miss hotspots
- missing local preflight checks that could prevent remote failures
Output to User
Always report:
- branch + SHA pushed
- attempts used and elapsed duration
- workflows evaluated and final CI result
- fixes applied during loop
- CI improvement opportunities
- blocker + next step if not green
Use this report shape:
## Ship Report
- Mode: [normal|dry-run]
- Branch: dev
- SHA: <head-sha>
- Attempts: <n>/<max_attempts>
- Duration: <elapsed>
- Required workflows: [list]
- CI result: [pass|fail|partial]
## Changes
- Commit: <sha> - <message>
- Commit: <sha> - <message>
## Failures Handled
- Workflow: <name>
- Root cause: <code|infra|unknown>
- Action: <fix|rerun|escalate>
- Outcome: <passed|failed|pending>
## CI Improvements (Top 3)
1. <improvement> - Impact: <...> - Proposed change: <...>
2. <improvement> - Impact: <...> - Proposed change: <...>
3. <improvement> - Impact: <...> - Proposed change: <...>
## If Not Green
- Blocker: <specific blocker>
- Next step: <single highest-leverage action>