Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Policy API draft #322

Closed
wants to merge 0 commits into from
Closed

Add Policy API draft #322

wants to merge 0 commits into from

Conversation

marie-x
Copy link
Collaborator

@marie-x marie-x commented May 25, 2019

Explain pull request

Add new Policy API and associated schema for digitally communicating micromobility policy from Agencies to Providers

Is this a breaking change

  • Yes, breaking
  • No, not breaking
  • I'm not sure

Provider or agency

Which API(s) will this pull request impact:

  • provider
  • agency
  • both
  • neither

@marie-x marie-x requested review from hunterowens, thekaveman and a team as code owners May 25, 2019 00:27
@marie-x marie-x changed the title add policy draft add Policy API first draft May 30, 2019
@marie-x
Copy link
Collaborator Author

marie-x commented May 30, 2019

Feedback solicited!

Copy link
Collaborator

@hunterowens hunterowens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Karcass @whereissean thank you both for putting this together. This is a great first start for getting standardized info about micromobility policies. A few overall comments (also sorry for the delay in getting this back to y'all )

  1. I'd like to simplify this as much as possible so that any city can participate. If possible, any cities should be able to publish a policy without having to spin up a full REST API.

  2. I'd like to check that we are being expressive of all the various city policies. tagging @mateoclarke @thekaveman to check if this would be able to express, your cities policies well.

  3. We need to solve the preferred_pick_up and preferred_drop_off

  4. It is unclear how this interfaces with service_areas, it would seem that this supplants them. I'm unsure why this is a whole separate section rather than a subsection of agency (given that is an API distributed by a agency). We should resolve.

  5. Would be good to have JSON Schema / Policy Linter or similar included in the spec so that providers and cities can validate these objects and ensure they follow the rules.

policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated
<a name="distribution"></a>
## Distribution

Policies may be published by Agencies or their authorized delegates via JSON objects via REST API.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make this simpler rather than requiring full REST. Ideally, IMO, a city should be able to have a static endpoint or arcGIS online endpoint that contains a policy page. This will enable all cities to publish policy documents easily.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A static endpoint/file would prevent the use of Provider-specific Policy objects, e.g. dynamic caps, which are a key requirement from LADOT. Agree that a subset of Policy could be done with static files, and that that's a worthy goal. I'd like to defer discussion of static-endpoint until next release.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a couple changes to support this. More verbiage coming by end of week.

policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated

Creating, editing, and publishing policies may be performed via a variety of mechanisms, and are therefore not specified here. Authoring tools would optionally provide schema extensions for tooling, including author, Provider-specificity, etc. We may add a specific instance of such extensions in a later revision of this document, but at present that’s TBD.

One mechanism may be via a source-control repository, where pull-requests to Policy objects are proposed, left open to public commentary, etc., and served as static content via the endpoints listed above.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove this couple lines, as this is more relevent for a PR message rather than for actual inclusion in the spec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 196 is meant to address your static-served-files ask. Were you asking to lose line 194 too?

policy/README.md Outdated
Dynamic caps can also be implemented by replacing the “maximum” integer with a URL to a source for dynamic data. This could be for provider-specific caps that go up and down, or for global caps e.g. “total 500 scooters at the coliseum”. Dynamic data sources would be required to have historical data so that validating prior information, and downloaded dynamic data would have a time-to-live.

<a name="compliance"></a>
## Compliance
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, we should either solve or remove this from the documentation here.

policy/README.md Outdated
<a name="compliance"></a>
## Compliance

A Compliance API will be described in a separate MDS specification. In brief, it will take as inputs the MDS Agency data stream, the MDS geography data, and these MDS Policy objects and emit Compliance objects. This work is in draft form but is closely informed by this Policy specification.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above. This seems overly complex

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to leave this forward-pointer. We will have the Compliance API spec soonish, once Policy firms up.

policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated
}
```

More examples to come. :)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove line from spec here. Commentary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, removing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amendment, we're going to add all of the current Policy objects in use by LADOT for compliance measurements.

@hunterowens
Copy link
Collaborator

also, I'm curious how y'all thought #203 would have worked / should interface with this PR

policy/README.md Outdated
| `name` | String | R | Name of cap item |
| `rule_type` | enum | R | Type of policy (see [“rule types”](#rule-types))|
| `rule_units` | enum | O | Measured units of policy (see [“rule units”](#rule-units))|
| `geographies`| UUID[] | R | List of Geography UUIDs (non-overlapping) specifying the covered geography |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest making this a URL where a GeoJSON file can be retrieved, so that implementers have more flexibility about where/how they want to host their geometry, and then removing the /geographies/{id} endpoint from the spec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally get your point. However, we have a design goal of publishing immutable Policy and immutable Geography objects, so that any point in time in the past can be accurately reconstructed for adjudication of Policy, and our reference implementation enforces that. Pointers to external data sources open the door to security and cross-site issues. I could imagine relaxing this in a subsequent revision, after input from a variety of cities interested in using this Policy / Geography paradigm.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rf- See update to include flat-file format

policy/README.md Outdated
| `minimum` | integer | O | Minimum value, if applicable (default 0) |
| `maximum` | integer | O | Maximum value, if applicable (default unlimited) |
| `start_time` | time | O | Beginning time-of-day (hh:mm:ss) when the rule is in effect (default 00:00:00) |
| `end_time` | time | O | Ending time-of-day (hh:mm:ss) when the rule is in effect (default 23:59:59) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth being more explicit that this is a string, since "time" isn't a defined type in MDS. Also this says "hh:mm:ss" but the example below is HH:MM.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

policy/README.md Outdated

### Order of Operations

Rules are ordered most-specific to most-general. E.g. an “earlier” cap rule would take precedence over a “later” cap rule. The internal mechanics of ordering are up to the Policy editing and hosting software.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the intention is just to say that the API implementation is responsible for deciding (presumably with input from a user at the agency) what order the rules should be in. I feel like the last sentence could probably just be removed though.

policy/README.md Outdated
| `rule_type` | enum | R | Type of policy (see [“rule types”](#rule-types))|
| `rule_units` | enum | O | Measured units of policy (see [“rule units”](#rule-units))|
| `geographies`| UUID[] | R | List of Geography UUIDs (non-overlapping) specifying the covered geography |
| `statuses` | Status[] | R | Vehicle `status` to which this rule applies. See [MDS Agency state diagram](https://github.com/CityOfLosAngeles/mobility-data-specification/blob/dev/agency/README.md#vehicle-events). |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still trying to get my head around the implications of this model for expressing rules. It seems well-suited to some use cases, but it seems like it might be problematic to not be able to distinguish between different events that lead to the same status. For example, the agency may want to limit or prohibit provider deployments in a given area but not user dropoffs—is there a way to model that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've addressed this particular point in a soon-to-be-amended version of this PR. Good catch!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@marie-x marie-x changed the title add Policy API first draft Add Policy API draft Jun 19, 2019
@hunterowens hunterowens added this to the 0.4.0 milestone Jun 28, 2019
policy/README.md Outdated

Parameters: none

Note: Intentionally omitted `GET /geographies` until a compelling use-case can be identified.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a front-end perspective it would be useful to be able to retrieve a number of geographies in a single request. This would facilitate, e.g. showing multiple the geographies in a map view quickly.

@marie-x
Copy link
Collaborator Author

marie-x commented Jul 15, 2019

Updated extensively. Looking for re-review. @hunterowens @rf-

@marie-x marie-x mentioned this pull request Aug 8, 2019
@evansiroky
Copy link
Contributor

I could see this being useful in a trip planning context. I've been working on improving OpenTripPlanner for the Portland, OR area where we have these manual files that are consumed that represent areas where travel with eScooters is banned and where parking eScooters is banned. It'd be great to have an actual API endpoint to fetch this data from cities either via this proposal or some other kind of GBFS-for-cities kinda thing.

For my two use cases, I guess an agency could model the banned parking area by creating a rule that applies to trip_end vehicle statuses and then perhaps model travel not allowed in an area by specifying a maximum value of 0 for a speed rule.

Anywho, I'm kind of just commenting here to follow along and see where the conversation goes for this topic.


##### Policy Design Approach

The Venice Special Operations Zone Policy consists of two rules, first, a rule which contains geographies representing the 'valid' `provider_drop_off` zones, and a second rule which has the overarching Venice geography. During the evaluation of the policy, a set of vehicles will be provided, we'll refer to this set as `V`. The first rule will match all vehicles which have been `provider_drop_off`'d within one of the given geographies, let's call this group of vehicles `v_1`. When evaluating the second rule, the vehicles which will be considered in the evaluation will be a subset `V \ v_1`. At this point, we are considering a subset which cannot have a vehicle in a valid drop off zone for this policy; and because of this, all vehicles that match with the second rule will be considered in violation of the policy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This explanation of the above rules doesn't make sense to me and it's especially confusing since the JSON of each rule seems essentially identical. Why wouldn't the geography in the 2nd rule just be listed among those in the first rule? And this explanation makes me wonder if somehow the order of the rules are important and should be combined together to produce some kind of hybrid rule.

Copy link
Collaborator Author

@marie-x marie-x Aug 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule order is important (per the spec). Each rule is applied in order, and if there's a match, generally further evaluation ceases.

In this example, the JSON is similar because it applies to the same types of vehicles and operations (provider_drop_off), but different because some of the specified areas are permitted and others aren't.

We are working on expanding the description (with ample diagrams) of how Policy objects and Rule lists are evaluated to help explain more clearly. Also I'd be happy to do a videoconference to walk though any aspects of this in the interests of making this as robust as possible.

We have a prototype running with a significant variety of Policy objects running for LADOT. This includes cap counting, no-fly zones, drop-off zones, speed limits, and others.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal of the Policy schema and its corresponding Compliance engine is to express as many different Policy concepts as possible, with a bare minimum of abstractions and exceptions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't see that section about how the order of the rules is important. My bad.

However, it's still not clear how to determine which areas are permitted and which ones aren't because it appears that the only data available in the geographies/{id} endpoint is the id of the geography.

policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated
| `geographies` | UUID[] | R | List of Geography UUIDs (non-overlapping) specifying the covered geography |
| `statuses` | { Status: Vehicle Event[] } | R | Vehicle `statuses` to which this rule applies. Optionally, you may provide specific `event_type`'s for the rule to apply to as a subset of a given status, providing an empty list or null defaults to "all". See [MDS Agency state diagram](https://github.com/CityOfLosAngeles/mobility-data-specification/blob/dev/agency/README.md#vehicle-events). |
| `vehicle_types` | VehicleType[] | O | Applicable vehicle categories, default “all”. See MDS shared data types document. (link forthcoming) |
| `minimum` | integer | O | Minimum value, if applicable (default 0) |
Copy link

@macsj200 macsj200 Sep 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not applicable for user rules, but may be necessary for others. Could we be more specific than R/O?

Also some clarity about min, max, both, either, or neither would be helpful.

policy/README.md Outdated

### Order of Operations

Rules are ordered most-specific to most-general. E.g. an “earlier” cap rule would take precedence over a “later” cap rule. The internal mechanics of ordering are up to the Policy editing and hosting software.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does the example relate to the explanation?

Specificity is distinctive from temporal ordering.

policy/README.md Outdated

#### Rule Ordering

Rules, being in a list, are implicitly ordered according to the JSON Specification. Rules are a very specific form of pattern matching; you specify the conditions for which a given rule is 'met', and a vehicle (or series of vehicles) may match with that specific rule. If a vehicle is matched with a rule, then it _will not_ be considered in the subsequent evaluation of rules within a given policy. This allows for expressing complex policies, such as a layer of 'valid' geographies in an earlier rule, with overarching 'invalid' geographies in later rules: see [LADOT Venice Beach Special Operations Example](./Examples.md#venice-beach-spec-ops)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Busted link

policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated

Returns: List of policy objects effective during the timespan described by greater than or equal to `start_time` and less than or equal to `end_time`

Policies will be returned in order of effective date (see Policy Schema, below), with pagination as in Agency or Provider.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ascending or descending? I would suggest most recent first, sorted on effective date.

@antrim
Copy link

antrim commented Sep 13, 2019

Note this GBFS pull request regarding adding geofencing
MobilityData/gbfs#92 (comment).

GBFS is seeking to align semantics with MDS. We'll add notes on this MDS proposal to our discussion and comparison of open proposals for geofencing.

Copy link
Contributor

@jfh01 jfh01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposed changes to make it easier for cities to publish simple policies as a static file at /policies, rather than as an interactive API end point.

policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated Show resolved Hide resolved
policy/README.md Outdated Show resolved Hide resolved
@marie-x
Copy link
Collaborator Author

marie-x commented Oct 2, 2019

Added flat-file format @hunterowens @jfh01 @rf- @thekaveman @antrim @evansiroky

policy/README.md Outdated

Rules, being in a list, are implicitly ordered according to the JSON Specification. Rules are a very specific form of pattern matching; you specify the conditions for which a given rule is 'met', and a vehicle (or series of vehicles) may match with that specific rule. If a vehicle is matched with a rule, then it _will not_ be considered in the subsequent evaluation of rules within a given policy. This allows for expressing complex policies, such as a layer of 'valid' geographies in an earlier rule, with overarching 'invalid' geographies in later rules: see [LADOT Venice Beach Special Operations Example](./Examples.md#venice-beach-spec-ops)

##### Evaluation Pseudocode
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this.

Copy link
Contributor

@rf- rf- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is generally looking pretty good to me. One question I still have is whether it's worth including a way to specify encouraged behaviors like parking within a specific zone. A numeric minimum doesn't seem like the right tool for expressing that policy.

policy/README.md Outdated

An Agency may wish to provide dynamic or global rules, e.g. "Within 300 yards of the stadium, 1000 total extra scooters may be deployed, across all Provider(s)." In this case, compliance is not computable from the information available to a single Provider. The Agency would provide a specified endpoint to get the current count of vehicles in the service-area, so that individual Providers could decide whether adding some number to those present can be done.

There are potential complexities that are as-yet unaddressed, such as the latency between a Provider deciding to enter such an area, and the number of vehicles in the area when the scooters arrive. As this specification is Alpha, feedback and refinements are welcome.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that this PR is close to being merged, what's the plan for aspects like this that are called out as not being fully baked yet?

policy/README.md Outdated

Certain policies could be fully dynamic, e.g. caps could be raised and lowered via algorithm on a day-to-day or even hour-to-hour basis. No-fly-zones could be created in quasi-real-time in response to emergencies or road-closures.

Dynamic caps can also be implemented by replacing the “maximum” integer with a URL to a source for dynamic data. This could be for provider-specific caps that go up and down, or for global caps e.g. “total 500 scooters at the coliseum”. Dynamic data sources would be required to have historical data so that validating prior information, and downloaded dynamic data would have a time-to-live.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest removing this whole section before merge. This is a spec for the API—it doesn't really seem necessary to list various ways it could be implemented.

Also, it seems like there's no provision in the spec right now for historical queries against the dynamic cap data. Is that something you're thinking about adding still?

policy/README.md Outdated

## Compliance

A Compliance API will be described in a separate MDS specification. In brief, it will take as inputs the a snapshot of the MDS status at a particular time, the MDS geography data, and these MDS Policy objects and emit Compliance JSON measurements. MDS status can be generated from either Provider or Agency data. This work is in draft form but is closely informed by this Policy specification.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also seems like something that would make sense to take out before merge. I wonder if it would make sense to think about some kind of light RFC process for future proposals, since information like this is valuable for people who are assessing the proposal but doesn't seem like it really belongs in the spec itself.

policy/README.md Outdated

#### Rule Ordering

Rules, being in a list, are implicitly ordered according to the JSON Specification. Rules are a very specific form of pattern matching; you specify the conditions for which a given rule is 'met', and a vehicle (or series of vehicles) may match with that specific rule. If a vehicle is matched with a rule, then it _will not_ be considered in the subsequent evaluation of rules within a given policy. This allows for expressing complex policies, such as a layer of 'valid' geographies in an earlier rule, with overarching 'invalid' geographies in later rules: see [LADOT Venice Beach Special Operations Example](./Examples.md#venice-beach-spec-ops)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This describes how rules are prioritized within a given policy, but what happens when rules belonging to different policies collide with each other? It doesn't seem like there's a way for the server to control the resolution of such conflicts since policies are returned in time order instead of priority order.

@hunterowens hunterowens mentioned this pull request Oct 16, 2019
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants