> ## 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

> A Shape names the types, properties and relationships of a domain, and entities keep the Shape version that they were saved under.

Concept · shapes

> **Use when**
>
> You read a Shape, adopt a public Shape, publish a new version, or need to know what a new version does to entities that exist.

> **Looking for something else?**
>
> Creating a Shape for a new domain (recipe [create-a-shape](https://docs.pnbr.io/guides/create-a-shape.md)). Changing a Shape through a draft (card [Shape draft](https://docs.pnbr.io/concepts/shape-draft.md)). Designing a good Shape, which this card does not cover. Changing one entity (card [Entity](https://docs.pnbr.io/concepts/entity.md)).

## For

A Shape is the model of a domain. It lists types, the properties of each type
and the relationships between types. The Graph holds entities of those types.
Extraction reads Files with a Shape and proposes entities of its types.

A Shape lives as one definition file, `<name>.shape.json`. The file holds the
Shape's name, a description, its `adherence` (`strict` or `loose`), its types
and its relationships. Each property carries a JSON Schema for its value and a
`required` flag. Each type, property and relationship also carries a ref
(`type_ref`, `property_ref`, `relationship_ref`).

Every publish adds a version of the Shape. A project can also adopt a public
Shape from the library. Entities keep the version they were saved under.

## Use when

* You read what a Shape holds before you stage or change entities.
* A person asks for a type, a property or a relationship that the Shape does not have.
* You adopt a public Shape, or a public Shape has an update waiting.
* You publish a change and must say what happens to the entities that exist.

## Not this

* Creating a Shape for a new domain: use recipe [create-a-shape](https://docs.pnbr.io/guides/create-a-shape.md). Changing a
  Shape that the project has: use recipe [change-a-shape](https://docs.pnbr.io/guides/change-a-shape.md).
* Starting, editing, checking and publishing a draft: use card [Shape draft](https://docs.pnbr.io/concepts/shape-draft.md).
* Choosing which types a Shape should have: Penumbra does not decide this for
  you, and this card does not cover it.
* Changing the properties of one entity: use card [Entity](https://docs.pnbr.io/concepts/entity.md).

## Rules

1. `shape.1` A published version never changes. Publishing adds the next
   version of the same Shape. **Your job:** treat a publish as permanent. No
   command removes a Shape that you published, and `penumbra shapes drop`
   discards a draft only.
2. `shape.2` A ref is the identity of a type, a property or a relationship. A
   changed name under the same ref is a rename. **Enforced:** a ref that you
   removed from a draft cannot return to that draft, and the push is refused
   with `invalid_draft`. **Your job:** keep every ref when you rename. A new ref
   is a new property, and the old one counts as removed.
3. `shape.3` Publishing rewrites no entity. Each entity keeps the version it was
   saved under, until an edit saves it under a newer version. **Your job:**
   after a publish, do not assume that entities hold the new properties.
4. `shape.4` A newer version takes over an older entity only across a change
   that keeps its meaning and renames nothing. Adding an optional property or a
   type, widening an enum, or making a required property optional keeps it.
   Requiring a property, narrowing an enum, removing a property or a type,
   changing a property's type, and any rename do not. **Enforced:** across such
   a change, `penumbra graph update` refuses a property that only the newer
   version has. The code is `graph_plan_rejected`, with exit code 3, and the
   message names no property. The entity stays on its own
   version, and an edit with the properties of that version still works.
5. `shape.5` `penumbra shapes diff` marks each change as preserving, creating,
   losing or breaking. It marks a rename as preserving, yet entities do not
   follow a rename. **Your job:** read a rename as a breaking change for
   entities that exist (problem [breaking-shape-change](https://docs.pnbr.io/troubleshooting/breaking-shape-change.md)).
6. `shape.6` A workspace pins a Shape's version when it first stages or checks
   out something in that Shape. A new workspace reads the newest version. A
   workspace that holds an entity plans its change under the version of that
   entity. **Enforced:** a workspace refuses a property that the entity's
   version lacks, with `missing_property_declaration`. This holds after an
   additive change too, and in a new workspace. **Your job:** to extract with a
   version that is newly published, start a new extraction. It opens its own
   workspace and reads the newest version (card rule [extraction.15](https://docs.pnbr.io/concepts/extraction.md#rule-extraction-15)). To give
   an older entity a property that only a newer version has, use
   `penumbra graph update` (rule [entity.2](https://docs.pnbr.io/concepts/entity.md#rule-entity-2)). Run
   `penumbra graph workspace validate` before you submit.
7. `shape.7` Adopt the exact public version that you reviewed. **Enforced:**
   `penumbra shapes add` without `--artifact-digest` is refused with
   `invalid_arguments`. If the listed version moved after your review, the
   server refuses the add with `shape_library_head_changed`. Review first with
   `penumbra shapes library review`.
8. `shape.8` Adopting or updating a public Shape changes no entity. Penumbra
   applies an update by itself only when the change is non-breaking. A breaking
   update waits, and `penumbra shapes links` shows it as pending. **Your job:**
   tell the person about each pending update. An update that renames something
   can apply by itself, and entities then stay on the old version (rule
   [shape.4](https://docs.pnbr.io/concepts/shape.md#rule-shape-4)).
9. `shape.9` A project holds at most 32 Shapes when you adopt. **Enforced:** an
   adoption that would pass 32 is refused with `project_shape_limit_reached`.
10. `shape.10` Only an owner or an admin of the project publishes. An editor
    writes drafts. **Enforced:** a caller without the publish permission is
    refused with `forbidden`. A project API key needs the scope
    `shapes.draft.publish`. **Your job:** a publish by a key or a connected
    agent waits for approval (card rule [approval.2](https://docs.pnbr.io/concepts/approval.md#rule-approval-2)).

## Failure signs

* `penumbra graph update` refuses a new property with `graph_plan_rejected` on
  an entity saved before a breaking change: problem [breaking-shape-change](https://docs.pnbr.io/troubleshooting/breaking-shape-change.md).
* `penumbra graph workspace validate` prints `missing_property_declaration` for
  a property that only a newer version has: rule [shape.6](https://docs.pnbr.io/concepts/shape.md#rule-shape-6).
* `penumbra context explore --shape-id <shape-id> --json` shows an entity with
  an `artifact_digest` that is not the newest in `penumbra shapes log <shape> --json`: rule [shape.3](https://docs.pnbr.io/concepts/shape.md#rule-shape-3).
* A publish exited with code 4: problem [change-waits-for-approval](https://docs.pnbr.io/troubleshooting/change-waits-for-approval.md).
* A View refuses with `view_republish_required` after a publish: problem
  [view-needs-republish](https://docs.pnbr.io/troubleshooting/view-needs-republish.md).

## Doors

| Door | Call |
| - | - |
| CLI | `penumbra shapes`, `penumbra shapes show`, `penumbra shapes log`, `penumbra shapes pull`, `penumbra shapes library`, `penumbra shapes library show`, `penumbra shapes library review`, `penumbra shapes add`, `penumbra shapes links`, `penumbra shapes update`, `penumbra shapes remove`, `penumbra shapes library settings`, `penumbra shapes lineage` |
| MCP (default) | `search_shapes`, `review_shapes`, `add_shapes`, `set_shape_updates`, `accept_shape_update`; in `execute`, `penumbra.shapes.list()` and `shape.read({ part: "model" })` |
| SDK | `project.shapes` |

In `execute`, `shape.read({ part: "model" })` shows a Shape's types,
properties and relationships. A tool appears only when the connection holds the
permission that it needs. Changing a Shape is card [Shape draft](https://docs.pnbr.io/concepts/shape-draft.md).

## The CLI word

The API calls a version a generation.

## HTTP reference

* [List shapes](https://docs.pnbr.io/api/http-shapes-list.md)
* [Get shape](https://docs.pnbr.io/api/http-shapes-get.md)
* [Get shape definition](https://docs.pnbr.io/api/http-shapes-definition.md)
* [Search shape types](https://docs.pnbr.io/api/http-shapes-search.md)
* [List shape versions](https://docs.pnbr.io/api/http-shapes-history.md)
* [List library shapes](https://docs.pnbr.io/api/http-shapes-library-list.md)
* [Get library shape](https://docs.pnbr.io/api/http-shapes-library-get.md)
* [Review library shape](https://docs.pnbr.io/api/http-shapes-library-review.md)
* [List linked shapes](https://docs.pnbr.io/api/http-shapes-links-list.md)
* [Link library shape](https://docs.pnbr.io/api/http-shapes-links-create.md)
* [Update linked shape](https://docs.pnbr.io/api/http-shapes-links-update.md)
* [Unlink shape](https://docs.pnbr.io/api/http-shapes-links-remove.md)

## Keep going

[Shape draft](https://docs.pnbr.io/concepts/shape-draft.md) · [Entity](https://docs.pnbr.io/concepts/entity.md) · [Workspace](https://docs.pnbr.io/concepts/workspace.md) · [Approval](https://docs.pnbr.io/concepts/approval.md) · [Extraction](https://docs.pnbr.io/concepts/extraction.md) · [View](https://docs.pnbr.io/concepts/view.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.