---
title: The ordered-sections model
description: An article is an ordered list of sections. The agent edits one at a time, addressed by anchor, while the server keeps the derived content in sync.
---

The ordered-sections model is the core of Scripto. It is what makes an agent editing a long article cheap, and what keeps formatting correct by construction.

## What a section is

An article's body is an **ordered list of sections**. A boundary is cut **before every `H2` heading** and **before every divider** (`· · ·`, the editor's `<hr>`). Each section owns:

- its **Markdown source** (`markdown`) — or `null` if it was authored in the human canvas (see below),
- the rendered **semantic HTML** (`html`) — the only HTML that ever ships,
- a **position** (a dense `0..n-1` integer, renumbered on every structural change).

`article.content` is the **derived** concatenation `concat(section.html ORDER BY position)`. The server rebuilds it on every write, so the invariant `content === concat(sections.html)` always holds. The editor and the public story page read the single `content` blob; the agent never has to.

## Anchors

You address a section by its **anchor** — any unique prefix of its section id. The [outline](#the-outline) prints anchors (the first 8 characters of each id). If an anchor matches more than one section, the API returns an `invalid-argument` with a `nextAction` telling you to use a longer prefix.

## The outline

The outline is the cheap **map** an agent reads before editing — one entry per section (anchor, level, title, word count, source), **never the bodies**. It stays tiny no matter how long the article grows.

```bash
scripto outline <id>
```

```text
  My first Scripto story  [draft] · 412w

  a1b2c3d4  h1  My first Scripto story        38w
  e5f6a7b8  h2  Why this matters             121w
  …
```

## The edit loop

<Steps>

<Step title="Map">

`scripto outline <id>` — read anchors + titles. No bodies, so it's cheap.

</Step>

<Step title="Pull one section">

`scripto section get <id> <anchor> -o sec.md` — fetch just that section's Markdown.

</Step>

<Step title="Replace it">

Edit `sec.md`, then `scripto section set <id> <anchor> --file sec.md`. If the new Markdown contains several headings, the one section becomes several in place.

</Step>

</Steps>

Insert, move, and remove round out the surface:

```bash
scripto section add <id> --file intro.md --before a1b2c3d4
scripto section mv  <id> e5f6a7b8 --after a1b2c3d4
scripto section rm  <id> e5f6a7b8
```

Every mutation echoes the fresh outline, so the next anchor is always in view.

<Note>

Prefer the section loop over `scripto articles update <id> --file whole.md`. Replacing the whole body works, but it re-splits everything and forces the agent to hold the entire document. The section loop keeps the agent's context proportional to the part it's changing.

</Note>

## Markdown-authored vs HTML-authored sections

A section's `source` is either `markdown` or `html`:

- **`markdown`** — authored by the agent (or `create`/`update`/`add`/`set`). Round-trips cleanly.
- **`html`** — edited by the human in the TipTap canvas, where `html` is canonical and there's no clean Markdown to reverse. `section get` returns the HTML; to reclaim it as Markdown, the agent simply `set`s the section with fresh Markdown.

## Next

- **[Working with sections](/guides/working-with-sections)** — the loop as a worked guide.
- **[Articles](/concepts/articles)** — the unit a section belongs to.
- **[GET .../outline](/api-reference/get-outline)** and **[the section endpoints](/api-reference/add-section)** — the HTTP surface.
