Skip to content

perf(people): forbid redirect-following in Employment-separation buyer evidence #393

Open

Description

@seonghobae

Finding

Draft #317 currently uses http.post(...) / http.batch(...) without a request-scoped redirects override. Pinned k6 v2.2.0 initializes ParsedHTTPRequest.Redirects from the global MaxRedirects, and the default k6 behavior follows redirects. The returned Response represents the final request after redirects.

That creates a commercial-evidence false-GREEN: /v1/employment-separations can redirect and a later endpoint can return the expected 200/409 JSON/privacy envelope, while #317 records the final response and latency as if the canonical People route itself produced the governed result. Redirect traffic can also alter request-rate accounting and make the measured buyer path differ from the route under test.

Required repair

  • Test first: request policy must fail closed unless redirects === 0 for every single and contention request.
  • Apply the same request policy to first_commit, replay, rejection and both http.batch contention requests.
  • Do not rely on global runner configuration; use request-scoped policy so the workload contract is self-contained.
  • Preserve current auth/idempotency headers, direct-network requirement, response privacy/media-type contracts, cardinality and latency evidence.
  • Keep test(perf): add Employment separation buyer-path workload #317 Draft until protected/integration and authenticated performance-attestation conditions are satisfied.

Primary evidence

  • Pinned k6 v2.2.0 js/modules/k6/http/request.go: ParsedHTTPRequest.Redirects defaults to state.Options.MaxRedirects, while request parameter redirects overrides it.
  • Grafana k6 HTTP documentation: redirects are followed by default; Params.redirects overrides maxRedirects per request; final Response information pertains to the last request in a redirect chain.

Owner: #317 / #316 performance acceptance lane. This issue is not complete on branch-local repair alone.

Activity

  1. seonghobae commented on Sep 15, 2026

    @seonghobae
    ContributorAuthor

    Implemented test-first on Draft #317.

    • RED commit: b453ef96fe865dd3d2ad70d773d16c0519e6fd1f adds employment_separation_request_contract.test.mjs before the request-policy module exists. Focused Node execution fails with ERR_MODULE_NOT_FOUND, so the predecessor lane has no no-redirect request contract.
    • Causal helper: b78e7fb5901e5c35e0027c90f1d67a5c0c69e4b1 adds governedSeparationRequestParams(...), preserving caller headers/tags while setting request-scoped redirects: 0 and rejecting unknown profiles/non-object headers.
    • Integration: 3a78672949032f324fe3bbeae0f427ec73920bd7 applies the helper to ordinary http.post(...) and both http.batch(...) contention requests. No global runner option is relied on.
    • Focused helper test reproduction is 4/4 GREEN locally. This is developer-side contract evidence only; it is not hosted k6 execution or latency acceptance.
    • Fresh compare against canonical People fix(people): protect governed mutation runtime types #64 0b4409e50a1fd646c1f960164012df5984cbde0c: merge base is exactly fix(people): protect governed mutation runtime types #64, behind 0 / ahead 286, and all 45 child-owned changed files remain under tests/performance/....

    Primary runtime evidence remains pinned k6 v2.2.0: ParsedHTTPRequest.Redirects starts from global MaxRedirects, while request param redirects overrides it. #393 remains 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