SDK and error contracts
The boundary
The boundary What wisent errors owns, and what it deliberately does not. The package decides the content of a failure report — the vocabulary, the shape, the derived fields, the trim rule — and almost nothing else. Everything on the far sid
The boundary
What wisent-errors owns, and what it deliberately does not. The package decides the content of a failure report — the vocabulary, the shape, the derived fields, the trim rule — and almost nothing else. Everything on the far side of this line stays in the products, on purpose.
Owned here
- The seven codes, and everything derivable from a code:
severity,retryable,outage, the edge HTTP status, the retryable exit-code rule (catalogue). - The classification of an upstream HTTP status into a code.
- The envelope shape, its stable key set, and its serialization order (envelope).
- The trim rule — hard cut, ends stripped — and the opt-in word-edge variant.
- The shape of a failure point: a dotted lowercase path, one segment or more.
- The proof that all four runtimes implement the above identically (conformance).
Not owned here
Product messages. They go in detail, verbatim. The package truncates;
it never writes, paraphrases, or re-classifies a sentence.
Provider text. It passes through and is truncated, never paraphrased or re-classified. Their words are data.
Failure-point registries. The package validates only the shape of
failure_point; which points exist, and how deep they go, is each product's
own registry. stado's come from its subcommand path and run from cli to
cli.host.user.create; probierz and growth-tactics are two-segment. A
shared rule that refused what five products already emit would be the
package being wrong, so depth deliberately carries no meaning.
Logging plumbing. Each product keeps its own emitter; this package
decides the content, not the transport. The one transport in this
repository is the Swift WisentFailureReporter, which exists for the two
native desktop clients and posts envelopes to a Probierz intake without
ever failing or blocking its caller (runtimes); nothing in
the Rust, Python, or JavaScript runtimes ships or logs anything.
Trim widths. 2000 is the package's own bound (DETAIL_LIMIT), used
when it trims on your behalf. A product's width is the product's decision
and is passed as an argument.
Exit-code conventions. Only the retryable path is remapped, to 69
(EX_UNAVAILABLE). A caller that already chose an exit code keeps it.
New codes. Seven, exactly as the reference had. A case the seven cannot
describe is worth adding; nothing found so far is one. The closest call is
recorded rather than hidden: two native clients independently invented
offline — retryable, warning, deliberately not an outage, because a
device with no signal must not tell its owner our infrastructure is down.
It is still not in the catalogue for one reason: http_status and
exit_code are derived for every code, and neither applies to a code no
server can observe and no command can exit with. Inventing values there is
the exact shape of the rules this package had to withdraw on its first day,
so both clients keep offline beside the seven with the reason written
next to it. That changes if a third product needs it, or if the catalogue
grows a way to say "this derivation does not apply".
Why the line sits here
Everything derivable from the code is derived; everything a caller decides
is an argument. A call site chooses where it broke, what the layer below
said, and which subject it concerns — it never chooses severity,
retryable, or outage, which is why one code cannot come to mean
different things in different products. The fleet's history is the
argument: five of six hand-kept copies drifted in the derived table, in the
same two lines, while the vocabulary — the part people compared — stayed
intact everywhere. Drift entered exactly where a copy had to be adapted;
the shared, generated, conformance-checked table is what removes that
surface. How a product adopts it is integration.