When a request that is schema validated (i.e., its events conform to their schemata) 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, log an error and drop the request. Otherwise, for each event...
# Verify that the configuration for the stream for the event includes a `producers.eventgate.use_edge_uniques` key with a value of `true`. If it doesn't, drop the event and register this as a schema validation error so it shows up in the EventGate dashboard.
# 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 and register this as a schema validation error so it shows up in the EventGate dashboard.
# 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 and register this as a schema validation error so it shows up in the EventGate dashboard.
# Verify that `experiment.subject_id` contains a string value of `awaiting`. If it doesn't, drop the event and register this as a schema validation error so it shows up in the EventGate dashboard.
# 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).
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.
[ ] Assuming things are enabled in production and working as expected, update https://wikitech.wikimedia.org/wiki/Event_Platform/Stream_Configuration
= 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.