Purpose
-------
The runtime half of chart C of the overview-charts plan
(docs/DOCS_OVERVIEW_CHARTS_PLAN_2026-09-27.md in the workspace): run one
``oct`` command in this process, record every call between oct functions
while it runs, and compare what ran with the static call graph that
:mod:`oct.deps.call_graph` resolves from the source.
The static graph says what a command CAN call; the trace says what one run
DID call. The comparison is the point: an edge only the trace has is a call
the static resolver cannot see (a dispatch table, Click's command dispatch,
a decorator's wrapper), and a function only the static graph has is a path
that run did not take. The first trace of ``oct git commit`` (2026-09-27)
found one resolver gap this way (dispatch tables, since fixed).
Calls are captured with :mod:`sys.monitoring` (``PY_START``): for each call
into oct code the capture walks back from the new frame to the nearest
oct frame, which is the caller, and notes which library, if any, sat in
between (Click, contextlib). Code outside the oct package is disabled after
its first event, so the overhead is small. ``_dbg`` records say which
functions ran but never who called them, so they cannot supply the edges;
the ``_dbg`` stream of a traced run is available separately through
oc_diagnostics' own config (``"*": 9`` and ``log_format: "jsonl"``).
Responsibilities
----------------
- :func:`trace_oct_command` - run ``oct ARGS`` in-process under
``sys.monitoring`` and return a :class:`RuntimeTrace`.
- :func:`compare` - set a trace against a :class:`StaticCallGraph` below one
root function, and around it; name the functions that ran with no
``_dbg`` call.
- :func:`to_diff_dot` - render the comparison: both, trace only, static only.
Diagnostics
-----------
Domain: OCT-DOCS
Levels:
L2 - trace entry / exit with sizes
L3 - comparison totals, tool-id selection
L4 - deep tracing
Contracts
---------
- The traced command runs FOR REAL, in the current directory, exactly as
``oct ARGS`` would: ``git commit`` makes a commit. Callers must say so.
- The ``sys.monitoring`` tool is always released, whatever the traced
command does (``finally``), so a second trace in the same process works.
- Frames above the trace's own entry are never attributed: the outer
``oct docs`` invocation does not appear in the graph.
- Module bodies run by imports during the command, and Python 3.14's lazy
annotation functions, are set aside and counted, as the static graph sets
module-level code aside.
Dependencies
------------
- oct.core.diagnostics (_dbg structured logger)
- oct.deps.call_graph (StaticCallGraph - the graph a trace is set against)
- oct.docs.callgraph (reachable - the shared closure)
- oct (lazy; locates the imported oct package, the default package root)
- oct.cli (lazy; cli - the command group the trace runs)
- click (lazy; ClickException and Abort raised by the traced command)