# How to Automatically Fix Section Ordering Issues with the Fixer Command

> Automatically fix DESIGN.md section ordering issues with the Fixer command. The API reorders sections to match the canonical specification, preserving the prelude.

- Repository: [Google Labs Code/design.md](https://github.com/google-labs-code/design.md)
- Tags: how-to-guide
- Published: 2026-07-03

---

**The Fixer API automatically reorders DESIGN.md sections to match the canonical specification by parsing the document into discrete sections, separating known and unknown headings, sorting them against the `CANONICAL_ORDER` array, and reassembling the document with the prelude preserved at the top.**

The [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) project provides a robust toolchain for maintaining consistent documentation structure. When sections appear out of order, the fixer command offers a deterministic way to automatically fix section ordering issues with the fixer command without manual editing. This API wraps the same logic used by the section-order linter rule, ensuring your documentation always matches the canonical specification defined in [`spec-config.yaml`](https://github.com/google-labs-code/design.md/blob/main/spec-config.yaml).

## How the Fixer API Reorders Sections

The core implementation resides in [`packages/cli/src/linter/fixer/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/fixer/handler.ts), specifically within the `fixSectionOrder` function. This handler processes the input through a five-stage pipeline that preserves content while enforcing structural rules.

### Input Validation with FixerInputSchema

All requests must conform to the `FixerInputSchema` defined in [`packages/cli/src/linter/fixer/spec.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/fixer/spec.ts). The schema requires two properties: `content` (the original document string) and `sections` (an array of objects containing `heading` and `content` fields). Each section represents a discrete portion of the DESIGN.md file, typically generated by a parser that splits the document at heading boundaries.

### Preserving the Prelude

The fixer identifies introductory content by checking for a section with an empty string heading. According to [`handler.ts`](https://github.com/google-labs-code/design.md/blob/main/handler.ts) at line 21, this "prelude" section is always retained at the very top of the output document. This ensures that frontmatter, free-form text, or introductory paragraphs remain untouched regardless of the reordering logic applied to subsequent sections.

### Separating Known and Unknown Sections

The algorithm distinguishes between sections defined in the specification and custom additions. In [`packages/cli/src/linter/spec-config.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.ts) at line 60, the `resolveAlias` helper maps section headings to their canonical forms before checking against `CANONICAL_ORDER`.

Known sections—those appearing in the canonical order list—are queued for sorting. Unknown sections are preserved but appended after all known sections, as implemented in [`handler.ts`](https://github.com/google-labs-code/design.md/blob/main/handler.ts) lines 28-32. This approach guarantees that proprietary or experimental sections are not deleted during the fixing process.

### Sorting and Document Reassembly

The sorter uses the index position within `CANONICAL_ORDER` to determine the correct sequence, as shown in [`handler.ts`](https://github.com/google-labs-code/design.md/blob/main/handler.ts) lines 33-36. After sorting, the reassembler concatenates three groups: the prelude (if present), the sorted known sections, and the unsorted unknown sections, each separated by a single newline.

The function returns an object containing `fixedContent` (the reordered document) and optional `details` showing the before and after ordering for debugging purposes, implemented in [`handler.ts`](https://github.com/google-labs-code/design.md/blob/main/handler.ts) lines 51-60.

## Practical Implementation Examples

You can invoke the fixer programmatically via the TypeScript API or through the bundled CLI command.

### Basic TypeScript Usage

Import `fixSectionOrder` from [`packages/cli/src/linter/fixer/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/fixer/handler.ts) and provide a valid `FixerInput` object:

```typescript
import { fixSectionOrder } from '@design-md/cli/src/linter/fixer/handler.js';
import type { FixerInput } from '@design-md/cli/src/linter/fixer/spec.js';

// Assuming parseDesignMd splits the file into sections
const { sections, rawContent } = parseDesignMd('my-design.md');

const input: FixerInput = {
  content: rawContent,
  sections,
};

const result = fixSectionOrder(input);

if (result.success) {
  console.log('Fixed document:', result.fixedContent);
  console.log('Order changed from:', result.details?.beforeOrder);
  console.log('Order changed to:', result.details?.afterOrder);
} else {
  console.error('Fix failed:', result.error);
}

```

### Using the CLI Command

For command-line workflows, use the `design-md fix` command:

```bash
design-md fix path/to/DESIGN.md --output fixed.md

```

This command internally parses the file, calls `fixSectionOrder`, and writes the `fixedContent` to the specified output path.

### Integrating into a Web Service

Expose the functionality via an HTTP endpoint:

```typescript
import express from 'express';
import { fixSectionOrder } from '@design-md/cli/src/linter/fixer/handler.js';
import type { FixerInput } from '@design-md/cli/src/linter/fixer/spec.js';

const app = express();
app.use(express.json());

app.post('/api/fix-section-order', (req, res) => {
  const input: FixerInput = req.body;
  const result = fixSectionOrder(input);
  res.json(result);
});

app.listen(3000);

```

## Key Source Files

Understanding the fixer requires familiarity with these specific files:

- **[`packages/cli/src/linter/fixer/spec.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/fixer/spec.ts)** – Defines the Zod schemas for `FixerInput` and result types
- **[`packages/cli/src/linter/fixer/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/fixer/handler.ts)** – Contains the `fixSectionOrder` implementation and reordering logic
- **[`packages/cli/src/linter/spec-config.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.ts)** – Declares `CANONICAL_ORDER` and the `resolveAlias` helper for canonical heading resolution
- **[`packages/cli/src/linter/linter/rules/section-order.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/rules/section-order.ts)** – The linter rule that detects violations using the same ordering logic

## Summary

- The **Fixer API** automatically reorders DESIGN.md sections by comparing parsed headings against the `CANONICAL_ORDER` array defined in the specification.
- **Prelude sections** (empty heading) are always preserved at the top of the document.
- **Unknown sections** are appended after known sections, ensuring no content loss during automated fixing.
- The implementation in [`packages/cli/src/linter/fixer/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/fixer/handler.ts) provides deterministic sorting via `fixSectionOrder`.
- You can invoke the fixer via **TypeScript API**, **CLI command**, or **HTTP service**.

## Frequently Asked Questions

### What happens to sections not defined in the canonical order?

Unknown sections are preserved and appended after all known sections. The fixer does not delete or modify their internal content; it only relocates them to the end of the document to maintain the integrity of custom sections while enforcing the standard structure.

### How does the fixer handle section aliases?

The `resolveAlias` function in [`packages/cli/src/linter/spec-config.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.ts) expands alternative headings to their canonical forms before checking against `CANONICAL_ORDER`. This ensures that documents using legacy or alternative section names are correctly sorted according to the current specification.

### Can I use the fixer without parsing the document first?

No, the `FixerInput` requires a pre-parsed `sections` array. You must split the document into sections with their respective headings and content before calling `fixSectionOrder`. The CLI command `design-md fix` handles this parsing automatically.

### Does the fixer modify the original file?

When using the API directly, `fixSectionOrder` returns a new `fixedContent` string without modifying the input. The CLI command writes to the specified output file (or stdout if no output is specified), leaving the original document unchanged unless you overwrite it with the `--output` flag pointing to the same path.