Every write to a Penumbra graph goes through a delta. A delta is a staged set
of changes you can inspect before it lands, plan against the live graph, apply as
a unit, and revert after the fact. It is version control for knowledge: stage,
review, apply, revert, with provenance preserved.
| Git | Penumbra |
|---|
| Working changes | A delta with staged entities and relationships |
git diff | pb.deltas.plan(id) — how applying it changes the graph |
git commit | pb.deltas.apply(id) |
git revert | pb.deltas.revert(id) |
Nothing reaches the committed graph except through this path. pb.capture and
pb.extract are conveniences that open a delta for you; underneath, it is always
the same primitive.
Stage a change
Build a delta and stage entities into it. Staging never touches the live graph.
const delta = await pb.deltas.create({ name: "Q3 deal notes" });
await pb.deltas.addEntities(delta.id, [
{ type: "Account", name: "Acme", properties: { tier: "enterprise" } },
]);
await pb.deltas.addRelationships(delta.id, [
{ from_entity_index: 0, to_node_id: "ent_renewal_2026", type: "HAS_RENEWAL" },
]);
The shortcut for a single entity is pb.capture({ ..., apply: false }), which
opens and stages a delta in one call.
Review before it lands
Submit the delta to mark it ready, then plan it to see exactly what applying it
would do to the live graph: what gets created, updated, or reconciled.
await pb.deltas.submit(delta.id);
const plan = await pb.deltas.plan(delta.id);
console.log(plan); // the diff against the committed graph
You can also ask whether applying it would degrade graph quality, as a read-grade
dry run:
const audit = await pb.dq.audit(delta.id);
if (audit.degrades) console.log(audit.explain());
Apply
Commit the delta. It lands as a unit, with lineage back to the source and the
delta that produced it.
await pb.deltas.apply(delta.id);
Revert
Applied deltas are revertible. Preview the revert, then undo.
const preview = await pb.deltas.revertPreview(delta.id);
await pb.deltas.revert(delta.id);
Stage with apply: false while you build and test, plan to confirm the diff,
and only apply once the plan looks right. Because every change is a revertible
commit, you can move quickly without fear of corrupting the graph.
See the pb.deltas reference for the full method list.