Can No-Mistakes Ask the User for Input on Findings? Implementation Guide

Yes. No-mistakes can pause pipeline execution and prompt the human operator for decisions when a finding's action is set to ActionAskUser, creating a gate that requires explicit user approval before proceeding.

The open-source no-mistakes repository implements a sophisticated human-in-the-loop workflow that distinguishes between automated fixes and changes requiring human judgment. When a pipeline step produces findings tagged with "ask-user", the executor parks the run, surfaces an awaiting status in the TUI, and generates a prompt for the operator to approve, edit, or skip the proposed change.

How No-Mistakes Implements User Input Requests

The architecture relies on a constant-action pattern within the finding model. When code analysis detects ambiguous or risky conditions that should not proceed automatically, it assigns the ActionAskUser constant to signal that human intervention is required.

The Finding Model Definition

In internal/types/findings.go, the system defines three possible actions for any finding:

const (
    ActionNoOp    = "no-op"
    ActionAutoFix = "auto-fix"
    ActionAskUser = "ask-user"
)

A finding with Action set to ActionAskUser explicitly triggers the user input workflow. This design ensures that automated steps and human gates share the same data structure, allowing the executor to route findings appropriately based on the action type.

Detection Logic

The helper function HasAskUserFindings scans finding collections to determine if any item requires human review:

// internal/types/findings.go
func HasAskUserFindings(findings Findings) bool {
    for _, item := range findings.Items {
        if item.Action == ActionAskUser {
            return true
        }
    }
    return false
}

The pipeline executor invokes this function after every step to decide whether to auto-fix or pause for approval.

The Ask-User Pipeline Flow

When the executor detects ask-user findings, it transitions the run into an awaiting-agent state. This flow involves three core components: the executor's pause logic, the TUI rendering layer, and the prompt generation system.

Executor Pause Logic

In internal/pipeline/executor.go (approximately lines 340-350), the executor checks findings before proceeding:

if !outcome.NeedsApproval && !hasAskUserFindingsJSON(outcome.Findings) {
    // Safe to auto-fix / continue
    ...
} else {
    // Mark the run as awaiting-agent so the UI shows a prompt.
    db.SetRunAwaitingAgent(runID, time.Now())
    // The agent driver will later ask the user.
}

If any ask-user findings exist, the call to db.SetRunAwaitingAgent parks the run immediately. The executor does not apply any automatic fixes, ensuring that potentially risky changes remain pending until a human validates them.

UI Rendering

The TUI aggregates findings by action type in internal/cli/axi_render.go within the findingsTally function:

case types.ActionAskUser:
    awaiting++

This tally appears in the run object as "<n> awaiting", providing immediate visibility into how many decisions the operator must resolve. Additionally, the runObjectFieldWithKey function renders an awaiting_agent field showing the human-readable duration since the run was parked.

Prompt Generation

When the executor reaches a gate containing ask-user findings, the driver in internal/cli/axi_drive.go (around line 470) constructs a human-readable instruction:


CI checks passed - the PR is ready. Ask the user to review and merge it.

This prompt appears when the user runs no-mistakes axi status, followed by a CLI instruction to respond:

no-mistakes axi respond --run <run-id> <decision>

The skill body defined in internal/skill/skill.go reinforces this by including a gate note that explicitly states, "Ask how they want to proceed," ensuring that AI agents interacting with the system recognize the requirement for human input.

Practical Implementation Example

To request user input from within a custom pipeline step, create a finding with the ActionAskUser action:

package main

import (
    "github.com/kunchenguid/no-mistakes/internal/types"
)

func main() {
    // Simulate a pipeline step that discovers a risky change.
    f := types.Finding{
        ID:          "f-001",
        Severity:    "error",
        File:        "cmd/main.go",
        Line:        42,
        Description: "Potential nil-pointer dereference",
        Action:      types.ActionAskUser, // Triggers user prompt
    }

    // The step returns its findings (normally via the pipeline framework):
    findings := types.Findings{
        Items: []types.Finding{f},
        Summary: "1 finding requiring user review",
    }

    // The executor will now park the run and the CLI will show:
    //   awaiting: 1
    // The operator can answer:
    //   $ no-mistakes axi respond --run <run-id> approve
}

When the finding is returned to the pipeline executor, the system automatically pauses execution and surfaces the waiting status in the CLI.

Responding to User Input Requests

Once a run is parked with awaiting_agent status, the operator interacts with the system through two primary commands:

  1. Check status: no-mistakes axi status displays the parked run with the awaiting tally and duration
  2. Submit decision: no-mistakes axi respond --run <id> approve|edit|skip

The internal/e2e/journey_test.go file contains end-to-end tests verifying that runs with ActionAskUser correctly end in a parked state and that user responses properly ungate the pipeline.

Summary

  • Yes, no-mistakes supports requesting user input on findings through the ActionAskUser constant defined in internal/types/findings.go.
  • The pipeline executor detects ask-user findings via HasAskUserFindings and parks the run using SetRunAwaitingAgent.
  • The TUI renders an awaiting tally and awaiting_agent timestamp so operators know exactly which decisions are pending.
  • Users resolve gates via no-mistakes axi respond --run <id> <decision>, allowing explicit approval of risky or ambiguous changes before the pipeline continues.

Frequently Asked Questions

How does no-mistakes distinguish between auto-fixable and human-required findings?

No-mistakes uses the Action field in the Finding struct. When set to ActionAutoFix in internal/types/findings.go, the executor applies changes automatically. When set to ActionAskUser, the executor invokes db.SetRunAwaitingAgent and pauses execution, routing the decision to the human operator instead.

Can I customize the prompt shown to users when asking for input?

Yes. The prompt generation logic in internal/cli/axi_drive.go constructs human-readable instructions based on the finding context. While the default message explains what needs review, you can extend the skill body in internal/skill/skill.go to include specific gate notes that provide additional context about why the finding requires human judgment.

What happens if multiple findings require user input in a single run?

The findingsTally function in internal/cli/axi_render.go aggregates all ask-user findings into a single count. The run remains parked until the user responds with no-mistakes axi respond, at which point the decision applies to the specific run state. The system treats multiple awaiting findings as a single gate that requires resolution before the pipeline can proceed.

Is the ask-user workflow secure for production CI/CD pipelines?

Yes. Because the executor in internal/pipeline/executor.go explicitly checks HasAskUserFindings before applying any fixes, there is no risk of accidental auto-execution for findings marked with ActionAskUser. The run state transitions to awaiting_agent and remains immutable until an authorized operator explicitly responds, ensuring that sensitive or risky changes cannot bypass human review.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →