FLOW_ONLY note now names step J. Live gate on the docker rig (8 nodes rebuilt
from this branch via docker/deploy.sh, FlowLogDemo seeded by
docker/seed-flow-log-demo.sh — idempotent, add then update proven):
J step logs live+replay -> YES
live: YES root=5793ddc2-5273-4e62-86c2-ccfc8de0e080 logs=3 levels=debug,info,warn scriptRun=Failed error=CALL_FAILED
replay: YES root=5793ddc2-5273-4e62-86c2-ccfc8de0e080 logs=3 levels=debug,info,warn scriptRun=Failed
H, H2 and I stayed YES in the same run.
Browser check (Playwright, /deployment/flow-debugger?executionId=<J root>,
screenshot /tmp/flow-log-demo.png): the SCRIPT RUN node is red with subtitle
"InvalidOperationException: demo failure" and badge "! 1 ≡ 2"; the WRITE node
carries no badge; the strip reads "LOG 0 errors · 1 warnings · 2 info"; the
detail panel opens on "Log (3)" with the full System.InvalidOperationException
block and the three info/debug/warn script lines.
FlowDebugRunner.RunMethodAsync now passes InboundScriptResult.ErrorDetail through to the
synthesized inbound audit row's errorDetail, so a SCRIPT_ERROR run's exception ToString() lands
on AuditDetails.ErrorDetail for the Flow Debugger's inbound node to read (never surfaced to the
HTTP caller). FlowDebugRunResult grows an additive LogsTruncated (default false, last positional
member) reporting the inline FlowTraceCollector's low-priority (ScriptLog) truncation separately
from Truncated (step-row fidelity); RunMethodAsync/RunScriptAsync thread collector.LogsTruncated
through on their two collector-backed results.
Task 5 code-review follow-ups:
- I1: ExternalSystemHelper gates its TraceStepScope on a new isTraced ctor arg
(default false for direct construction), not on `_traceSink is not null` — a
traced run without an inline collector still writes durable ScriptLog rows
that must name their step.
- I2 (design §5): an inline shared script now SHARES its caller's ScriptLogger
via the new `sharedLog` ctor param — one line cap, one anchor, one closing
row. Consequence documented on the Log property: a shared script's lines
carry the PARENT run's ExecutionId and land on the parent's ScriptRun node.
- M3: TraceCapturingLogger swallows a throwing formatter — most of what it
captures is best-effort "audit write failed" warnings logged from inside a
catch block, and a formatting exception must not escape that path.
- Tests: ApiCall step attribution, traced-without-collector, shared-script
logger sharing, nested batch/wait scope attribution + unwind, throwing
formatter; test (c) now also pins the anti-recursion property (EmitLog must
log through the undecorated logger).
CompileSurfaceParityTests stays red until Task 7 mirrors Log on ScriptCompileSurface.