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). Changing a Shape through a draft (card Shape draft). Designing a good Shape, which this card does not cover. Changing one entity (card Entity).
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. Changing a Shape that the project has: use recipe change-a-shape.
- Starting, editing, checking and publishing a draft: use card Shape draft.
- 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.
Rules
shape.1A 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, andpenumbra shapes dropdiscards a draft only.shape.2A 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 withinvalid_draft. Your job: keep every ref when you rename. A new ref is a new property, and the old one counts as removed.shape.3Publishing 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.shape.4A 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 updaterefuses a property that only the newer version has. The code isgraph_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.shape.5penumbra shapes diffmarks 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).shape.6A 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, withmissing_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). To give an older entity a property that only a newer version has, usepenumbra graph update(rule entity.2). Runpenumbra graph workspace validatebefore you submit.shape.7Adopt the exact public version that you reviewed. Enforced:penumbra shapes addwithout--artifact-digestis refused withinvalid_arguments. If the listed version moved after your review, the server refuses the add withshape_library_head_changed. Review first withpenumbra shapes library review.shape.8Adopting 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, andpenumbra shapes linksshows 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).shape.9A project holds at most 32 Shapes when you adopt. Enforced: an adoption that would pass 32 is refused withproject_shape_limit_reached.shape.10Only an owner or an admin of the project publishes. An editor writes drafts. Enforced: a caller without the publish permission is refused withforbidden. A project API key needs the scopeshapes.draft.publish. Your job: a publish by a key or a connected agent waits for approval (card rule approval.2).
Failure signs
penumbra graph updaterefuses a new property withgraph_plan_rejectedon an entity saved before a breaking change: problem breaking-shape-change.penumbra graph workspace validateprintsmissing_property_declarationfor a property that only a newer version has: rule shape.6.penumbra context explore --shape-id <shape-id> --jsonshows an entity with anartifact_digestthat is not the newest inpenumbra shapes log <shape> --json: rule shape.3.- A publish exited with code 4: problem change-waits-for-approval.
- A View refuses with
view_republish_requiredafter a publish: problem view-needs-republish.
Doors
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.
The CLI word
The API calls a version a generation.HTTP reference
- List shapes
- Get shape
- Get shape definition
- Search shape types
- List shape versions
- List library shapes
- Get library shape
- Review library shape
- List linked shapes
- Link library shape
- Update linked shape
- Unlink shape