Skip to content

fix(intercept): toServeStub silently drops behaviors, _rift, binary mode, and extra header values - #208

Merged
EtaCassiopeia merged 1 commit into
masterfrom
fix/rift-207-intercept-serve-guard
Aug 6, 2026
Merged

fix(intercept): toServeStub silently drops behaviors, _rift, binary mode, and extra header values#208
EtaCassiopeia merged 1 commit into
masterfrom
fix/rift-207-intercept-serve-guard

Conversation

@EtaCassiopeia

Copy link
Copy Markdown
Collaborator

Summary

InterceptImpl.toServeStub was silently discarding serve responses that the engine's action cannot deliver: behaviors (wait/decorate/repeat/copy/lookup/shellTransform), the _rift extensions (templated/script and latency/error/tcp faults), binary body mode, and the 2nd+ values of a multi-valued header. Registration returned success, so a fault-injection test stayed green while asserting against the plain 200 the author never asked for.

Rather than carrying these through (which requires an engine change), this change rejects them at registration time with a single InvalidDefinition error listing all offending constructs and pointing to redirectTo(imposter) as the correct path for full stub fidelity.

InvalidDefinition is widened to cover SDK-side rejection as well as the engine's HTTP 400; the sealed leaf set is untouched, so the cross-SDK contract holds. rift-scala took the same approach in achird-labs/rift-scala#147.

A reflection canary pins the record components of the model types the guard enumerates, so adding a field there fails the build instead of silently reopening this bug.

Verification

  • ./mvnw -o verify -DskipITs — BUILD SUCCESS with 518 core tests
  • javadoc:javadoc — clean
  • docs/intercept.md updated with the deliverable set

Closes #207

…iver (#207)

`InterceptImpl.toServeStub` projected an `IsSpec` down to the engine's intercept
serve action and silently discarded everything that action cannot carry:
behaviors (wait/decorate/repeat/copy/lookup/shellTransform), the `_rift`
extensions (templated/script and latency/error/tcp faults), binary body mode,
and the 2nd+ values of a multi-valued header. Registration returned success, so
a fault-injection test stayed green while asserting against a plain 200 the
author never asked for.

The engine cannot carry them: `ServeStub` in `intercept_rules.rs` is exactly
`{statusCode, headers: HashMap<String,String>, body}` and its deserializer has
no `deny_unknown_fields`, so posting the extra fields would be accepted and
ignored just as quietly. Carrying them through is an engine change, not an SDK
one, so this rejects instead.

`requireDeliverable` collects every offending construct in one pass and throws a
single `InvalidDefinition` naming all of them and pointing at
`redirectTo(imposter)`, which reaches a real imposter and has full stub
fidelity. It runs before the rule reaches the transport, so a rejected rule is
never registered, and both entry points (`Intercept.serve` and
`InterceptRuleBuilder.serve`) share the one guard site. The accepted set's wire
output is unchanged.

`InvalidDefinition` is widened to cover an SDK-side rejection as well as the
engine's HTTP 400; the sealed leaf set is untouched, so the cross-SDK contract
holds. rift-scala took the same client-side approach in achird-labs/rift-scala#147.

A reflection canary pins the record components of the model types the guard
enumerates, so adding a field there fails the build instead of silently
reopening this bug.

Closes #207
@EtaCassiopeia
EtaCassiopeia merged commit 3b28553 into master Aug 6, 2026
18 checks passed
@EtaCassiopeia
EtaCassiopeia deleted the fix/rift-207-intercept-serve-guard branch August 6, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(intercept): toServeStub silently drops behaviors, _rift, binary mode, and extra header values

1 participant