Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #362 +/- ##
===========================================
Coverage 100.00% 100.00%
Complexity 579 579
===========================================
Files 62 62
Lines 2007 2007
===========================================
Hits 2007 2007 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
rmcdaniel
pushed a commit
that referenced
this pull request
Apr 17, 2026
Command and update payload previews rendered in RunDetailView, HistoryTimeline, and RunUpdateView previously went through the legacy Serializer::unserialize sniffer. The sniffer routes by first byte (base64 prefix → Base64, JSON markers → Json, otherwise → Y) and cannot detect binary Avro blobs, so Avro-coded commands rendered as opaque base64 strings (or worse, as the failed Y-decoded garbage) in Waterline's payload inspector and in the CLI's describe/history output. Thread the persisted payload_codec through CommandPayloadPreview and RunUpdateView::normalizeTypedValue so the stored codec is used for decode when known. When codec is null (rows persisted before payload_codec was populated), behavior is unchanged — both helpers still fall through to the sniffer. Advances acceptance criteria on the release-gating parity suite (#362): "Waterline renders Avro payloads readably" and "CLI renders Avro payloads readably" transitively inherit the fix through the shared observability view helpers they already consume. Decode failures in the preview helpers continue to fall back to the raw blob rather than throwing — these are display helpers, not strict decoders. Strict codec-mismatch detection remains at ingress (PayloadEnvelopeResolver). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rmcdaniel
pushed a commit
that referenced
this pull request
Apr 17, 2026
… Avro export
Two pieces of the release-gating Avro parity surface:
1. Loud, typed codec-mismatch ingress errors
Add Workflow\Serializers\CodecDecodeException — a typed exception that
names the declared codec, what the decoder actually saw, and a
remediation hint. The Avro and Json codecs now throw it instead of a
generic RuntimeException when the bytes don't match the declared codec.
The ingress diagnosers cover the two most common cross-codec mistakes:
- JSON bytes labeled `avro` (producer JSON-encoded but tagged it Avro)
- Avro bytes labeled `json` (producer Avro-encoded but tagged it JSON)
In both cases the message names the codec, describes the symptom, and
tells the operator how to fix it ("change the codec tag to X" or
"re-encode the payload"). The wrapping ValidationException at the HTTP
ingress (PayloadEnvelopeResolver) preserves the typed message verbatim
so it shows up in API responses without losing context.
Covers acceptance criteria from the issue:
- "Sending JSON bytes under an `avro` codec tag produces a loud, typed
error — not silent garbage"
- "Sending Avro bytes under a `json` codec tag produces a loud, typed
error"
- "Avro decode failure names the codec, expected schema, and a
remediation — not a generic RuntimeException"
2. Self-describing Avro history-export bundles
HistoryExport bundles now include a top-level `codec_schemas` map. When
the bundle contains any payload encoded with the Avro codec (whether on
the run, commands, updates, signals, or tasks), the map embeds the
generic-wrapper schema JSON plus the documented prefix bytes (0x00
generic wrapper, 0x01 typed schema). An offline consumer reading the
export — without the workflow runtime in scope — can decode the
0x00-prefixed Avro payloads using only the bundle.
Bundles with no Avro payloads keep `codec_schemas: {}` so the field is
always present and shape-stable, simplifying consumer code.
Tests: 7 new ingress-mismatch unit tests; 2 new HistoryExport tests
covering the Avro-present and Avro-absent codec_schemas cases. All 130
tests across the changed surface pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rmcdaniel
pushed a commit
that referenced
this pull request
Apr 17, 2026
Mixed-codec runs (JSON run payload with an Avro signal or update) could previously produce history-export bundles where the update and signal rows lacked their own payload_codec field. collectCodecSchemas() already scanned those rows for Avro, so an Avro signal/update went undetected and the offline consumer never got the avro wrapper schema. - HistoryExport::update() and ::signal() now emit payload_codec alongside the encoded arguments/result, so codec_schemas detection and offline decode both see row-local codec metadata. - Fix latent typo where update export read \$update->name instead of the real \$update->update_name column; the exported 'name' field was always null, including in redaction-context callbacks. - Regression test asserts mixed-codec bundle carries row-local payload_codec and triggers codec_schemas.avro even when the run itself is JSON-coded. Existing full-snapshot test now asserts signal payload_codec round-trips.
rmcdaniel
pushed a commit
that referenced
this pull request
Apr 17, 2026
…rence 8 tests, 35 assertions covering: - Start input round-trips under Avro with type fidelity - Full workflow lifecycle: start -> activity -> signal -> complete - Float/int fidelity (3.14 stays float, 42 stays int) - Every payload row tagged avro (no json codec leaks) - History export includes codec metadata - Schema evolution: v1 payload decodes with v2 reader schema - Negative: non-Avro bytes under avro tag produce typed errors - JSON-tagged-as-avro gets diagnostic mentioning JSON Documents generic wrapper limitation: integer-valued floats like 3.0 lose precision through json_encode (becomes 3). Typed Avro schemas (#288) would fix this; generic wrapper does not.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
AssertionErrorguards so test behavior does not depend on PHPassertsettingsrunningInConsole()preconditions explicit in test fixtures instead of letting them disappear when assertions are disabledWorkflowTest::testCompletedDelay()to expect the deterministicTestWorkflowside-effect log entryTesting
composer feature -- --filter AsyncWorkflowTestvendor/bin/phpunit --testdox --testsuite feature --filter '^Tests\\Feature\\WorkflowTest(::.*)?$'composer unit -- --filter WorkflowStubTest