Self-Healing CI: Building Hooks That Fix Your Pipeline Before You Notice It's Broken

May 03, 2026 • ArchyPress

Architecture diagram showing self-healing CI pipeline with before and after implementation hooks

What if your CI pipeline could fix itself before you even push? Not in a hand-wavy AI way, but through deterministic hooks that run at exactly the right moment in your development workflow. Here's how we built one.

The Problem With Firefighting CI

Every engineering team has a version of this loop: you push code, CI fails, you read the error, fix it locally, push again, wait for CI, and hope it's green this time. On good days it takes one iteration. On bad days — especially when merge conflicts lurk in the background — it takes three or four.

We had just dealt with a particularly frustrating incident where 12 TypeScript errors showed up in CI that were invisible locally (the error was TS2540, covered in our companion posts). The fix was mechanical — a simple typed alias pattern. But the process of discovering the error, diagnosing it, fixing it, and verifying the fix across multiple branches took hours. Not because the fix was hard, but because the feedback loop was slow.

That's when we asked the question: what if the feedback loop ran before the push?

Anatomy of a Hook-Based CI Extension

We use a specification-driven development tool called Speckit that has a concept of implementation phases: before_implement (preparation) and after_implement (verification). Each phase can have hooks — scripts or command definitions that run automatically at the right moment. The hooks are registered in a YAML manifest and executed in priority order.

Architecture diagram showing extension.yml hook registry with before_implement and after_implement phases connecting to CI commands

We built a CI extension that adds two hooks:

  • ci.resolve-conflicts (before_implement): Proactively detects merge conflicts before you start coding

  • ci.verify (after_implement): Runs the full verification suite before your code reaches remote CI

The Before Hook: Conflict Detection

The ci.resolve-conflicts hook runs at the very start of implementation. It does three things:

  1. Fetches the latest remote state for all tracked branches (main, preview, feature branches)

  2. Runs git merge-tree to detect conflicts WITHOUT actually merging anything. This is key — merge-tree is a dry-run merge that tells you if conflicts exist without modifying your working tree.

  3. For predictable conflicts (lock files, generated code, import ordering), it applies automatic resolution strategies. For unpredictable conflicts (business logic, overlapping edits), it stops and tells you exactly what needs manual attention.

The automatic resolution is rule-based, not AI-based. Package lock files always take theirs. Generated files always regenerate from source. Import ordering always re-sorts. These are mechanical resolutions where the correct answer is deterministic. Anything ambiguous gets escalated.

The After Hook: Local Verification

The ci.verify hook is where the real value lives. It runs after implementation is complete but before the code is pushed to remote. The verification sequence is:

  1. TypeScript typecheck (tsc --noEmit) — catches TS2540 and similar strict-mode errors locally

  2. ESLint with auto-fix — catches formatting issues and automatically corrects them

  3. Unit test suite — runs the full test suite, not just changed files

  4. Push to all target branches (main, preview, feature) if everything passes

  5. Monitor GitHub Actions for the first 2-3 minutes to catch environment-specific failures

The critical design decision here is that the hook runs the exact same checks that CI runs remotely. Not a subset. Not an approximation. The same commands, the same configuration, the same error thresholds. If it passes locally, it passes in CI. If it would fail in CI, it fails locally first — where the feedback loop is seconds, not minutes.

Auto-Fix Patterns

The hook includes pattern-specific auto-fix capabilities. When it encounters known error patterns, it applies the fix automatically rather than just reporting the error:

TS2540 (readonly process.env)

Automatically applies the typed alias pattern: creates const env = process.env as Record<string, string | undefined> and rewrites assignments. Deterministic, well-tested, no ambiguity.

ESLint auto-fixable violations

Runs eslint --fix which handles most formatting violations, unused imports, and quote style issues automatically. Only flags as errors those that auto-fix can't handle.

Lock file conflicts

Detects lock file conflicts and regenerates from package.json. No merge strategy needed — just regenerate from the source of truth.

Import ordering conflicts

Re-sorts and deduplicates. The correct merge of two import lists is always the union of both, sorted alphabetically. Deterministic.

Configuration as Code

The entire extension is configured through a YAML file (ci-config.yml) that lives in the repository. This means the CI behavior is version-controlled, reviewable, and consistent across all contributors:

checks:

typecheck: true

lint: true

test: true

build: false # optional, for larger projects

auto_fix:

ts2540_readonly_env: true

eslint_autofix: true

lock_file_conflicts: true

deploy_targets:

- main

- preview

conflict_resolution:

auto_resolve_lock_files: true

auto_resolve_generated: true

require_manual: [src/**/*.ts, src/**/*.tsx]

The require_manual list is important. It explicitly marks paths where automatic conflict resolution is not allowed. Source code conflicts in TypeScript files always need human judgment. The system won't try to be clever where cleverness would be dangerous.

The Extension Architecture

The hook system follows a simple pattern that's easy to extend:

  • Extension manifest (extension.yml): Declares the extension name, version, and available commands

  • Command definitions (commands/*.md): Each command is a markdown file with structured instructions the workflow agent executes

  • Configuration (ci-config.yml): Project-specific settings that control which checks run and which auto-fixes are enabled

  • Registry (.registry): A central file that tracks all installed extensions and their priority order

Priority ordering matters: conflict resolution runs before git commit (priority 30), while verification runs after git commit but before Jira sync (priority 30 after_implement). The ordering ensures that conflicts are resolved before code is committed, and verification happens before the workflow reports success to project management tools.

Architecture diagram showing the self-healing CI pipeline with before and after implementation phases

Results and Impact

Since implementing the CI hooks extension:

  • Zero TS2540 errors have reached CI — the auto-fix catches them locally every time

  • Merge conflicts are detected before coding starts, not during push

  • The average push-to-green time dropped from multiple CI iterations to a single push

  • New team members (and AI contributors) benefit from the same guardrails without configuration

The key insight is that most CI failures are predictable. They follow patterns. And patterns can be automated. Not with AI guessing at fixes, but with deterministic rules that apply the known-correct resolution for each pattern. Save the AI for the creative work. Let the boring stuff be boring and automatic.

Key Takeaways

Deterministic beats probabilistic for CI

If you can describe the fix in an if-then rule, automate it. If you can't, require human review. The boundary between the two is your system's trust boundary.

Hooks should run the same checks as CI

The same pipeline that protects you from your own mistakes should protect you from AI mistakes, merge conflicts, and environmental drift. One pipeline, all authors.

Shift verification left

Catching errors locally (seconds of feedback) vs in CI (minutes of feedback) compounds across every push, every day, every contributor.

Configuration over convention

A YAML config that's version-controlled, reviewable, and explicit is better than a shell script that 'just works' until it doesn't. Make the automation visible.

Automating your CI pipeline?

We write about CI/CD automation, development workflow design, and the engineering practices behind building production applications.

© 2026 Meet Archy
Self-Healing CI: Automated Hooks for Deployment Verification & Conflict Resolution | Archy Engineering | ArchyPress Platform