metadata: Add a 'warnings' slot that accumulates across stack frames
A warning is a Z5 which we record rather than raise, so that execution
continues and the diagnostic is not lost. The evaluator already emits
them (Z590-Z593) and WikiLambda already displays them, but nothing on
the orchestrator side could add one, and what did arrive was lossy: only
'executorDebugLogs' collected the values of every frame, so a second
warning silently replaced the first, and a nested frame lost to the one
enclosing it.
Generalise that single special case into a table of accumulating keys,
each with the element type of the typed list it becomes, so setMetadata(),
mergeKeys() and getMergedMetadata() all read the rule from one place.
Warnings are also deduplicated and capped: one raised inside a recursive
function occurs once per frame, and WikiLambda caches the envelope, so an
unlimited list makes every later read of that result more expensive.
A value arriving as a bare Z5 rather than as a list is wrapped, not
dropped, so an evaluator older than this change still reaches the reader.
An accumulating key holds a JS array from the write until the response
envelope needs a typed list, and setMetadata() is the only place which
takes the other shapes a value arrives in. Every later write adds to that
array in place, because a copy for each write costs O(n^2) and Z820 and
Z854 let one call write as many values as it likes. Each warning is
serialised once, and the identity is held against the warning, so that a
merge does not serialise the same warnings again for every frame.
The values of one frame now read in the order they were written, where
before the newest came first; the frames below still come first. A debug
log therefore reads in the order the calls ran, and the cap keeps the
earliest warnings, which is the more useful half of a warning that
repeats as a recursion goes deeper.
Assisted-by: Claude Opus 5
Bug: T427112