# How no-mistakes Orchestrates Pipeline Steps: Review, Test, Lint, Docs, Push, PR, and CI

> Learn how no-mistakes orchestrates review test lint docs push PR and CI pipeline steps sequentially a central executor shares state and pauses for human review gates

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: deep-dive
- Published: 2026-07-02

---

**The no-mistakes CLI orchestrates review, test, lint, docs, push, PR, and CI pipeline steps through a sequential executor that runs each step in order while sharing state via an `executionContext`, pausing for human review gates when needed.**

The `no-mistakes` repository implements a robust automation framework that coordinates complex software development workflows through a deterministic **pipeline**. Its architecture executes discrete steps—from initial intent parsing through continuous integration monitoring—while maintaining safety through lease-guarded operations and human-in-the-loop gates. Understanding how these **pipeline steps** are orchestrated reveals the extensible design patterns that make the tool suitable for both manual CLI usage and autonomous agent operation.

## The Core Pipeline Architecture

All steps in the no-mistakes pipeline implement a common interface defined in [`internal/pipeline/steps/common.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/common.go). The orchestrator creates a **run** object, builds the step list, and executes them sequentially while passing a shared `executionContext` to each step.

Each step resides in its own source file under `internal/pipeline/steps/` and follows a consistent pattern: initialize state, execute core logic, record results to the database, and return control to the executor.

## The Eight Pipeline Steps Explained

The default step order is defined as a static slice in the executor. While users can trim or reorder steps via configuration, the standard sequence follows the development lifecycle from intent to CI monitoring.

### Intent: Parsing User Commands

The **intent** step ([`internal/pipeline/steps/intent.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent.go)) parses the user's request to determine which subsequent steps are required. For example, a command to only run tests will trim the lint, push, and PR steps from the execution list.

### Review: Human-in-the-Loop Gates

When a run requires human validation, the **review** step ([`internal/pipeline/steps/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/review.go)) creates a gate that pauses execution. It sets `awaiting_agent_since` in the database via `db.SetRunAwaitingAgent` and surfaces findings to the user. The run remains in a "parked awaiting agent" state visible in `axi status` until the user responds, at which point `db.ClearRunAwaitingAgent` clears the flag and execution resumes.

### Test: Executing the Test Suite

The **test** step ([`internal/pipeline/steps/test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/test.go)) executes the repository's test suite using `go test -race ./...` by default. Results are stored in the SQLite database ([`internal/db/run.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/run.go)) and displayed in the CLI UI ([`internal/cli/axi_render.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/cli/axi_render.go)). Failures generate evidence objects that can trigger auto-fix routines.

### Lint: Static Analysis and Evidence Generation

Running configured linters (such as `golint` or `staticcheck`), the **lint** step ([`internal/pipeline/steps/lint.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/lint.go)) converts failures into structured **evidence** objects. These evidence artifacts, defined in [`internal/pipeline/steps/evidence.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/evidence.go), enable the auto-fix system to programmatically correct issues without human intervention.

### Document: Documentation Generation

The **document** step ([`internal/pipeline/steps/document.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/document.go)) acts as a thin wrapper around repository-specific documentation commands. It generates or validates markdown and API documentation, ensuring artifacts remain current before pushing to remote.

### Push: Lease-Guarded Force Strategy

Before pushing changes, the **push** step ([`internal/pipeline/steps/push.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/push.go)) calls `resolveForcePushDecision` from [`internal/pipeline/steps/forcepush.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go) to prevent accidental loss of upstream work. The safety check compares the remote tip against the last-seen SHA using `git rev-list --cherry-pick`. If the push would discard commits not part of the current run, the step aborts with `forcePushWouldDiscardError`.

### PR: Opening and Updating Pull Requests

The **pr** step ([`internal/pipeline/steps/pr.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/pr.go)) opens or updates Pull Requests on configured SCM platforms (GitHub, GitLab, Bitbucket). It generates a formatted summary using [`prsummary.go`](https://github.com/kunchenguid/no-mistakes/blob/main/prsummary.go) and attaches relevant evidence and test results to the PR description.

### CI: Monitoring and Auto-Fixing

Finally, the **ci** step ([`internal/pipeline/steps/ci.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/ci.go)) monitors the CI pipeline for the PR. It implements timeout logic using the `ci_timeout` configuration from [`internal/config/config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/config/config.go), re-arming the idle timeout when the upstream default branch advances. The step auto-fixes failing checks when possible and re-bases the branch if the target changes.

## How the Executor Orchestrates Steps

The pipeline execution follows a strict lifecycle managed by the executor in [`internal/pipeline/steps/common.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/common.go).

First, the CLI creates a **run** record in the SQLite database. Then, `pipeline.NewRunExecutor` builds the step slice:

```go
steps := []pipeline.Step{
    intent.New(),
    review.New(),
    test.New(),
    lint.New(),
    document.New(),
    push.New(),
    pr.New(),
    ci.New(),
}

```

The executor initializes an `executionContext` ([`internal/pipeline/steps/execution_context.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/execution_context.go)) containing references to the repository, database transaction, logger, and a `StepState` map. It then iterates through the steps, calling `step.Run(ctx)` for each.

After each step, the executor checks `ctx.State.IsCancelled()` or the `awaiting_agent_since` flag. If a gate is hit, the run persists to the database and returns control to the CLI. Otherwise, the executor records the `StepResult` (success status and evidence) and proceeds to the next step.

## Safety Mechanisms and State Management

The orchestration layer implements several safety mechanisms to prevent data loss and ensure reliable execution.

**Force-Push Safety**: The push step uses `resolveForcePushDecision` to verify that force-pushing will not discard upstream commits. It aborts with an error if the safety check fails, protecting against race conditions with other developers.

**Evidence and Auto-Fix**: Steps can produce evidence objects that describe failures in a machine-readable format. When the executor detects auto-fixable evidence, it calls `runFix` from [`internal/pipeline/steps/common_fix.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/common_fix.go) to automatically correct issues before proceeding.

**Database Persistence**: Run state, including the awaiting-agent timestamp and step results, persists to [`internal/db/run.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/run.go). This allows the CLI to resume interrupted runs and enables the `axi` commands to display live, color-coded progress bars.

## Summary

- **Sequential Execution**: The executor runs steps in a fixed order (intent → review → test → lint → document → push → pr → ci) defined in [`internal/pipeline/steps/common.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/common.go).
- **Shared Context**: Each step receives an `executionContext` containing the repository, database handle, and logger, enabling stateful operations across the pipeline.
- **Human Gates**: The review step pauses execution by setting `awaiting_agent_since`, allowing human validation before continuing.
- **Safety First**: The push step implements lease-guarded force-push logic via `resolveForcePushDecision` to prevent accidental commit loss.
- **Auto-Fix Capability**: Lint, test, and CI steps generate evidence that triggers automatic fixes through `runFix` when possible.
- **CI Monitoring**: The CI step monitors external pipelines with configurable timeouts and auto-rebases when target branches change.

## Frequently Asked Questions

### How does no-mistakes handle pipeline interruptions or user review?

When a step requires human intervention, the review step sets `awaiting_agent_since` in the database via `db.SetRunAwaitingAgent` and returns control to the CLI. The run enters a "parked awaiting agent" state visible in `axi status`. Once the user responds, `db.ClearRunAwaitingAgent` clears the flag and the executor resumes from the next step.

### What prevents no-mistakes from overwriting remote commits during push?

The push step calls `resolveForcePushDecision` in [`internal/pipeline/steps/forcepush.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go) to compare the remote tip with the last-seen SHA using `git rev-list --cherry-pick`. If the push would discard any upstream commits not present in the current run, the step aborts with `forcePushWouldDiscardError`, preventing accidental loss of work.

### Can individual pipeline steps be skipped or reordered?

Yes. The intent step ([`internal/pipeline/steps/intent.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent.go)) parses the user's command to determine which steps are necessary. Users can configure the pipeline to skip specific steps (such as linting) or the executor can trim the default step slice before execution begins.

### How does the CI step handle long-running pull requests?

The CI step uses the `ci_timeout` configuration from [`internal/config/config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/config/config.go). It re-arms the idle timeout whenever the upstream default branch advances, ensuring that long-lived PRs are not terminated merely because they remain open. The step also auto-fixes failing checks and re-bases the branch when the target changes.