# How the Combined Document and Lint Housekeeping Pass Works in no-mistakes

> Discover how the combined document and lint housekeeping pass in no-mistakes streamlines your workflow by merging documentation updates and lint checks into one LLM agent call. Reduce costs and latency.

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

---

**The combined document and lint housekeeping pass merges documentation updates and lint checks into a single LLM agent invocation, eliminating the cost and latency of a second cold-start when the repository configuration leaves lint commands empty.**

The **no-mistakes** repository implements an optimized pipeline stage that consolidates what would normally be two separate agent runs into one efficient operation. This design targets scenarios where `commands.lint` is not configured, allowing the documentation step to absorb linting responsibilities and store results in shared pipeline context for later retrieval. By avoiding redundant agent initialization, the system reduces both execution time and API costs while maintaining full analytical coverage.

## Why Combine Documentation and Linting?

The pipeline typically executes documentation generation and lint checking as distinct steps, each triggering its own agent invocation. When the repository configuration leaves `commands.lint` empty, the **document step** automatically detects this condition and activates the combined pass mode.

Rather than handing off to a separate lint agent, the document step appends a hidden **lint section** to its own prompt. This architectural decision prevents the second cold-start latency inherent to LLM-powered agents. The document step then records the lint findings in a shared struct (`HousekeepingLintResult`), allowing the subsequent lint step to detect these results and skip its own agent call entirely.

## Prompt Construction for the Housekeeping Pass

In [`internal/pipeline/steps/document.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/document.go), the system constructs a specialized prompt that extends the standard documentation request with linting instructions. The prompt uses a dedicated schema that adds a top-level `Category` field to distinguish housekeeping findings.

```go
const housekeepingLintSection = `
{
  "purpose": "housekeeping",
  "section": "lint",
  "schema": ` + string(housekeepingFindingsSchema) + `
}
`

```

The prompt's purpose is explicitly set to `"housekeeping"` with an introductory directive stating: *"Perform the combined documentation and lint housekeeping pass for this change."* This raw JSON schema (`housekeepingFindingsSchema`) extends the regular `findingsSchema` used elsewhere in the codebase, ensuring the agent returns structured data compatible with the pipeline's expectations.

## Result Handling and Shared State

After the agent returns its response, the document step parses the combined JSON output. Successful parsing extracts the lint findings and stores them in the shared pipeline context via the `SetHousekeepingLint` method.

```go
var findings types.Findings
if err := json.Unmarshal(agentResult.Output, &findings); err != nil {
    // unparsable → request human approval
    return documentApprovalOutcome("combined housekeeping lint result unreadable"), nil
}
sctx.Shared.SetHousekeepingLint(pipeline.HousekeepingLintResult{
    FindingsJSON: agentResult.Output,
    Summary:      fmt.Sprintf("%d unresolved items", len(findings.Items)),
})

```

The **lint step** in [`internal/pipeline/steps/lint.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/lint.go) checks for this shared state before invoking its own agent. When `sctx.Shared.HousekeepingLint()` returns a non-nil result, the step logs the reuse and skips the redundant invocation:

```go
if sctx.Shared.HousekeepingLint() != nil {
    // Re‑use the findings from the document step
    lintFindings := sctx.Shared.HousekeepingLint()
    sctx.Log(fmt.Sprintf(
        "housekeeping lint result recorded for the lint step: %d unresolved items",
        len(lintFindings.Findings.Items),
    ))
    return nil
}
// …otherwise run the normal lint agent

```

## Error Handling and Safety Mechanisms

If the combined result cannot be parsed as valid JSON, the document step triggers a safety gate rather than failing silently. The `documentApprovalOutcome` function forces human intervention when the message reads *"combined housekeeping lint result unreadable"*. This ensures that malformed agent outputs do not propagate corrupted data through the pipeline or skip critical lint checks without operator awareness.

## Testing and Verification

The implementation includes targeted tests that verify the single-invocation guarantee and end-to-end behavior:

- **[`internal/pipeline/steps/housekeeping_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/housekeeping_test.go)** asserts that exactly one agent invocation occurs during a combined pass, ensuring the optimization works as designed.
- **[`internal/e2e/journey_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/e2e/journey_test.go)** validates the complete flow, confirming that the lint prompt is properly omitted when the combined pass is present while still delivering accurate lint findings to the pipeline output.

These tests protect against regressions that might accidentally reintroduce the second agent call or fail to properly transfer housekeeping results between steps.

## Summary

- The **combined document and lint housekeeping pass** merges two pipeline stages into one agent invocation to reduce latency and API costs.
- The document step in [`internal/pipeline/steps/document.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/document.go) detects empty `commands.lint` configuration and appends a `housekeepingLintSection` to its prompt.
- Results are stored in `HousekeepingLintResult` within the shared pipeline context ([`internal/pipeline/shared.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/shared.go)).
- The lint step detects stored results via `sctx.Shared.HousekeepingLint()` and skips its own agent invocation when present.
- Unparseable results trigger a mandatory approval gate requiring human intervention.
- Unit tests in [`housekeeping_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/housekeeping_test.go) and end-to-end tests in [`journey_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/journey_test.go) ensure only one agent runs per combined pass.

## Frequently Asked Questions

### How does the combined pass reduce costs in no-mistakes?

The combined pass eliminates the need to initialize and run a second LLM agent for lint checking. Since agent cold-starts incur both latency and API token costs, consolidating the document and lint operations into a single invocation cuts resource usage approximately in half for repositories without explicit lint commands configured.

### What happens if the agent returns malformed JSON during the housekeeping pass?

If the JSON response cannot be parsed into the expected `types.Findings` structure, the document step returns a `documentApprovalOutcome` with the specific message *"combined housekeeping lint result unreadable"*. This forces the pipeline to halt and request human approval, preventing silent failures or corrupted lint data from proceeding downstream.

### Where is the housekeeping lint result stored between pipeline steps?

The result is stored in the shared pipeline context struct defined in [`internal/pipeline/shared.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/shared.go). The document step calls `sctx.Shared.SetHousekeepingLint()` with a `HousekeepingLintResult` containing the raw JSON findings and a summary string. The lint step later retrieves this via `sctx.Shared.HousekeepingLint()` to check if it should skip its own agent invocation.

### How does the lint schema differ in housekeeping mode compared to normal operation?

The housekeeping mode uses `housekeepingFindingsSchema`, which extends the standard `findingsSchema` with a top-level `Category` field. This extension allows the system to differentiate findings generated during the combined pass from those produced in standalone lint operations, as implemented in [`internal/types/findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/types/findings.go).