v1.0.2
Patch release closing the v1.0.2 priority list from
docs/assessment-maintainable-architect-v4-head-2026-07-18.md, a
cross-review of v1.0.1 + post-tag HEAD combining an external review and
an independent Codex direct review
(docs/repository-assessment-head-codex-2026-07-18.md). No breaking
changes; module path unchanged.
Fixed:
- Panic-recovery log fields (stack trace included) were dropped for a
panic recovered after the response was already committed, or after a
successful Hijack, because field selection was keyed off the stale
HTTP status of the prior response rather than the panic itself.
Fields are now derived from the recovered error's own severity;
http_statusis no longer reported for these two cases since no
error response was actually rendered, andresponse_committed_status
/hijackedremain the transport-level truth in its place. safeJSONMarshalnow validates that a nil-errorjson.Marshal
result is actually valid JSON. Under legacyGODEBUG=panicnil=1
semantics, a customMarshalJSONthat does a literalpanic(nil)
was invisible torecover(), sojson.Marshalcould return a
truncated, invalid body with a nil error - silently reported as a
fully successful response.- A marshaler panic carrying an
errorvalue is now wrapped with%w
instead of flattened with%v, soerrors.Is/errors.Ascan still
reach it throughRenderErr. - RFC 9457 problem titles no longer render empty for a nonstandard
status (e.g. a custom code mapped to 499):http.StatusText
returning""now falls back to the package's own occurrence-
invariant per-code text, matching the JSON/HTML fallback bodies.
Changed:
New/Wrapnormalize an emptyErrorCodetoErrCodeInternal
instead of letting""ride through to the wire as the
machine-readable classification key.RegisterStatusCodeand
RendererConfig.StatusCodesnow reject an empty code key at
registration.- Both GitHub Actions workflows declare
permissions: contents: read
explicitly rather than relying on the mutable repository-level
default, and the vulnerability-scan workflow pins
govulncheck@v1.6.0instead of floating@latest, so a future scan
result stays reproducible against a fixed scanner version.
Test coverage: 100.0% (root module), 100.0% (zerologadapter).