@@ -566,29 +566,39 @@ def to_yaml(self) -> str:
566566 # sort_keys=False keeps insertion order, which follows node order in spec
567567 return yaml .safe_dump (yaml_obj , sort_keys = False )
568568
569- # tracer event handling helpers:
570- @staticmethod
571- def _probe_to_dict (probe : Any ) -> dict [str , Any ]:
572- """
573- Duck-typed conversion of a BaseDataProbe-like object to JSON-safe dict.
574- """
575- if probe is None :
576- return {}
577-
578- shape = getattr (probe , "shape" , None )
579- nan_unc = getattr (probe , "nan_unc" , {}) or {}
580-
581- return {
582- "shape" : list (shape ) if shape is not None else None ,
583- "ndim" : getattr (probe , "ndim" , None ),
584- "rank_of_data" : getattr (probe , "rank_of_data" , None ),
585- "units" : getattr (probe , "units_str" , None ),
586- "dimensionality" : getattr (probe , "dimensionality_str" , None ),
587- "nan_signal" : getattr (probe , "nan_signal" , None ),
588- "nan_unc" : {str (k ): int (v ) for k , v in dict (nan_unc ).items ()},
589- "min_signal" : getattr (probe , "min_signal" , None ),
590- "max_signal" : getattr (probe , "max_signal" , None ),
591- }
569+ # --------------------------------------------------------------------- #
570+ # Trace events / run-time introspection
571+ # --------------------------------------------------------------------- #
572+ #
573+ # Summary
574+ # -------
575+ # Pipelines can optionally collect per-step TraceEvent records during execution.
576+ #
577+ # Design goals:
578+ # - Keep Pipeline execution fast and lightweight (no arrays stored).
579+ # - Keep trace events strictly step-local (each event describes only one executed node).
580+ # - Support UI rendering without requiring access to live ProcessingData.
581+ #
582+ # What is stored:
583+ # - Always: module metadata, prerequisite step_ids, and the step configuration used.
584+ # - Optionally: dataset "diff" payloads produced by PipelineTracer (units/dimensionality/NaNs/etc).
585+ # - Optionally: rendered, UI-ready snippets (HTML/Markdown/plain) for trace + config.
586+ #
587+ # What is NOT stored:
588+ # - No signal arrays, maps, or large objects (TraceEvent must stay JSON-friendly).
589+ # - No global or cross-step state (events can be attached/serialized independently).
590+ #
591+ # Integration pattern (typical runner / notebook):
592+ # node(processing_data)
593+ # tracer.after_step(node, processing_data)
594+ # pipeline.attach_tracer_event(node, tracer,
595+ # include_rendered_trace=True,
596+ # include_rendered_config=True)
597+ # pipeline.done(node)
598+ #
599+ # Export:
600+ # - Pipeline.to_spec() includes node-level config + optional trace_events per node,
601+ # enabling graph viewers to show "what changed" as expandable panels.
592602
593603 def attach_tracer_event (
594604 self ,
0 commit comments