Skip to content

perf(people): bind Employment-separation verdicts to JSON response media type #387

Open

Description

@seonghobae

Finding

The current Employment-separation buyer-path harness parses response.body with the strict JSON boundary and validates status/body semantics, but it does not validate the response media type before accepting a governed success/conflict verdict.

Canonical People HTTP truth on current #64 emits Content-Type: application/json for _send_json(...), including /v1/employment-separations. On current #317, parseJson(response) ignores response.headers, so a proxy/service returning the same governed-looking body under text/plain, a missing Content-Type, or an ambiguous duplicate case-variant Content-Type can still contribute a passing check and a clean employment_separation_unexpected_response Rate. That is a commercial-evidence false-GREEN: the transport no longer proves the published JSON representation that the harness claims to measure.

Required repair

Test first, then minimally:

  • add a response-contract boundary that accepts one own Content-Type field whose media type is application/json (case-insensitive, optional parameters allowed) and rejects missing/non-string/non-JSON/ambiguous case-variant duplicates;
  • invoke that boundary before parsing the response body in the buyer workload so first-commit, replay, rejection, and contention all fail closed on the same transport contract;
  • retain the existing duplicate-aware raw JSON body parsing, closed success/error envelopes, operational UUID/timestamp/replay checks, pinned k6 runtime and outcome/latency cardinality contracts;
  • do not add gateway/provider assumptions or weaken the p(95) <= 20 ms acceptance boundary.

Keep open through protected/integration acceptance; branch-local repair is not a close condition.

Activity

  1. seonghobae commented on Sep 15, 2026

    @seonghobae
    ContributorAuthor

    Repair lineage now on #317:

    • test-first 807eaf652a38062aef3228b34a9ff9e5bbeab13e adds the media-type regression before the contract exists;
    • 0ea2a597712df3628afe601777f63b1d8c9ce4c8 adds hasGovernedSeparationJsonMediaType(...);
    • current 273396de823b94c1456602318cb0f8c7c14ba32c applies the boundary before strict body parsing for first-commit, replay, rejection and contention.

    Pinned-runtime primary-source verification: Grafana k6 v2.2.0 lib/netext/httpext/response.go defines HTTP Response.Headers as map[string]string, so the boundary intentionally consumes string values and does not adopt newer/browser response-header APIs. Focused local assertions for canonical JSON, parameterized JSON, missing header, text/plain, case-variant ambiguity and non-string value are 6/6 PASS. #317 still has no hosted exact-head workflow run; keep this issue open through protected/integration acceptance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions