Skip to main content
A shape is the contract for a slice of your graph. It defines the entity types that can exist, the properties each type carries, and the relationships that connect them. The same shape that decides what you can capture also decides what extraction is allowed to produce and what retrieval reads back. When you author a shape in the Workbench, you are setting the rules for all three at once.

The data model

A shape is a nested model. Read it top to bottom:
LevelWhat it isExample
ShapeThe contract for a domain slice.research
Entity typeA kind of node the shape allows.finding, source
PropertyA field on an entity type, with a kind and required/optional status.content (required), domain
RelationshipA typed edge between two entity types.evidenceSUPPORTSfinding
When you materialize the shape, these become the only shapes of node and edge the runtime will write for that project. An entity that does not match a type in the shape, or a property the type does not declare, has nowhere to land.
shape
  └─ entity type
       ├─ property
       └─ relationship → entity type

Adherence modes

Every shape carries an adherence mode that controls how strictly capture and extraction must conform to the model. You set it on the shape; it applies to everything written through that shape.
Only declared types, properties, and relationships are accepted. A capture or extraction that introduces an unknown type, an undeclared property, or a missing required field is rejected rather than written.Use strict when the graph feeds something downstream that depends on a fixed schema — typed accessors, exports, reporting — and you want guarantees over coverage.
Adherence is a property of the shape, not of a single call. To change how conformant writes must be, change the shape’s mode and re-materialize.

One shape, three jobs

The reason a shape is worth authoring carefully is that it is reused at every stage of the loop. Define a type once and it governs:
StageWhat the shape decidesSDK surface
CaptureWhich entity types you can stage, and which properties they carry.pb.capture
ExtractionWhat an LLM is allowed to pull out of a source — coerced into the shape’s types and properties.pb.extract
RetrievalWhat comes back, since results are typed entities matching the shape.pb.search
This is why the modeling work pays off in practice. If a type is missing a property, extraction cannot capture that field no matter how clearly it appears in the source — there is nowhere to put it. If a relationship is not declared, neither capture nor extraction can draw that edge, so traversal later will not find it. The shape is the ceiling on what your graph can know.
Before you extract a new kind of source, check that the shape already has the types and properties you expect to find. Authoring the model first is cheaper than re-extracting after you notice the gap.

System shapes ship preloaded

You do not start from nothing. Penumbra ships a set of system shapes that are already materialized and ready to use, including two you will reach for early.

The memory shape

The default shape behind pb.memory. It defines a single entity type, memory, for agent working memory.
PropertyNotes
contentRequired. The memory text.
kindOne of preference, decision, fact, lesson, observation, signal.
domainThe subject area the memory belongs to.
scopeOne of agent, commons, project.
date_observedWhen the memory was formed.
source_contextWhere it came from.
expiryWhen it should be considered stale.
Its relationships connect a memory to what it is about and to what replaces it:
RelationshipMeaning
ABOUTLinks a memory to the entity it concerns.
SUPERSEDED_BYLinks a memory to the one that replaces it.
To capture memory specific to your domain, fork this shape and add your own properties — see Custom memory layer.

The research shape

A starting model for research work, with the entity types inquiry, source, evidence, finding, open_question, and research_note. Use it as-is to structure investigation, or open it in the Workbench and extend it.

Where a shape’s entities live

A shape governs structure; planes govern role. The two are orthogonal — the same shape’s entities can sit on different planes depending on how they were written.
PlaneWhat lives there
SemanticThe default canonical surface. Capture and extraction land here.
MemoryWhere pb.memory writes and reads; recall defaults here.
ArchivalRetired memory and history, kept out of the active surface.
MetaHidden internal infrastructure. You do not write to it.
In practice: when you pb.capture or pb.extract through a shape, the entities land on the semantic plane. When you write through pb.memory, the memory shape’s entities land on the memory plane, and recall reads them back from there by default. Same data model, different plane, different default visibility.

Next

Author a shape

Define types, properties, and relationships in the Workbench.

Capture and extract

Put knowledge into a shape-governed graph with the SDK.