When a request that is schema validated bears the HTTP header `X-Experiment-Enrollments`:
# Verify that the header is well-formed. It should match a format like that in [[ https://gitlab.wikimedia.org/repos/sre/libvmod-wmfuniq/-/blob/dea2d799ae3e2cd61c6c0144bfd27e007174971f/src/vtc/fullexample.vtc#L38 | fullexample.vtc ]]. If the `X-Experiment-Enrollments` header is present but malformed, drop the request. Otherwise, for each event...
# Verify that the configuration for the stream for the event includes a `producers.eventgate.enrich_fields_from_http_header` header hoisting entry for `x-experiment-enrollments`. If it doesn't, drop the event.
# Verify that the event corresponds to a schema for which there is an `experiment` fragment (cf. [[ https://gitlab.wikimedia.org/repos/data-engineering/schemas-event-secondary/-/commit/dfbfacaf9bce0fcfc86060670488488af06070f0#7c77f467375ef22d36154ff29ccd7ef66f5cca4c_0_9 | the experiment YAML ]] and its inclusion in the web schema in that diff). If the event doesn't contain an `experiment` fragment, drop the event.
# Look at the event payload's `experiment.enrolled` and `experiment.assigned` values and confirm that there is a corresponding `experiment_name=group_name` assignment (so that `experiment.enrolled` corresponds to `experiment_name` and `experiment.assigned` corresponds to `group_name`) in the `X-Experiment-Enrollments` header. If the fields don't map correctly, drop the event.
# Verify that `experiment.subject_id` contains a string value of `awaiting`. If it doesn't, drop the event.
# If all of this has worked so far, change the `experiment.subject_id` value to that provided by `X-Experiment-Enrollments` for the `experiment_name=group_name` (i.e., the part that follows the `/` symbol for the given record).
# If all of this has worked so far, redact from the event payload's fields the hoisted value that arose from the `x-experiment-enrollments` header hoisting entry in `producers.eventgate.enrich_fields_from_http_header`. As an aside, technically speaking, the name of the event payload field taking the hoisted value could be anything, although in practice we'll likely want to encourage some consistent naming standard that indicates that the field's value will not be retained.
.
# When events are dropped register these as schema validation errors so they show up in the EventGate dashboard.
Using the example from [[ https://gitlab.wikimedia.org/repos/sre/libvmod-wmfuniq/-/blob/dea2d799ae3e2cd61c6c0144bfd27e007174971f/src/vtc/fullexample.vtc#L38 | fullexample.vtc ]], we see the `X-Experiment-Enrollments` header as having the following sort of form:
```
2025-abtests2-foo-10x10=grp0/cSbN4iEngsnYMz1vEK9O6g;2025-abtests2-sel1-4x25=grp1/ckNy35nnQikEwoey8XS1Lw;2025-abtests2-sel2-4x25=grp1/ckNy35nnQikEwoey8XS1Lw;2025-abtests2-udom=grp2/yHi9O8ylLWG2qFw1FfCHww;
```
Notice that records are semi-colon separated. Each record is of the form `experiment_name=group_name/subject_id`.
- `experiment_name` should match the regex `^[A-Za-z0-9][-_.A-Za-z0-9]{7,62}$`
- `group_name` values should match the regex `^[A-Za-z0-9][-_.A-Za-z0-9]{1,62}$`
- `subject_id` should be base64-decodable and its length prior to decoding should be at least 22 characters (it doesn't need to be decoded-and-processed, this is just to ensure the value looks correct).
== Part 1 acceptance criteria ==
[ ] Code
[ ] Tests
[ ] Works in beta cluster for requests sent to the existing v1 endpoint on intake-analytics.wikimedia.beta.wmflabs.org. Note that in Part 2 we'll be unsetting the `X-Experiment-Enrollments` header in Varnish eventually, but right now we're just trying to verify correctly functioning processing at EventGate.
[ ] Works in the prod cluster for requests sent to the existing v1 endpoint on intake-analytics.wikimedia.org. Note that in Part 2 we'll be unsetting the `X-Experiment-Enrollments` header in Varnish eventually, but right now we're just trying to verify correctly functioning processing at EventGate.
= Part 2, Varnish =
- The `X-Experiment-Enrollments` header should be unset unilaterally before further request processing in Varnish. The `X-Experiment-Enrollments` header will be set with a meaningful value by Varnish if the user is enrolled in one or more experiments and will be conveyed in the request to EventGate only if the client-requested path was `/beacon/v2/events?hasty=true`.
- If a request is destined for a path of `/beacon/v2/events?hasty=true` for internet facing endpoints, such requests should be forwarded to the same EventGate endpoints as the `/v1/events` requests.
== Part 2 acceptance criteria ==
A separate task for an //A/A experiment// (and another one or two for some initial handcrafted experiments) should make it possible to set the `X-Experiment-Enrollments` header in Varnish manually for EventGate's processing to verify end-to-end that processing is working as expected.
= Important notes =
This here task doesn't presume clients will have started routing experiment-associated events to the v2 endpoint. That will be handled separately in {T391988}, which entails both server configuration and client changes.