fix!: define deterministic operating hours for Location service - #687
Open
igrigorik wants to merge 1 commit into
Open
fix!: define deterministic operating hours for Location service#687igrigorik wants to merge 1 commit into
igrigorik wants to merge 1 commit into
Conversation
The current Location PR introduces weekly and exceptional operating hours, but leaves several wire and evaluation semantics ambiguous. In particular, closures rely on an artificial midnight interval, `open_now` depends on an implicit server clock, exception date bounds are unclear, and the specification does not define timezone, overnight, DST, overlap, or precedence behavior. Close those gaps with a UCP-native schedule model informed by Schema.org's OpeningHoursSpecification: https://schema.org/OpeningHoursSpecification Schema.org is design input only. UCP owns the field names, values, and evaluation rules defined here. Make weekly intervals explicit and reusable: "hours": [ { "day": "tuesday", "opens": "09:00", "closes": "12:00" }, { "day": "tuesday", "opens": "13:00", "closes": "21:00" } ] Rename `open` and `close` to `opens` and `closes`, and define `day` as a stable UCP weekday identifier rather than localized display text. Multiple entries for one day represent split shifts, and an interval whose closing time is earlier than its opening time continues into the next local date. Refactor the shared time interval schema so `opens` and `closes` are an optional but inseparable pair. Weekly hours require both fields, while exception hours may omit both to represent a full closure. Reject the ambiguous `00:00` to `00:00` pair and reserve `00:00` to `23:59` as the full-local-day sentinel. Replace the previous exception shape: { "from": "2026-11-26", "through": "2026-11-27", "label": "Thanksgiving", "open": "00:00", "close": "00:00" } with inclusive local-date bounds and an actual closure representation: { "title": "Thanksgiving", "valid_from": "2026-11-26", "valid_through": "2026-11-26" } Rename `from`, `through`, and `label` to `valid_from`, `valid_through`, and `title`. Treat `title` as optional presentation metadata that does not affect schedule evaluation. Allow timed exceptions with paired `opens` and `closes`, including multiple entries with identical bounds for split shifts. Define every returned schedule in the Location's Business-owned IANA timezone. Require `timezone` whenever regular or exception hours are present, and keep the canonical schedule independent of the requesting Platform or Buyer's timezone. Specify deterministic evaluation: - convert an exact instant into each Location's local date, weekday, and time - use half-open timed intervals, except for the reserved full-day sentinel - let overnight intervals carry into the following local date - replace regular hours with exception hours at local midnight - treat omitted weekdays as having no interval starting that day - treat absent schedules as unknown rather than closed - evaluate DST gaps and folds pointwise without shifting nonexistent times - reject equal time pairs and intersecting non-identical exception ranges as Business conformance errors where JSON Schema cannot express the constraint Remove the redundant `open_now` filter. It makes results depend on an implicit processing clock and creates undefined precedence when combined with `open_at`. Require one caller-supplied RFC 3339 instant instead: "filters": { "hours": { "open_at": "2026-05-18T17:00:00Z" } } Require `open_at` to include `Z` or a numeric offset. The offset identifies the instant only; the Business still evaluates that instant using each candidate Location's authoritative IANA timezone. Keep the nested hours filter open so extensions can add qualifiers without changing the standard predicate. Move complete Search and Lookup examples into the transport-neutral capability documents. Cover hours with serviceability and amenities, inventory with distance, split shifts, full closures, and partial Lookup success there. Reduce REST and MCP examples to equivalent binding envelopes that link to the same canonical payload examples. This keeps both transports on equal footing, avoids duplicating domain semantics, and prevents one binding's examples from becoming more complete or authoritative than the other. Preserve MCP's required `meta["ucp-agent"].profile` contract while separating protocol metadata from the Location request. This is a breaking correction to the Location PR's draft wire shape: - `open` becomes `opens` - `close` becomes `closes` - `from` becomes `valid_from` - `through` becomes `valid_through` - `label` becomes `title` - `open_now` is removed - full closures omit both time fields instead of using `00:00` to `00:00`
17 tasks
karangoel16
reviewed
Aug 5, 2026
| "exception_hours": [ | ||
| { | ||
| "title": "Thanksgiving", | ||
| "valid_from": "2026-11-26", |
Contributor
There was a problem hiding this comment.
should we add some kind of description as well , with the title for the exception hours ?
"business might close early due to Thanksgiving or something like that " ,
at times description could be useful
| { | ||
| "ucp": { | ||
| "version": "{{ ucp_version }}", | ||
| "capabilities": { |
Contributor
There was a problem hiding this comment.
should we also add in expiry_at after this platform or agent should pull new info, this could help agent understand that the location info is stale and they need to pull new information ?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The current Location PR (#687) introduces weekly and exceptional operating hours,
but leaves several wire and evaluation semantics ambiguous. In particular,
closures rely on an artificial midnight interval,
open_nowdepends on animplicit server clock, exception date bounds are unclear, and the specification
does not define timezone, overnight, DST, overlap, or precedence behavior.
Close those gaps with a UCP-native schedule model informed by Schema.org's
OpeningHoursSpecification:
https://schema.org/OpeningHoursSpecification
Schema.org is design input only. UCP owns the field names, values, and
evaluation rules defined here.
Make weekly intervals explicit and reusable:
Rename
openandclosetoopensandcloses, and definedayas astable UCP weekday identifier rather than localized display text. Multiple
entries for one day represent split shifts, and an interval whose closing time
is earlier than its opening time continues into the next local date.
Refactor the shared time interval schema so
opensandclosesare anoptional but inseparable pair. Weekly hours require both fields, while
exception hours may omit both to represent a full closure. Reject the ambiguous
00:00to00:00pair and reserve00:00to23:59as the full-local-daysentinel.
Replace the previous exception shape:
with inclusive local-date bounds and an actual closure representation:
Rename
from,through, andlabeltovalid_from,valid_through, andtitle. Treattitleas optional presentation metadata that does not affectschedule evaluation. Allow timed exceptions with paired
opensandcloses,including multiple entries with identical bounds for split shifts.
Define every returned schedule in the Location's Business-owned IANA timezone.
Require
timezonewhenever regular or exception hours are present, and keepthe canonical schedule independent of the requesting Platform or Buyer's
timezone.
Specify deterministic evaluation:
Remove the redundant
open_nowfilter. It makes results depend on an implicitprocessing clock and creates undefined precedence when combined with
open_at. Require one caller-supplied RFC 3339 instant instead:Require
open_atto includeZor a numeric offset. The offset identifies theinstant only; the Business still evaluates that instant using each candidate
Location's authoritative IANA timezone. Keep the nested hours filter open so
extensions can add qualifiers without changing the standard predicate.
Move complete Search and Lookup examples into the transport-neutral capability
documents. Cover hours with serviceability and amenities, inventory with
distance, split shifts, full closures, and partial Lookup success there.
Reduce REST and MCP examples to equivalent binding envelopes that link to the
same canonical payload examples. This keeps both transports on equal footing,
avoids duplicating domain semantics, and prevents one binding's examples from
becoming more complete or authoritative than the other. Preserve MCP's
required
meta["ucp-agent"].profilecontract while separating protocolmetadata from the Location request.
This is a breaking correction to the Location PR's draft wire shape:
openbecomesopensclosebecomesclosesfrombecomesvalid_fromthroughbecomesvalid_throughlabelbecomestitleopen_nowis removed00:00to00:00