Notebook inspection design
A proposal to connect variables, data, network structure, and training history in one research workspace.
Implementation status and remaining design, October 11, 2026. The first read only development inspector is implemented in VS Code extension 0.1.28, the native session protocol, and the optional Jupyter adapter. Aner runs in production by default; development is an explicit observation setting independent of shared variable/independent program execution. See the user workflow, VS Code notebooks, and Jupyter installation.
Choose Dev and rerun setup cells, then open Inspector after a cell completes. It shows typed globals, bounded scalar/collection/object descriptions, reference diagrams, named observations, and per fit loss. Aner: Open Development Training Report opens recorded topology, activations, and available gradients. Source edits mark observations stale; reset, cancellation, timeout, runtime failure, or switching modes invalidates live state. A retained training view identifies its producing execution as historical rather than claiming to describe a later cell's variables.
The optional Jupyter kernel returns read only HTML/SVG and typed development MIME output beneath completed cells. Its controls include %aner dev, %aner dev values, %aner variables, %aner prod, and %aner reset. It provides variable/object views, per fit loss, and an operation topology summary. Detailed neuron/dependency controls remain available in the standalone report. Neither adapter streams observations while execution is running or supports pause/step debugging.
The separate Open training report workflow, introduced in extension 0.1.17, still opens a user selected CLI index.html or trace.json beside a notebook. Both files stay together. The association is workspace state; the viewer consumes JSON using the packaged viewer rather than executing selected HTML. This historical report is not automatically linked to the current notebook's source/session. See recorded training reports.
The following design describes the broader coordinated experience and distinguishes implemented completed cell observations from the remaining streaming/debugging work.
The coordinated experience
Keep the notebook as the main surface, with an Aner Inspector beside it and training history beneath it. Every computed view identifies the execution and observation it represents. Selecting an older loss point selects the corresponding recorded state when available; it must never suggest that the running program has rewound.
| View | Current implementation and remaining work |
|---|---|
| Variables | Completed cell typed globals, bounded previews, exact Int64 text, object/reference identity, Tensor shapes/statistics; paused locals/scope inspection is future work. |
| Data | Native value summaries and dataset attribution; a dedicated lazy schema/table explorer is future work. |
| Network | Recorded operation topology, shapes, parameters, and available activation/gradient summaries; detailed neuron controls in CLI/VS Code reports. |
| Training | Separate captured loss series with local steps and phase labels; streaming and general named metric/validation history are future work. |
| Debugger | Source locations in diagnostics/captures; call stacks, breakpoints, pause/continue/step, and local variable editing are future work. |
The implemented variable explorer is read only. Editing a variable through a panel can change an experiment without changing its source; a later editing facility should require a valid typed assignment and record it in the execution history. An inspector must not execute arbitrary user code just to display a value.
The coordinated inspection workflow is a design objective. Evaluation should measure whether source, variables, data, topology, and recorded training history remain consistent and reduce user effort. Panel availability alone does not establish a language level capability.
A consistent state across views
A variable table, network capture, and metric point must refer to compatible observations. The implemented aner.dev/1 envelope contains run identity, runtime version, generation/request IDs, source basename, status/reset/snapshot phase, typed values, capture sequence/source spans, omissions, and optional training trace/summary. Int64 and identity counters use exact decimal strings. Notebook adapters add execution/cell/source identity and handle stale states. Fit captures have series/local step/phase fields.
A future streaming or paused frame envelope should extend this with source revisions, frame/binding identity, parameter version, and explicit epoch/batch/data partition semantics where actually known. Do not infer provenance from a pathname or a random seed alone.
Completed cell views distinguish successful state, stale/historical observations, and unavailable/reset state. Future streaming/debugging views should additionally distinguish Running: last observation and Paused: current frame. Display the age or step of an observation while computation continues. If a metric was recorded without a matching network/variable capture, say so; do not substitute a nearby frame as though it were simultaneous.
Inspectors consume immutable copied summaries or versioned handles with bounded lifetimes. They must not hold an entire autograd graph alive merely to keep a panel open. A session restart invalidates live handles; saved observations remain historical data. A saved notebook is not a complete process checkpoint.
Int64 values must survive transport without JavaScript precision loss. Use a typed representation for large integers and nonfinite floating values instead of relying on unqualified JSON numbers. Diagnostics and unsupported inspection requests should produce explicit unavailable states rather than guessed values.
Neural networks and loss charts
Use an architecture view for model structure and a separate operation view for the actual executed tensor graph. Small models such as XOR can expand to neurons; large models should default to collapsed layers and shapes. Do not draw every trainable scalar as a neuron. Selecting a layer should reveal its parameter shapes, operation, available summaries, and source location where the runtime can supply one.
Aner already has viz.capture(step, loss) and bounded native tensor/gradient snapshots for offline reports. Current graph node IDs are local to a capture, and labels are not stable model identities. Per fit series and local epoch counters distinguish training runs. Linking particular logical layers across arbitrary dynamic graphs still requires stable logical identities and versioned runtime node references. Generated or conditional graph structure must remain distinguishable from an authored model diagram.
Capture phases matter: a loss and its gradients belong to the forward/backward computation that produced them. The existing Iris loop captures after backward and before the SGD updates. Automatic classifier captures explicitly distinguish after backward before update and the final trained evaluation; separate fits are never joined into one loss curve. Do not pair that loss with post update weights without labeling the difference. Gradients not yet computed, invalidated by failure, or omitted by a capture budget must be shown as unavailable.
Keep metric collection lightweight and separate from heavier graph snapshots. A metric record needs a name, value, step, optional epoch/batch, train/validation/test partition, reduction, sample/element count, aggregation weighting, and observation identity. Distinguish batch loss from an aggregate epoch loss; unequal batches must not become an unweighted mean of batch means. A display should not assume that a variable named epoch establishes those semantics.
The current Iris example has a training/test split and evaluates its held out test rows after training. It does not supply a validation curve. A future validation curve requires a separate validation partition and an explicit evaluation schedule; never silently use held out test results to guide model selection.
Native execution and debugging
Two capabilities are related but distinct:
- The implemented persistent session retains notebook level variables, datasets, and models and returns bounded read only development observations after execution. Inspecting function locals while paused additionally requires call stack and lexical scope information.
- A future running independent program can stream metric and graph observations before it exits. This can improve independent program mode without promising shared cell state.
Today standalone execute creates fresh state, while the native Session owns globals, imports, and function definitions across evaluations. Function locals live in frames that disappear after returning. A frame's storage can retain values whose lexical block has ended; an inspector must respect active scope rather than listing every occupied storage slot. The implemented session lifecycle distinguishes static failure from runtime reset. Observation identities must invalidate correctly on those resets, cancellation, or restart.
The opt in native aner session --stdio --dev-protocol uses version 2 byte framing and PROD, DEV, or DEV_VALUES execution requests. It returns separate stdout, diagnostics, and bounded structured inspection payloads; the original version 1 text protocol remains compatible. Both VS Code and Jupyter consume this interface. Prints cannot masquerade as observations. The producer bounds traversal, snapshot storage, neural capture count, and the 512 KiB observation payload, with explicit omission/truncation status.
Streaming and pause/step will need additional control messages, safe points, bounded buffering/backpressure, dropped/coalesced event accounting, and source revision mapping. They are not implemented by the completed cell protocol.
Pause and step require cooperative safe points in the interpreter and long native operations, plus explicit paused frame ownership. Cancellation and pause are different: the current notebook Stop terminates the child process. It cannot preserve that process's variables for later continuation. Future GPU/cluster operations may only stop or observe at backend defined boundaries; the UI must report the actual boundary reached.
Use VS Code's debugging integration for breakpoints, stepping, and call stacks when those native capabilities exist. Custom data/model panels should consume the same state identities, not implement a separate debugger. Remote execution keeps native data on its execution host and sends only requested bounded observations.
Large data and research controls
The current inspector copies native descriptions without invoking user getters or lazy CSV scans. It does not collect tables or retain live graphs. Tensor statistics still cost O(t) for t elements; bounded export size does not make that reduction free. Future lazy/GPU inspectors should begin with cheap metadata and request expensive work explicitly, with visible cost/cancellation. A tensor's numeric payload size is different from retained graph storage and total process memory; label each measurement's scope.
Development requires an explicit mode selection and includes bounded scalar/String/object previews alongside native summaries. Raw tensor/gradient arrays require the additional values opt in. Reports and notebook outputs can retain these observed values, so review their contents before sharing. A future data record explorer should make its export choices explicit. Summaries are not a guarantee of de identification. This follows the existing statistics first visual capture approach and is especially relevant to the intended medical research workflow.
Keep loss history and snapshots bounded independently. Downsampled chart displays should disclose that reduction, preserve meaningful anomalies, and expose missing records. Do not replace the current capture caps with unbounded epoch by epoch graph retention. No performance or memory overhead claim is valid until measured with observation disabled and enabled.
Implementation sequence and acceptance
- Completed: bounded native observations and notebook integration. CLI
--devproduces offline variable/object and neural reports, including partial runtime failure observations. The native v2 protocol returns typed observations separately from text. VS Code 0.1.25 supplies Dev/Prod controls, the read only Inspector, source stale handling, and a historical training view. The optional Jupyter adapter executes real.ipynbdocuments and returns development MIME/HTML/SVG after cells complete. Captures preserve numerical results, exact integers, cycles, omissions, and phase; inspection does not retain training graphs. - Completed: read only globals and lifecycle handling. Observations describe declared binding types and bounded reachable values with stable heap identities. Static failure preserves state; runtime failure records historical pre reset state and clears live values. Restart, Stop, timeout, and mode changes invalidate observation state. Saved output is not a live heap or checkpoint. Model state is saved separately through validated fitted classifier checkpoints.
- Next: streaming metric observations. Add bounded named metric records and matching graph snapshots while a cell runs, with backpressure/coalescing and explicit aggregation/data partitions. Verify slow clients remain bounded, dropped observations are visible, and charts do not invent simultaneity between different states.
- Future: coordinated pause and step debugging. Expose source locations/stacks and cooperative safe points; keep current state views on one paused snapshot. Verify historical selections cannot mutate or resume the running program, cancelled work remains cancelled, and source edits do not silently remap breakpoints.
- Future: dependency tracking and extensible inspectors. Track changed source/input dependencies, provide fresh ordered execution, define third party inspection/rendering contracts, and retain text fallbacks. Dedicated table explorers and variable editing require their own bounds and validation.
The implemented foundation makes both neural training and linked list mutations visible with explicit development mode. It observes completed executions and recorded steps; live streaming, paused locals, debugger replay, and generic object serialization remain separate milestones. See the mode guide for runnable examples, recording budgets, checkpoint complexity, and the production/compilation boundary.