Report a description or a failure that cannot be rendered Stacked on #155, which is where exceptions thrown *by* a test are decided. This is about the two places outside a test body where an exception still took the suite down. ## Hole 1: a description A description is user code: `describe (nameFor x)` throws whatever `nameFor` throws. Nothing forced one until the output did, in the thread that collects results, where the exception took the suite down along with the results of every test that had already run. Worse, the terse output never forces a description at all, so the same suite passed piped into a file and died in a terminal. `reportUnrenderableDescriptions` walks the forest once in `runTestDefM`, after filtering and randomisation, and replaces a node whose description throws with a test that fails carrying that exception. Every runner gets its forest from `runTestDefM`, so one walk covers all of them and the two output formats agree by construction rather than by assertion. A `describe` takes its subtree with it: a group that cannot say what it is cannot sensibly report what is under it. The stand-in keeps the call stack of the `it` it replaces, so the failure points at the test whose name threw, and it is not retried, because the same description throws the same way every time. ## Hole 2: a failure Rendering a failure runs user code too: the `displayException` of whatever the test threw, the `Show` of a compared value, a message built lazily. That first ran in the thread collecting results, so a failure whose rendering throws — `effectful`'s errors among them — took the suite down after every test had already run, with the summary and every other result. `reportUnrenderableFailures` forces a result's rendering in the worker that produced it, where anything thrown is that test's own failure, and replaces what could not be rendered with an assertion carrying the message. An assertion, because that is what both output formats render as the text it is: the terse output does not print `extraInfo`, and an exception made in the handler carries a context whose backtrace points into sydtest's own forcing and holds a package-id hash that differs between builds. Nothing unrenderable is kept — exception, extra info, failing inputs, labels, classes and tables all go — because a result that still carries it still has something that throws when the output reaches it. Forcing once is enough: the output renders the same value again, and a value that rendered once renders again. ## Tests - `UnrenderableDescriptionSpec`: reported as one failing test by each runner, a `describe` collapsing in place of its tests, the rest of the suite still running, and the failure naming what threw. All seven fail without the fix. - `UnrenderableFailureSpec`: `reportUnrenderableFailures` directly, including extra info that does not render, which the pretty output renders and which an earlier version of this branch left in place. - `sydtest-output-test` gets a case whose `displayException` throws. That suite runs its spec through all four runners and golden-tests the rendering, so without the fix it dies during the first of the four and never reaches the golden tests. The case sits at the end of its spec with its type declared below `spec`, because every failure there is numbered and every test records its source line, so anything added earlier renumbers the lot. ## Version 0.35.0.0. No API changes, but a suite that passes today with a lazily-unused bottom description starts failing, which is more than a patch and matches how 0.32.0.0 and 0.33.0.0 were versioned.