> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pnbr.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Shape draft

> A draft is the only place where a Shape changes, and you take it from a pulled file through check and diff to a publish.

Concept · shapes

> **Use when**
>
> You start, edit, check, compare, publish or discard a change to a Shape.

> **Looking for something else?**
>
> Reading a published Shape, adopting a public Shape, or finding what a new version does to entities (card [Shape](https://docs.pnbr.io/concepts/shape.md)). Changing one entity (card [Entity](https://docs.pnbr.io/concepts/entity.md)).

## For

A draft holds one change to a Shape until you publish it. You pull the
definition into a file, edit the file, and push it back. Penumbra turns the
difference into edits of the draft. Each push makes a new draft revision. A
publish turns one revision into a new version of the Shape.

## Use when

* A person wants a type, a property or a relationship added, changed or removed.
* You want to see what a change would do before it is public.
* You want your own copy of a public Shape and its types.

## Not this

* Looking at the types of a published Shape, or adopting one: use card [Shape](https://docs.pnbr.io/concepts/shape.md).
* Giving an entity a new value: use card [Entity](https://docs.pnbr.io/concepts/entity.md).
* Abandoning a published version: no command does this (rule [shape.1](https://docs.pnbr.io/concepts/shape.md#rule-shape-1)).

## Rules

1. `shape-draft.1` Start from the right source. `penumbra shapes edit <shape>` opens an edit draft that publishes as the next version of that
   Shape. `penumbra shapes new` starts a new Shape: `--blank --name <name>` to
   start empty, or `--brief <text>` to generate one. `penumbra shapes fork <shape>` copies a Shape into a new one. For a public Shape, give
   `<publisher>/<shape>`. A brief can add Files with `--from <file>` and Shapes with
   `--like <shape>` for the draft to fit. **Your job:** use an edit for the same Shape. A fork
   is a new Shape, and the entities of the original stay with the original.
2. `shape-draft.2` Push a file with the revision it was pulled at. **Enforced
   when you ask:** a pulled file carries a [source](https://docs.pnbr.io/concepts/source.md) field with the draft and
   its revision. If the draft moved on, the push is refused with
   `revision_conflict` (exit code 3). Pull again and reapply your edits. With
   `--draft <other-draft-id>`, nothing checks the revision.
3. `shape-draft.3` After a push, the file follows its draft. A file that you
   pulled from a published Shape starts a new edit draft at the first push.
   **Your job:** push the same file again to keep editing that draft, and keep
   the draft id that the push printed. **Enforced:** the Shape can already have
   an open draft. Then a push of a file that still names the published version
   is refused with `draft_already_open`, and nothing is sent. Run
   `penumbra shapes pull <draft-id>` to see that draft, or push again with
   `--into-open-draft` to replace it with your file.
4. `shape-draft.4` Check the revision that you plan to publish. `penumbra
   shapes check <draft-id>` validates the draft at its current revision. It
   exits with code 3 and lists diagnostics when the draft is not valid.
   **Enforced:** a draft is not valid when the Shape states no purpose
   (`telos.purpose`). It is not valid when a type's name or description field
   holds a list or an object. Extraction reads every File through the purpose, and the
   Graph shows the name and description fields as one value each. **Your
   job:** write the purpose in `telos`, not only in `description`. Check again
   after each push, because a push makes a new revision.
5. `shape-draft.5` Read the diff before you publish. `penumbra shapes diff <draft-id>` compares the draft with the version it started from. It lists
   each change with its impact and a recommended bump, and the tools agents
   would get. It deploys nothing and changes no entity. **Your job:** for a
   change marked losing or breaking, or any rename, entities stay on their old
   version (rule [shape.4](https://docs.pnbr.io/concepts/shape.md#rule-shape-4)).
6. `shape-draft.6` A publish needs a message. **Enforced:** `penumbra shapes
   publish` without `-m` is refused with `invalid_option`. The message is up to
   2000 characters, and `penumbra shapes log` shows it. **Your job:** say what
   changes in the version.
7. `shape-draft.7` A publish does not wait for approval under the default
   policy. **Enforced:** an owner or admin can add `shape_change` to the policy.
   Then a publish by an API key or a connected agent returns `pending` (exit
   code 4) with an approval URL. Do not publish again. A person's own session
   never waits. The key also needs the scope `shapes.draft.publish`.
8. `shape-draft.8` A publish can end in a state other than published.
   **Your job:** if the output says `prepared` or `reconciling`, the server
   finishes it. Read the draft with `penumbra shapes show <draft-id>` until it
   says published. Do not push to it meanwhile: a publishing draft refuses edits
   with `draft_locked`. If the output says the publication was rejected, nothing
   was published.
9. `shape-draft.9` A published draft is finished. For later work, open a new
   edit draft from the new version. **Your job:** start the next change with `penumbra shapes edit <shape>`.
10. `shape-draft.10` `penumbra shapes drop <draft-id>` discards a draft and keeps
    its history. It changes no published version. **Enforced:** a drop does not
    wait for approval under the default policy (rule [shape-draft.7](https://docs.pnbr.io/concepts/shape-draft.md#rule-shape-draft-7)).

## Failure signs

* A push exits with code 3 and `revision_conflict`: rule [shape-draft.2](https://docs.pnbr.io/concepts/shape-draft.md#rule-shape-draft-2).
* A push is refused with `invalid_draft` and says that a ref was removed earlier:
  card rule [shape.2](https://docs.pnbr.io/concepts/shape.md#rule-shape-2).
* `penumbra shapes diff` shows a change marked losing or breaking: problem
  [breaking-shape-change](https://docs.pnbr.io/troubleshooting/breaking-shape-change.md).
* A publish exits with code 4: problem [change-waits-for-approval](https://docs.pnbr.io/troubleshooting/change-waits-for-approval.md).
* A push says `draft_locked`: rule [shape-draft.8](https://docs.pnbr.io/concepts/shape-draft.md#rule-shape-draft-8).

## Doors

| Door | Call |
| - | - |
| CLI | `penumbra shapes drafts`, `penumbra shapes new`, `penumbra shapes pull`, `penumbra shapes push`, `penumbra shapes check`, `penumbra shapes diff`, `penumbra shapes publish`, `penumbra shapes drop`, `penumbra shapes show` |
| MCP (default) | `execute` with `penumbra.shapes`: `penumbra.shapes.list()`, `penumbra.shapes.open({ name })`, `penumbra.shapes.copy({ from, name })`, then on the Shape `read({ part })`, `define`, `modify`, `validate`, `submit({ note })`, `discard` |
| SDK | `project.shapes.drafts`, `project.shapes.definitions` |

No MCP door writes a definition file. `shape.define` takes a complete
definition into a draft, and `shape.modify` changes a draft by named
operations.

## Keep going

[Shape](https://docs.pnbr.io/concepts/shape.md) · [Entity](https://docs.pnbr.io/concepts/entity.md) · [Approval](https://docs.pnbr.io/concepts/approval.md) · [Workspace](https://docs.pnbr.io/concepts/workspace.md) · [A Shape change renamed or removed something](https://docs.pnbr.io/troubleshooting/breaking-shape-change.md) · [Create a Shape and try it on a File](https://docs.pnbr.io/guides/create-a-shape.md) · [Change a Shape and publish it](https://docs.pnbr.io/guides/change-a-shape.md)

Penumbra Grammar 0.6.26


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.