# How the Intent Step Analyzes Commit Diffs and Assesses Risk in no-mistakes

> Learn how the no-mistakes intent step analyzes commit diffs and assesses risk. It uses LLM agents to score changes, determining auto-fix, approval, or abort actions for seamless code integration.

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

---

**The Intent step extracts the developer’s goal by feeding the commit diff to an LLM agent, then calculates a numeric risk score (0-1) based on diff magnitude and critical file paths to govern whether the pipeline auto-fixes, asks for approval, or aborts.**

The `no-mistakes` repository implements a pipeline-based automation framework that treats the **Intent step** as the mandatory first stage of every run. This step analyzes the raw `git diff` output to infer high-level developer intent and assess potential risks before downstream steps execute. By deriving both semantic intent and quantitative risk from the same diff data, the pipeline determines when it can safely auto-fix code versus when it must request explicit human approval.

## Extracting Intent from Commit Diffs

The Intent step begins by generating a machine-readable representation of the changes. In [`internal/pipeline/steps/intent.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent.go), the `IntentStep.Run` method calls `common_diff.Generate` from [`internal/pipeline/steps/common_diff.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/common_diff.go) to execute `git diff --cached` (or the appropriate range) and capture added, removed, or modified lines.

This diff data becomes the primary context for the LLM agent. The `runIntent` helper constructs a prompt via `intentPrompt` in [`internal/pipeline/steps/intent_prompt.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent_prompt.go), which packages the diff alongside any existing commit messages. The LLM (Claude, Codex, or similar) returns a structured `intent.Result` containing a concise intent string, confidence score, model name, and session ID.

```go
// internal/pipeline/steps/intent.go – runIntent wrapper
func (s *IntentStep) Run(ctx context.Context, sctx *pipeline.StepContext) error {
    // 1️⃣ Gather diff for the step context
    diff, err := common_diff.Generate(sctx.Repo, sctx.Branch)
    if err != nil { return err }

    // 2️⃣ Build LLM prompt (includes diff and any prior intent)
    prompt := intentPrompt(sctx, diff)

    // 3️⃣ Call the LLM agent (Claude, Codex, etc.)
    rsp, err := s.runIntent(ctx, sctx) // LLM returns intent.Result
    if err != nil {
        // No intent → step is skipped
        return pipeline.ErrSkip
    }

    // 4️⃣ Store sanitized intent
    cleaned := sanitizeIntent(rsp.Summary)
    sctx.Run.Intent = &cleaned
    sctx.Run.IntentSource = &rsp.Source
    sctx.Run.IntentScore = &rsp.Score
    // Persist to DB (omitted for brevity)
    return nil
}

```

## Sanitizing and Persisting Intent Results

Once the LLM returns the raw intent, `IntentStep` sanitizes the text by removing markup or disallowed words before persisting it. The cleaned data is written to the run record fields `db.Run.Intent`, `IntentSource`, and `IntentScore`, while also being attached to the in-memory `StepContext` as `sctx.UserIntent`.

This dual storage ensures that subsequent steps can reference the intent without re-querying the database. The `StepContext` acts as the single source of truth for the remainder of the pipeline, carrying both the semantic intent and the raw diff data forward to risk calculation.

## Computing Risk from Diff Heuristics

While the Intent step itself does not assign risk labels, it provides the necessary inputs for the **PR-summary risk** calculation performed later in [`internal/pipeline/steps/prsummary_risk.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/prsummary_risk.go). This step receives the same `git.DiffResult` and the extracted intent, then applies deterministic heuristics:

- **Large-scale file additions or deletions** trigger high risk flags, indicating potential breaking changes.
- **Modifications to critical directories** such as `cmd/` or `internal/`, or changes to build scripts, elevate risk to moderate.
- **Pure documentation or formatting changes** result in low risk classifications.

The `assessRisk` function parses the diff using utilities from [`common_diff.go`](https://github.com/kunchenguid/no-mistakes/blob/main/common_diff.go) to count added and removed lines while detecting file-type patterns. It returns a normalized risk score between 0 and 1, which is stored on the `Run` object as `Run.RiskAssessment`.

```go
// internal/pipeline/steps/prsummary_risk.go – simple risk heuristics
func assessRisk(diff git.DiffResult, intent string) float64 {
    // count added/removed lines
    linesChanged := diff.AddedLines + diff.RemovedLines

    // penalise changes to core packages
    corePenalty := 0.0
    for _, f := range diff.Files {
        if strings.HasPrefix(f, "cmd/") || strings.HasPrefix(f, "internal/") {
            corePenalty += 0.2
        }
    }

    // Base risk on magnitude (capped at 1.0)
    base := math.Min(float64(linesChanged)/500, 1.0) // 500 lines = high risk
    return math.Min(base+corePenalty, 1.0)
}

```

## Gating Downstream Actions

Subsequent steps in [`internal/pipeline/steps/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/review.go) and [`internal/pipeline/steps/push.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/push.go) read `sctx.UserIntent` and `sctx.RiskAssessment` to implement policy decisions:

- **Low risk** (score near 0): The pipeline may automatically apply fixes using `auto-fix` actions.
- **Moderate risk**: The pipeline transitions to `ask-user` mode, requiring explicit confirmation before proceeding.
- **High risk** (score approaching 1): The pipeline aborts or enforces explicit approval gates to prevent potentially destructive changes.

This architecture ensures that the **intent step analyze commit diffs** not only for semantic understanding but also to calibrate the pipeline’s aggression level.

## Transparency in Pull Request Output

The final PR body, generated by [`internal/pipeline/steps/pr.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/pr.go), surfaces both the intent and risk assessment to human reviewers. The `prependIntentSection` function inserts a `## Intent` section containing the sanitized intent string, while [`prsummary.go`](https://github.com/kunchenguid/no-mistakes/blob/main/prsummary.go) adds a `## Risk Assessment` section explaining the numerical score and triggering factors.

```go
// internal/pipeline/steps/pr.go – prepend Intent and Risk sections
func prependIntentSection(body string, sctx *pipeline.StepContext) string {
    cleaned := cleanedUserIntent(sctx) // removes empty or unsafe tags
    if cleaned == "" { return body }
    return "## Intent\n\n" + cleaned + "\n\n" + body

}

```

This visibility ensures that reviewers understand both what the developer intended to achieve and why the pipeline classified the change as low, moderate, or high risk.

## Summary

- **Diff generation**: `common_diff.Generate` in [`internal/pipeline/steps/common_diff.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/common_diff.go) produces the machine-readable diff that feeds both intent extraction and risk analysis.
- **Intent extraction**: `runIntent` in [`internal/pipeline/steps/intent.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent.go) prompts an LLM with the diff to derive a structured intent result and confidence score.
- **Risk calculation**: `assessRisk` in [`internal/pipeline/steps/prsummary_risk.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/prsummary_risk.go) applies heuristics to the diff and intent to compute a 0-1 risk score based on line counts and critical file paths.
- **Policy enforcement**: Downstream steps like [`review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/review.go) and [`push.go`](https://github.com/kunchenguid/no-mistakes/blob/main/push.go) use `sctx.RiskAssessment` to choose between `auto-fix`, `ask-user`, or abort actions.
- **Transparency**: The final PR includes explicit Intent and Risk Assessment sections generated by [`pr.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pr.go) and [`prsummary.go`](https://github.com/kunchenguid/no-mistakes/blob/main/prsummary.go).

## Frequently Asked Questions

### How does the Intent step in no-mistakes extract intent from commit diffs?

The `IntentStep` calls `common_diff.Generate` to capture the current `git diff`, then passes this data to `runIntent` in [`internal/pipeline/steps/intent.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent.go). This function constructs a prompt via `intentPrompt` that includes the diff and commit context, which is sent to an LLM agent (Claude, Codex, etc.) to infer the developer’s high-level goal.

### What risk factors does the no-mistakes pipeline evaluate during the Intent step?

While the Intent step provides the raw data, the risk assessment in [`internal/pipeline/steps/prsummary_risk.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/prsummary_risk.go) evaluates three primary factors: the total number of added and removed lines (magnitude), changes to critical directories like `cmd/` or `internal/`, and the presence of build script modifications versus documentation-only edits.

### How does the risk assessment influence downstream pipeline actions?

Downstream steps check `sctx.RiskAssessment` to determine automation policy. Low-risk changes allow `auto-fix` actions, moderate-risk changes trigger `ask-user` approval prompts, and high-risk changes cause the pipeline to abort or require explicit human sign-off before proceeding to steps like rebase or push.

### Where does no-mistakes store the extracted intent and risk scores?

The Intent step persists sanitized results to the database fields `db.Run.Intent`, `IntentSource`, and `IntentScore`, while also caching them in the in-memory `StepContext` as `sctx.UserIntent`. The risk score is stored as `Run.RiskAssessment` and remains accessible to all subsequent pipeline steps via the shared context.