| name | hours-rules-authoring |
| description | Write or edit an hours-rules JSON file โ the format that encodes Israeli opening hours including Shabbat- and chag-relative rules, for resolution by israel_hours.py. Covers the schema, selector precedence, anchor expressions, hybrid earliest_of/latest_of closings, and how to translate Hebrew hours phrasing into rules. Use after collecting stated hours from Google or easy.co.il. |
Authoring an hours-rules file
An hours-rules file encodes what a business's hours mean, so they can be
evaluated against any date. Schema: ${CLAUDE_PLUGIN_ROOT}/schema/hours-rules.schema.json.
Worked example: ${CLAUDE_PLUGIN_ROOT}/examples/makolet-jerusalem.json.
Shape
{
"name": "Business name",
"location": { "city": "jerusalem" },
"source": "google + easy.co.il",
"confidence": "friday close is derived, not stated",
"stated_hours_verbatim": { "he": "...", "en": "..." },
"weekly": { "sun": [ ... ], "mon": [ ... ] },
"day_types": { "erev_shabbat": [ ... ], "shabbat": [ ... ] },
"dates": [ { "date": "2026-09-11", "windows": [ ... ] } ],
"default": [ ]
}
Always fill stated_hours_verbatim with the merchant's original wording,
Hebrew included. It is the audit trail for every derived time, and it lets a
later session re-derive the rules without refetching.
Selector precedence
Most specific wins, first match only:
dates[] โ an exact date
day_types{} โ the day's classification
weekly{} โ sunโฆsat
default[]
A day has exactly one day_type, resolved by israel_hours.py itself. A Friday
before a chag classifies as erev_yom_tov, not erev_shabbat. A Saturday that
is also yom tov classifies as shabbat_yom_tov. So define erev_yom_tov and
shabbat_yom_tov explicitly if the business treats them differently โ they will
not fall through to erev_shabbat / shabbat.
Windows
{ "open": <endpoint>, "close": <endpoint>, "label": "human explanation" }
An empty window list means closed all day. If close is earlier than
open, the window is taken to run past midnight and is flagged
crosses_midnight.
Endpoints
| Form | Meaning |
|---|
"14:30" | clock time on that date, in the location's own UTC offset |
{"anchor": "havdalah", "offset_min": 60} | 60 min after havdalah |
{"anchor": "candle_lighting", "offset_min": -90} | 90 min before candle lighting |
{"anchor": "sunset", "offset_min": -30, "anchor_date": "2026-09-13"} | anchor taken from a specific other date |
{"earliest_of": [ ... ]} | whichever resolves earliest |
{"latest_of": [ ... ]} | whichever resolves latest |
Anchors: sunrise, sunset, chatzot, tzeit (every day);
candle_lighting, havdalah (only on days they occur).
A window anchored to candle_lighting or havdalah on a day that has neither
is skipped, not an error โ recorded in notes as "window not applicable".
That is how a motzei-chag reopening correctly does nothing on the first day of
a two-day chag.
Use earliest_of for Friday closings
This is the single most important modelling point, and getting it wrong is the
most common source of bad estimates.
A bare offset before candle lighting does not extrapolate across the year.
Candle lighting in Jerusalem ranges from ~16:00 in midwinter to ~19:15 in
midsummer. A shop observed closing at 14:30 on a January Friday is not
closing at 17:45 in July โ staff still leave mid-afternoon. In winter the
constraint is Shabbat; in summer it is the working day.
Model it as a hybrid:
"close": { "earliest_of": ["15:00", {"anchor": "candle_lighting", "offset_min": -90}] }
Verified behaviour, Jerusalem: Friday 2026-01-02 โ closes 14:37 (candle
lighting 16:07 drives it). Friday 2026-07-31 โ closes 15:00 (the clock cap
drives it).
Only use a bare offset when the source explicitly states one
("ืขื ืฉืขื ืืคื ื ืื ืืกืช ืืฉืืช").
Translating Hebrew phrasing
| Phrase | Rule |
|---|
ืขื ืื ืืกืช ืืฉืืช | {"anchor": "candle_lighting", "offset_min": 0} |
ืฉืขื ืืคื ื ืื ืืกืช ืืฉืืช | {"anchor": "candle_lighting", "offset_min": -60} |
ืืฆื ืฉืขื ืืคื ื ืื ืืกืช ืืฉืืช | offset_min: -30 |
ืฉืขื ืืืืจ ืฆืืช ืืฉืืช | {"anchor": "havdalah", "offset_min": 60} |
ืืื ืืืืฆ"ืฉ | {"anchor": "havdalah", "offset_min": 15} โ allow a short grace |
ืกืืืจ ืืฉืืช | "shabbat": [] |
ืคืชืื ืืฉืืช | give shabbat normal clock windows |
ืขืจื ืื ืืื ืขืจื ืฉืืช | copy the erev_shabbat windows into erev_yom_tov |
When the source gives only a clock time
Google gives you "Friday 08:00โ15:00" and nothing else. You do not know whether
15:00 is a fixed time or a Shabbat-derived one. Do this:
- Compute candle lighting for the Friday the listing plausibly reflects.
- If 15:00 sits at a round offset before it (60/90/120 min), a derived rule is
likely โ model it as
earliest_of with the clock time as the cap.
- Otherwise treat it as a fixed clock time.
- Either way, record the uncertainty in
confidence and tell the user the
Friday time is an inference.
Do not invent precision. A rules file that says "we don't know the Friday rule"
in confidence is more useful than one that quietly guesses.