How the no‑mistakes Database Tracks Run States: pending, running, parked, and awaiting‑agent
The no‑mistakes pipeline engine tracks run states through three coordinated columns in the runs table—status for high‑level lifecycle phases, awaiting_agent_since for gate‑blocked agents, and parked_ms for accumulated wait time—enabling precise observability and crash recovery.
The kunchenguid/no‑mistakes repository implements a durable pipeline runner that persists every execution state to SQLite. Understanding how its database layer tracks transitions between pending, running, parked, and awaiting‑agent states requires examining the Run struct in internal/db/run.go and the specialized mutation helpers that maintain consistency during gate checks and daemon restarts.
Core Database Schema for Run State Tracking
The runs table schema centers on the Run struct, which uses three distinct fields to separate lifecycle status from observational metadata.
The status Column for Lifecycle States
The status field stores the high‑level execution phase as a types.RunStatus enum. Valid values include pending, running, completed, failed, and cancelled. According to the source code in internal/db/run.go, the InsertRun function initializes every new row with status = types.RunPending【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L73-L86】. When a pipeline finishes—regardless of outcome—UpdateRunStatus atomically transitions the run to its terminal state and clears the push_active flag【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L200-L207】.
The awaiting_agent_since Timestamp for Gate Blocking
When a step enters an awaiting‑agent gate (such as awaiting_approval or fix_review), the executor calls SetRunAwaitingAgent, which stamps the current Unix milliseconds into the nullable awaiting_agent_since column【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L41-L46】. A non‑nil value signals that the run is parked, halting further execution until the driving agent responds. This marker is purely observational; gate resolution logic operates independently.
The parked_ms Counter for Telemetry
To support performance analysis, the database maintains parked_ms, an accumulated wall‑clock duration (in milliseconds) spent waiting on gates. The AddRunParkedDuration helper adds a delta to this counter only if the value is greater than zero【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L66-L73】. When an agent finally responds, CompleteRunAwaitingAgent both clears the awaiting_agent_since marker and commits the final interval to parked_ms【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L79-L87】.
Run State Transition Lifecycle
The no‑mistakes engine transitions runs through a deterministic sequence that separates creation, execution, gated waits, and completion.
-
Creation. When a webhook push triggers a pipeline,
InsertRunpersists a row withstatus = RunPendingand zeroed parked metrics. -
Execution Start. The daemon worker picks up the run and calls
UpdateRunStatus(run.ID, types.RunRunning), marking it active. -
Gate Entry. Upon encountering a gate requiring LLM intervention, the executor invokes
SetRunAwaitingAgent(run.ID). The non‑nilawaiting_agent_sincetimestamp now indicates the run is parked and awaiting‑agent input. -
Agent Response. After the agent replies,
ClearRunAwaitingAgent(orCompleteRunAwaitingAgent) removes the marker, allowing the pipeline to resume. -
Completion. Once all steps finish,
UpdateRunStatusmoves the run toRunCompleted,RunFailed, orRunCancelled, preserving the finalparked_msvalue for telemetry.
Crash Recovery via RecoverStaleRuns
If the daemon crashes, the RecoverStaleRuns routine—invoked at startup in internal/daemon/manager.go—identifies runs that were still pending or running and performs three atomic actions: marks them as failed, clears any dangling awaiting_agent_since marker, and adds elapsed parked time to parked_ms so metrics are not lost【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L93-L107】.
Practical Code Examples
The following patterns from internal/db/run.go demonstrate how to manipulate run states in application code:
// Create a new run (status = pending)
run, err := db.InsertRun(repoID, branch, headSHA, baseSHA)
// Mark the run as running
err = db.UpdateRunStatus(run.ID, types.RunRunning)
// When a step hits a gate that needs an LLM:
err = db.SetRunAwaitingAgent(run.ID)
// After the LLM finishes the step:
err = db.ClearRunAwaitingAgent(run.ID)
// Optionally add extra parked time (e.g. after a timeout)
err = db.AddRunParkedDuration(run.ID, extraMS)
// At the end of the pipeline, set final status
err = db.UpdateRunStatus(run.ID, types.RunCompleted)
Summary
- The no‑mistakes database tracks run states using three coordinated fields in
internal/db/run.go:statusfor lifecycle phases,awaiting_agent_sincefor gate blockage, andparked_msfor wait telemetry. - Pending and running states are managed through
InsertRunandUpdateRunStatus, while parked and awaiting‑agent conditions rely onSetRunAwaitingAgentandClearRunAwaitingAgent. - The
RecoverStaleRunsfunction ensures crash safety by failing incomplete runs and preserving parked duration metrics. - All state mutations are atomic and designed to support concurrent pipeline execution without race conditions.
Frequently Asked Questions
What is the difference between the parked and awaiting_agent_since fields?
The awaiting_agent_since column stores a timestamp indicating when a run entered a gate requiring agent approval, signaling that the run is currently awaiting‑agent input. The parked_ms column accumulates the total milliseconds spent in such gates across the entire run lifecycle, providing historical telemetry regardless of current state.
How does no‑mistakes recover runs after a daemon crash?
During startup, the daemon invokes RecoverStaleRuns, which queries for runs with status = RunPending or status = RunRunning, marks them as failed, clears any remaining awaiting_agent_since values, and adds elapsed parked time to parked_ms to prevent metric loss【/cache/repos/github.com/kunchenguid/no-mistakes/main/internal/db/run.go#L93-L107】.
Can a run status move directly from pending to completed?
Yes. If a pipeline encounters an immediate terminal condition (such as a configuration error) before execution begins, UpdateRunStatus can transition the run from pending directly to completed, failed, or cancelled without ever entering the running state.
Where are the RunStatus constants defined?
The RunStatus type and its constants—RunPending, RunRunning, RunCompleted, RunFailed, and RunCancelled—are declared in the types package (conventionally internal/types/status.go) and imported by internal/db/run.go to enforce compile‑time safety on status transitions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →