The S2 library uses what you might call a half open containment model. So when your query point is on a vertex, about half of the time it will say that point is contained, and the other half of the time it is not contained.
That is, the S2Loop.contains(S2Point) operation has no notion of "on the boundary"; points are always judged to be inside or outside, regardless of whether they are far from the boundary, or right on top of it.
This should cause no problem for a geofence use case, since the transition from inside to outside or vice-versa is what you're looking for.
If you wanted to test whether a point is "moving along the fence" then you would need to bring your own notion of what that means. E.g. always within 10 meters of the fence, or something like that. Which isn't the same as a contains point test.
Let me know if that clears anything up for you, and by all means if you have any other questions just ask.
- Eric