Skip to main content
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

  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).
  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). To give an older entity a property that only a newer version has, use penumbra graph update (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).
  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).

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.
  • penumbra graph workspace validate prints missing_property_declaration for a property that only a newer version has: 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.
  • A publish exited with code 4: problem change-waits-for-approval.
  • A View refuses with view_republish_required after 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

Keep going

Shape draft · Entity · Workspace · Approval · Extraction · View · Create a Shape and try it on a File · Change a Shape and publish it