# Document lifecycle: states, Save vs Publish (https://systemhub.com/docs/concepts/document-lifecycle)

> Part of systemHUB Docs · Connect: Settings → AI Gateway in systemHUB · Auth: OAuth (scoping is workspace-level today — see Getting started) · MCP tools: 48 · Full corpus: https://systemhub.com/llms-full.txt

Every systemHUB document — whether a System, Policy, or Training — moves through a defined lifecycle. An AI agent must understand this before authoring, or it will create content nobody can see, or overwrite an approved document.

## Document states

A document's `state` is an integer with a fixed meaning and colour:

| `state` | Colour | Meaning |
|---|---|---|
| `0` | GREY | Draft — being written, not yet reviewed |
| `1` | ORANGE | Needs review — drafted, awaiting approval |
| `2` | RED | Overdue — past its review date |
| `3` | GREEN | Approved — current, reviewed, live |
| `4` | PURPLE | Archived — retired, kept for reference |

These values are returned on every tree node, search result, and `get_*_details` call, and are accepted by the `state` parameter on create/edit tools.

## Save vs Publish (the distinction that matters most)

**Save records your changes. Publish is what your team sees** — until you publish, assigned members keep viewing the last published version.

- **Save** — writes the current content. On its own, saving does not push a new visible version to assigned users.
- **Publish** — releases a version so that assigned members actually see it. Publishing is what makes content live.

For agents, the practical rules are:

- **Creating a document *with content* auto-publishes it** — assigned users can see it immediately. This is intentional; you do **not** need to ask the user to confirm publishing.
- **To create a draft that stays hidden**, pass `publish: false` on the create call. It's saved but not released.
- **Editing auto-publishes too.** `edit_*` releases the change to assigned members unless you pass `publish: false`. Use `publish_system` / `publish_policy` / `publish_training` when you want to cut a *named* version (e.g. `"v1.1 - Added billing steps"`), not to make an edit visible — it already is.
- **So do metadata writes.** `add_document_tags`, template, media and attachment tools all default to `publish: true` — *tagging a document publishes it*. That means a document you created with `publish: false` stops being hidden the moment you tag it. If something must stay unpublished, pass `publish: false` on **every** write to it, not just the create.

> ⚠️ **The practical consequence:** there is no "work quietly then release" mode by default. Any write to a live document — including one that only touches metadata — is visible to the whole team immediately. Before editing an approved document, be sure the user wants the change live now.

> **Canonical wording:** the summary line above is the current agreed phrasing; the app empty-state copy is being finalised from the internal content audit and will be reconciled here so the docs and the product never disagree.

## View vs Edit

Access to a document is not all-or-nothing:

- **View** — a member can read the document but not change it.
- **Edit** — a member can modify content.

What a given person can do is a function of their **role** and any **direct assignment** on the document. See [Roles & seats](/docs/concepts/roles-and-seats). An agent connected with a user's token inherits exactly that user's view/edit scope.

## How systemHUB behaves over time (the model to reason with)

The sequence an agent should hold in its head:

| You do | What happens | When |
|---|---|---|
| `create_system` with content | Document saved AND published — assigned members can see it | Immediately |
| `create_system` with `publish: false` | Document saved as a hidden draft | Visible to no one until published |
| `edit_system` | Content updated at the API layer, stored **verbatim** | Immediately; a new published version only when you cut one |
| `publish_system` | A named version released to assigned members | Immediately |
| A human opens the doc in the editor and saves | The editor **filters the stored HTML** to its supported feature set | First human save — this is when out-of-contract formatting silently changes |

That last row is the one that surprises agents: the API stores whatever HTML you send, but the *editor* is the filter, applied on the next human save — which may be days later. Author within the [supported set](/docs/concepts/authoring-content) and the document is stable forever; author outside it and the document changes under the owner's feet the first time they touch it.

## Master templates

Some content is a **master template** — read-only reference content supplied from the master workspace (`isMasterTemplate: true`). It appears in trees and search so it can be browsed and copied, but it cannot be edited, moved, published, or deleted, and `get_*_details` returns `404` for it. Treat master templates as immutable.

Next: **[Roles & seats →](/docs/concepts/roles-and-seats)**
