Expand description
nbformat .ipynb notebook persistence (Phase 21.4): pure serde_json
read/insert/persist over the human’s reviewable, git-diffable notebook
artifact. A normal module (no kernel/HTTP deps) — it manipulates JSON, it
does not run cells. run_cell(persist_to=…) calls notebook::persist_cell
to append each executed cell. See
docs/design/centaur-data-scientist.md
§4.1, the notebook-artifact bullet.
nbformat .ipynb notebook persistence (Phase 21.4).
The Centaur Data Scientist
§4.1 notebook-artifact bullet: the human notebook must stay a faithful,
reviewable, git-diffable artifact of the agent’s work. Where 21.3 ran cells
on a live kernel and reported the outputs into chat, 21.4 leaves a durable
record on disk — run_cell(persist_to=…) appends each executed cell (source
- its outputs) to a real
.ipynbso a human can open it in JupyterLab, see exactly what ran, and review the diff in a pull request.
§What this module is (and is not)
This is a pure serde_json .ipynb manipulator — it has no kernel, HTTP,
or websocket dependency, so it is a normal module (not behind the kernel
feature). An .ipynb is just JSON in the
nbformat v4
schema:
{ "cells": [ … ], "metadata": { … }, "nbformat": 4, "nbformat_minor": 5 }The three public operations mirror the three Phase 21.4 MCP tools:
read_notebook→notebook_read: a reviewable summary of every cell.insert_cell→notebook_insert_cell: proposes a cell (it does not execute it — a code cell goes in withexecution_count: null, outputs: []).persist_cell→notebook_persist_executed_cell: appends a code cell carrying its source and already-nbformat-shaped outputs. This is the low-level primitiverun_cell(persist_to)calls after a successful run.
§Atomicity (the load-bearing review contract)
Every write goes through [atomic_write]: serialize to a temp file in the
same directory as the target, then rename it over the target. A rename
within one filesystem is atomic, so a reader (a human’s JupyterLab autosave
watcher, a git diff) never observes a half-written notebook, and a
serialization failure leaves the original untouched — the same discipline the
conversation store uses for data.db. The notebook is an artifact under
review; a torn write would be a corrupt artifact.
§Errors
Every fallible operation returns crate::Result over crate::DataError:
a missing file on read, a non-nbformat-4 or corrupt file, or an I/O failure
is a clean typed error — never a panic.
Structs§
- Cell
Info - One cell’s reviewable summary, returned by
read_notebook.
Enums§
- Cell
Type - The kind of cell
insert_cellbuilds. Acodecell gets the executable scaffolding (execution_count: null,outputs: []); amarkdownorrawcell carries onlysource. Anything the caller passes that is notmarkdownorrawis treated ascode(the safe, executable default).
Functions§
- insert_
cell - Build a fresh nbformat cell from
sourceand insert it into the notebook atpath, proposing it without executing (Phase 21.4notebook_insert_cell). - persist_
cell - Append a code cell carrying
sourceand the given already-nbformat-shapedoutputsto the notebook atpath(Phase 21.4notebook_persist_executed_cell). - read_
notebook - Read and parse the
.ipynbatpath, returning aCellInfosummary of every cell (Phase 21.4notebook_read).