# Understanding the no-mistakes Database Schema: Runs, Steps, and Checkpoints

> Discover the no-mistakes database schema for immutable audit trails and checkpoint recovery. Learn about runs, steps, and checkpoints in this SQLite hierarchy for reliable pipeline execution.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: internals
- Published: 2026-06-30

---

**The no-mistakes database schema implements a three-tier SQLite hierarchy—`runs`, `step_results`, and `step_rounds`—to create an immutable audit trail of pipeline executions with full checkpoint recovery capabilities.**

The `kunchenguid/no-mistakes` repository stores pipeline execution history in a single SQLite file using a relational schema designed for observability and resumption. This **no-mistakes database schema** organizes every pipeline execution into discrete runs, ordered steps, and granular checkpoints that capture agent findings and user interactions.

## The Three-Tier Hierarchy

The schema centers on three primary tables that form a strict parent-child relationship: each run contains multiple steps, and each step contains multiple checkpoint rounds. This design enables the daemon to resume, re-run, or diagnose past pipeline executions with full fidelity.

### The runs Table (Pipeline Executions)

The `runs` table, defined in [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go) at lines 13-25, represents a single pipeline execution. Key columns include `id`, `repo_id`, `branch`, `head_sha`, `base_sha`, `status`, `pr_url`, `error`, `awaiting_agent_since`, `created_at`, and `updated_at`. The `repo_id` column establishes a foreign key relationship to the `repos` table, linking each run to its source repository while maintaining Git context through SHA references.

### The step_results Table (Individual Steps)

Defined at lines 27-40 of [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go), the `step_results` table records each pipeline step such as lint, test, or review. Critical columns include `run_id`, `step_name`, `step_order`, `status`, `exit_code`, `duration_ms`, `log_path`, `findings_json`, `error`, `started_at`, and `completed_at`. The `run_id` foreign key ties each step to its parent run, while `step_order` preserves execution sequence.

### The step_rounds Table (Checkpoints)

The `step_rounds` table, located at lines 42-54 of [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go), captures each checkpoint round where an agent produces findings or a user makes a selection. This table stores `step_result_id`, `round`, `trigger_type`, `findings_json`, `user_findings_json`, `selected_finding_ids`, `selection_source`, `fix_summary`, `duration_ms`, and `created_at`. The `step_result_id` foreign key links rounds to specific steps, enabling granular audit trails.

## Schema Implementation and Migrations

The `no-mistakes` source code defines the schema in [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go) and manages database lifecycle in [`internal/db/db.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/db.go). The [`db.go`](https://github.com/kunchenguid/no-mistakes/blob/main/db.go) file opens the SQLite connection and executes the schema SQL alongside migration statements to maintain backward compatibility with existing databases.

Migration logic appears at lines 65-79 of [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go), which includes statements like adding the `awaiting_agent_since` column to the `runs` table. This ensures older database files automatically upgrade to the current schema version without manual intervention.

## Working with the Database (Code Examples)

The repository provides type-safe Go structs and CRUD helpers across four dedicated files:

- **[`internal/db/run.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/run.go)** – Struct and helpers for the `runs` table
- **[`internal/db/step.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/step.go)** – Struct and helpers for `step_results`
- **[`internal/db/round.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/round.go)** – Struct and helpers for `step_rounds`
- **[`internal/db/db.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/db.go)** – Database initialization and connection management

Creating a new run record:

```go
// Create a new Run record
run := db.Run{
    ID:        uuid.NewString(),
    RepoID:    repo.ID,
    Branch:    "feature/foo",
    HeadSHA:   "abc123",
    BaseSHA:   "def456",
    Status:    db.StatusPending,
    CreatedAt: time.Now().Unix(),
}
if err := db.InsertRun(ctx, run); err != nil { … }

```

Inserting a step result:

```go
// Insert a StepResult for the "lint" step of a run
step := db.StepResult{
    ID:        uuid.NewString(),
    RunID:     run.ID,
    StepName:  "lint",
    StepOrder: 2,
    Status:    db.StatusPending,
    CreatedAt: time.Now().Unix(),
}
if err := db.InsertStepResult(ctx, step); err != nil { … }

```

Recording a checkpoint round:

```go
// Record a checkpoint (round) when the agent produces findings
round := db.StepRound{
    ID:                uuid.NewString(),
    StepResultID:      step.ID,
    Round:             1,
    TriggerType:       "agent",
    FindingsJSON:      findingsJSON,
    DurationMS:        int64(duration / time.Millisecond),
    CreatedAt:         time.Now().Unix(),
}
if err := db.InsertStepRound(ctx, round); err != nil { … }

```

## Summary

- The **no-mistakes database schema** uses SQLite to store pipeline execution data in three hierarchical tables: `runs`, `step_results`, and `step_rounds`.
- Schema definitions reside in [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go) with specific line ranges for each table (lines 13-25, 27-40, and 42-54).
- Migration support at lines 65-79 ensures schema evolution without data loss when upgrading existing databases.
- Four Go files—[`run.go`](https://github.com/kunchenguid/no-mistakes/blob/main/run.go), [`step.go`](https://github.com/kunchenguid/no-mistakes/blob/main/step.go), [`round.go`](https://github.com/kunchenguid/no-mistakes/blob/main/round.go), and [`db.go`](https://github.com/kunchenguid/no-mistakes/blob/main/db.go)—provide type-safe access to the database with `InsertRun`, `InsertStepResult`, and `InsertStepRound` functions.
- The design enables full audit trails, step resumption, and checkpoint recovery for CI/CD pipelines through strict foreign key relationships.

## Frequently Asked Questions

### What database does no-mistakes use for tracking pipeline executions?

The `no-mistakes` project uses **SQLite** as its embedded database engine. The system stores all execution history in a single SQLite file, making it lightweight and portable while still supporting complex relational queries across the `runs`, `step_results`, and `step_rounds` tables.

### How does the schema handle database migrations?

According to the source code in [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go) (lines 65-79), the schema includes migration statements that run automatically when the database opens. For example, the migration adds the `awaiting_agent_since` column to the `runs` table if it doesn't exist, ensuring older databases remain compatible with newer code versions.

### What is the relationship between runs and step_results in the schema?

The relationship is **one-to-many**. Each record in the `runs` table (defined at lines 13-25 of [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go)) can have multiple associated records in `step_results` (lines 27-40), linked via the foreign key `run_id`. This design allows a single pipeline execution to track multiple discrete steps like linting, testing, and code review in sequential order.

### Can step_rounds store both agent findings and user selections?

Yes. The `step_rounds` table (defined at lines 42-54 of [`internal/db/schema.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/schema.go)) contains both `findings_json` for automated agent outputs and `user_findings_json` for manual user input. It also stores `selected_finding_ids` and `selection_source` to track which specific findings were chosen and whether the selection came from a user or an automated process.