**DRAFTING**
Note that we'll double check assumptions and timing here / on Slack / face-to-face via Meet, as all of this is coming together fast over the next 1-3 weeks.
When a request that is schema validated bears the HTTP header `X-Experiment-Enrollment`:
# 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-Enrollment` header is present but malformed, drop the request.
# 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 request.
# 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-Enrollment` 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-Enrollment` 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-Enrollment` 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 3 we'll be unsetting the `X-Experiment-Enrollment` header in Varnish eventually, but right now we're just trying to verify correctly functioning processing at EventGate.
= Part 2, Varnish =
After part 1 is confirmed as working: Varnish should handle EventGate-destined messages as follows
- If a request is destined for a path starting with `/v1/events` for internet facing endpoints going to EventGate, then the `X-Experiment-Enrollment` header should be unset unilaterally.
- 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 ==
[ ] Otherwise well-formed events sent from the internet toward the Beta Cluster EventGate v1 endpoint via intake-analytics.wikimedia.beta.wmflabs.org bearing an `X-Experiment-Enrollments` header and an `experiment` fragment are dropped by EventGate.
[ ] Otherwise well-formed events sent from the internet toward the production EventGate v1 endpoint via intake-analytics.wikimedia.org bearing an `X-Experiment-Enrollments` header and an `experiment` fragment are dropped by EventGate.
[ ] Well-formed events sent from the internet toward the Beta Cluster EventGate v2 endpoint bearing an `experiment` fragment and a well-formed `X-Experiment-Enrollments` header will be honored by EventGate as described at the opening part of this ticket's Description.
[ ] Well-formed events sent from the internet toward the production EventGate v2 endpoint bearing an `experiment` fragment and a well-formed `X-Experiment-Enrollments` header will be honored by EventGate as described at the opening part of this ticket's Description.
Note here that we're still allowing Varnish to trust the `X-Experiment-Enrollments` header, even thought it was sent manually by a client. This is just to make sure everything is working.
= Part 3, Varnish =
After part 2 is confirmed as working: Varnish should additionally handle EventGate-destined messages as follows:
- If a request is destined for a path starting with `/beacon/v2/events` for internet facing endpoints going to EventGate, then the `X-Experiment-Enrollment` header should be unset unilaterally before subsequent processing. The `X-Experiment-Enrollment` header will be set with a meaningful value 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`.
== Part 3 acceptance criteria ==
[ ] Otherwise well-formed events sent from the internet toward the Beta Cluster EventGate v2 endpoint via intake-analytics.wikimedia.beta.wmflabs.org bearing an `X-Experiment-Enrollments` header and an `experiment` fragment are dropped by EventGate (assuming the event isn't associated with an enrollment by Varnish's determination).
[ ] Otherwise well-formed events sent from the internet toward the production EventGate v2 endpoint via intake-analytics.wikimedia.org bearing an `X-Experiment-Enrollments` header and an `experiment` fragment are dropped by EventGate (assuming the event isn't associated with an enrollment by Varnish's determination).
= 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.
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.