Canvas Context runs now set an explain flag. With it, each trace row carries
the module's display name and a handler detail dict: which derivation branch
fired, with every test's result and the value it read; a wildcard's option,
odds, pool and the constraints that re-weighted it; a constraint's reach and
rule counts. Warnings a module raised name it as their owner, and trace rows,
warnings and nested @{} picks are tagged with the Context node's graph id.
WP Debug forwards the nested-pick log, node seeds, internal flags, rolled
axes, constraint hits and multi-pick items.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wwo837fQ1tm6RacaQGYom1
25 lines
914 B
Python
25 lines
914 B
Python
"""Per-module run detail for the WP Debug node.
|
|
|
|
A run opts in by setting ``ctx["__wp_explain__"] = True`` (the canvas Context
|
|
node does; the Test Runner's thousand-seed runs don't). The pipeline then gives
|
|
each module an empty ``ctx["__wp_module_detail__"]`` dict before it resolves and
|
|
files whatever the handler put there on that module's trace row as ``detail``.
|
|
|
|
Handlers call :func:`module_detail` and write only when it returns a dict, so
|
|
an un-opted run pays one dict lookup per module and nothing else.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
EXPLAIN_KEY = "__wp_explain__"
|
|
DETAIL_KEY = "__wp_module_detail__"
|
|
|
|
|
|
def module_detail(ctx: Any) -> dict[str, Any] | None:
|
|
"""The active module's detail sink, or None when nobody asked for one."""
|
|
if not isinstance(ctx, dict):
|
|
return None
|
|
sink = ctx.get(DETAIL_KEY)
|
|
return sink if isinstance(sink, dict) else None
|