How opening status is determined
This is the operational contract behind every result. It separates a current official update from a published timetable, applies last-admission cutoffs, and never turns a failed network check into a live-open claim.
1. Public status contract
| Status | What the engine must know |
|---|---|
| 🟢 OPEN NOW | A current official operational source explicitly reports service, within today’s operating window. |
| 🟢 SCHEDULED OPEN | A still-valid official timetable says visitors should be admitted now; this is not presented as a live feed. |
| 🟡 LIMITED | Access is conditional, partial, booked, restoration-limited, weather-dependent, or based on a timetable while a live recheck is delayed. |
| 🔴 CLOSED | The official source reports closure, a dated exception closes it, or Romania-local time is outside the published admission window. |
| ⚪ CHECK OFFICIAL | No current claim can be supported for this date. The result links directly to the authoritative source. |
2. Calculation order
- An active, expiring operator override wins.
- A same-day official live update may produce OPEN NOW, LIMITED, or CLOSED.
- A confirmed official schedule is evaluated in
Europe/Bucharest, including seasonal ranges, weekday rules, split hours, dated exceptions, and validity dates. - Admission cutoffs—not building closing times—end an open claim where the source publishes both.
- If a live recheck is late, a still-valid conditional timetable degrades to LIMITED. A stable timetable remains explicitly SCHEDULED OPEN.
- If the timetable does not cover the date, the engine returns CHECK OFFICIAL instead of guessing.
3. Verified source registry
Every attraction has a dedicated adapter entry and an HTTPS host allowlist. Parsers require attraction-specific names, dates, times, or operational phrases; a generic page-load success is not enough.
| Attraction | Actual mode | Refresh | Schedule coverage | Official source |
|---|---|---|---|---|
| Bran Castle | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Bran Castle ↗ |
| Râșnov Citadel | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Râșnov Citadel ↗ |
| Tâmpa Cable Car | Current official operational board + schedule fallback | live | Seasonal · reviewed 2026-08-21 | Ana Teleferic / Discover Poiana ↗ |
| Seven Ladders Canyon | Official schedule parser + Romania-local calculation | normal | Seasonal · reviewed 2026-08-21 | Seven Ladders Canyon ↗ |
| Libearty Bear Sanctuary | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | AMP Libearty ↗ |
| Black Church Brașov | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Biserica Neagră ↗ |
| Peleș Castle | Official notice/schedule parser + Romania-local calculation | normal | open start → 2026-12-31 | Peleș National Museum ↗ |
| Pelișor Castle | Official notice/schedule parser + Romania-local calculation | normal | open start → 2026-12-31 | Peleș National Museum ↗ |
| Sinaia Gondola & Cable Cars | Current official operational board + schedule fallback | live | Seasonal · reviewed 2026-08-21 | Transport Urban Sinaia ↗ |
| Transfăgărășan | Official notice/schedule parser + Romania-local calculation | normal | 2026-06-12 → 2026-10-15 | CNAIR Dispecerat ↗ |
| Bâlea Cable Car | Official schedule parser + Romania-local calculation | cable | Seasonal · reviewed 2026-08-21 | Bâlea Cable Car ↗ |
| ASTRA Museum Sibiu | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | ASTRA Museum ↗ |
| Biertan Fortified Church | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Visit Sibiu County ↗ |
| Viscri Fortified Church | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Viscri Fortified Church ↗ |
| Sighișoara Clock Tower / History Museum | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Visit Mureș ↗ |
| Salina Turda | Official schedule parser + Romania-local calculation | daily | Seasonal · reviewed 2026-08-21 | Salina Turda ↗ |
| Corvin Castle | Official notice/schedule parser + Romania-local calculation | normal | 2026-04-01 → 2026-09-30 | Corvin Castle Museum ↗ |
| Sarmizegetusa Regia | Official notice/schedule parser + Romania-local calculation | normal | open start → 2026-12-31 | Museum of Dacian and Roman Civilisation ↗ |
| Poiana Brașov Lift System | Current official operational board + schedule fallback | live | Seasonal · reviewed 2026-08-21 | Ana Teleferic / Discover Poiana ↗ |
| Transalpina | Official notice/schedule parser + Romania-local calculation | normal | 2026-05-29 → 2026-08-31 | CNAIR Dispecerat ↗ |
4. Accuracy corrections in this revision
- Bran Castle uses the current official last-entry times: 18:00 or 19:00 by season. Revision 9 removed the superseded 19:30 August cutoff.
- Black Church open claims now stop 20 minutes before building close, matching its published last-entrance rule.
- Peleș and Pelișor stop open claims at 16:00 and 16:15 respectively, while still displaying the 17:00 building closure.
- Salina Turda stops admission claims at 17:00; ASTRA uses the 19:45 last-ticket cutoff.
- Libearty displays the actual 09:45 and 11:15 guided departures, includes the booking requirement, and stops availability after the final public departure.
- Biertan now includes the 19:00 June–August close, daily lunch break, and winter Tuesday–Sunday schedule.
- Sighișoara now distinguishes winter weekday 09:00 opening from weekend 10:00 opening.
- Viscri’s current tower/restoration restrictions and Râșnov’s garden-only access produce LIMITED.
- The Poiana parser reads only operator status fields; it cannot mistake a site-footer timestamp for current lift data.
- Sinaia accepts the official named-date daily heading without requiring a numeric year and extracts today’s section times.
- Successful live-board checks now clear any older same-day-hours snapshot when the source does not publish replacement hours.
- Transfăgărășan and Transalpina use CNAIR Dispecerat’s current road inventory and published 2026 daytime windows as conditional schedules, not as perpetual live-road claims.
5. Refresh paths and frequency
| Group | Cadence | Targets |
|---|---|---|
| live | 15 minutes | Sinaia, Tâmpa, Poiana Brașov |
| cable | 30 minutes | Bâlea timetable and operating caveats |
| normal | 6 hours | Dynamic notices, castles, roads, and restoration schedules |
| daily | Daily | Stable museum, heritage, nature, and castle timetables |
Cloudflare scheduled events are the primary path. An eligible HTML request also starts every due group after the page response has had priority; a per-worker cooldown prevents visitor traffic from repeatedly starting the fallback. Each group claims its own D1 lease before fetching, so simultaneous requests cannot duplicate a run. Starting all due cadences removes the starvation bug where a frequently-due live group could prevent normal and daily checks from ever starting on a low-traffic deployment. A new configuration revision clears prior run summaries once, making every cadence immediately due after deployment. Every scheduled event also catches up any other due cadence, so this validation does not depend on visitor traffic. The admin can run any group immediately as well.
6. Durable state
D1 stores places, source configuration, same-day extracted hours, last attempt, last successful confirmation, parser health, repeated-failure count, status history, dated exceptions, admin login throttles, and refresh leases/run summaries. Configuration is revisioned: a new deployment upgrades existing rows in place while preserving manual overrides.
Production database errors are surfaced. The application no longer silently swaps in seed records after a D1 query failure.
7. Failure behavior
Each source attempt has a seven-second timeout, responses are capped at two megabytes, redirects are limited to four allowlisted HTTPS hops, and transient HTTP/network failures receive one bounded retry. Blocked hosts, unsafe redirects, bot challenges, missing exact fields, and unsupported wording record a failed attempt and its reason. They never advance last_confirmed_at. The display then uses a still-valid official schedule with the appropriate status, or asks the visitor to check the linked source when no schedule can support the date.
8. Operator controls
The protected console can run all source adapters on demand, inspect parser health and consecutive errors, set an expiring override, and edit the official URL, freshness policy, or validated schedule JSON. Automatic checks continue underneath a manual override.
9. Automated release gates
| Gate | What it proves |
|---|---|
| 20 adapter contracts | Every seeded attraction has a registered adapter whose required names, dates, times, and operational phrases parse successfully. |
| Schedule boundaries | Romania-local weekday/season selection, last-admission cutoffs, delayed-live degradation, and published validity horizons resolve safely. |
| Live parser fixtures | Sinaia’s dated update and Discover Poiana’s scoped installation states cannot be confused with unrelated page text. |
| Network safety | A transient error retries once; cross-host redirects and anti-bot challenges are rejected. |
| Scheduler fairness | One request attempts live, cable, normal, and daily groups instead of stopping after the first due cadence. |
| Production build + HTML | The deployable Worker builds, renders all 20 places, and exposes only the five documented public status labels. |
10. Audit snapshot · 21 August 2026
“Accurate” here is a testable contract: every attraction is mapped to its named official source; every parser must recognize attraction-specific evidence; schedule calculations stop at admission cutoffs; failures cannot create an open claim; and uncovered future dates return CHECK OFFICIAL. No crawler can guarantee that an external operator page is always online or that an operator has published a last-minute on-site decision, so the system surfaces those limits instead of manufacturing certainty.
11. Honest MVP boundaries
- Road results remain conditional: CNAIR Dispecerat supplies the current HTML inventory, while weather and on-site safety decisions can still change access without notice.
- Weather-dependent cable cars and canyon access remain LIMITED when only a timetable is available.
- Official pages protected by anti-bot challenges may force the schedule fallback even when visitors can open the page in a browser.
- Future schedules with a known publication horizon—such as Corvin after September 2026 and Transalpina after August 2026—must be reviewed when the operator publishes them.
- On-site staff and the linked source remain authoritative for same-day safety decisions.