Story: Fix jetstream_admin missing gzip decompression

Table of Contents

This page documents a story in Sprint 24. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

Goal

Split out of Fix image-batch NATS payload overflow, add SVG compression once that story's core goal (compression + byte-size-aware batching) shipped: the one remaining loose end, raised non-blocking in PR #1706 review, doesn't belong under a now-closed story.

jetstream_admin::peek_message() and peek_last_message() (projects/ores.nats/src/service/jetstream_admin.cpp) read natsMsg data directly without extracting headers or calling decompress_if_flagged(), unlike extract_message() in client.cpp. Since js_publish() now transparently gzips payloads at or above the 4096-byte threshold, any JetStream message that crosses it (e.g. an image-batch workflow message) shows up as raw gzip bytes in admin tooling such as ores.qt's QueueDetailDialog. Fix by extracting headers the same way extract_message() does, then running data through decompress_if_flagged() before returning stream_message.

Status

Field Value
State DONE
Parent sprint Sprint 24
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-07-29

Acceptance

  • [X] peek_message() and peek_last_message() extract headers and call decompress_if_flagged() before returning stream_message, same as extract_message().
  • [X] A JetStream message above the 4096-byte compression threshold (e.g. an image-batch workflow message) displays decompressed in admin tooling (ores.qt's QueueDetailDialog), not as raw gzip bytes.

Tasks

Task State Start End Description
Decompress payloads in jetstream_admin peek_message/peek_last_message DONE 2026-07-29 2026-07-29 jetstream_admin::peek_message() and peek_last_message() (projects/ores.nats/src/service/jetstream_admin.cpp) read natsMsg data directly without extracting headers or calling decompress_if_flagged(), unlike extract_message() in client.cpp. Since js_publish() now transparently gzips payloads at or above the 4096-byte threshold, any JetStream message that crosses it (e.g. an image-batch workflow message) will show up as raw gzip bytes in admin tooling such as ores.qt's QueueDetailDialog. Fix by extracting headers the same way extract_message() does, then running data through decompress_if_flagged() before returning stream_message. Raised in PR #1706 review, explicitly non-blocking for that PR.

Decisions

Shared helper, not inline duplication

Decided in the decompress task. Added a fill_data_and_headers() helper in jetstream_admin.cpp's anonymous namespace, mirroring client.cpp's extract_message(), rather than inlining the header-extraction + decompress_if_flagged() logic twice (once in peek_message(), once in peek_last_message()). jetstream_admin has no existing unit-test coverage (live-JetStream- only, exercised via manual QA), so no new unit test was added; local build and the existing ores.nats.tests suite both pass.

Out of scope

Emacs 29.3 (Org mode 9.6.15)