Runbook: correcting what a zone opening refused
Opening a zone runs a completeness gate: a bookable accommodation that no resolver can name is not imported (ADR-049 §3). This runbook covers the loop that lets an operator fix the refusals worth fixing — reading the report, writing the corrections, importing them — and the one limitation the design accepts.
It is deliberately narrow. Opening a zone is zone-opening.md (and the
routing graph it depends on, valhalla-routing-graph.md); this file
is only about the corrections. Like the opening itself, it runs against a local or recette
stack (make provision-override uses the dev compose project).
1. Read the report
Every opening and re-opening writes, per zone:
.docker/osm/data/zones/<zone>/rejected.tsv # OSM refusals
.docker/osm/data/zones/<zone>/rejected-datatourisme.tsv # flux refusals
Tab-separated with a header:
| Column | Meaning |
|---|---|
source |
osm or datatourisme |
source_id |
N/123 for OSM (type + id), the flux id otherwise |
category |
hotel, camp_site, … |
lat, lon |
where it is |
commune |
resolved offline from the imported boundaries |
reason |
why the gate refused it |
cycle_route_m |
metres to the nearest signed cycle route |
tags |
the raw OSM tags, for context |
The file is sorted by cycle_route_m, nearest first, and that is the point. You work
the thirty refusals that border a véloroute, not the three thousand lost in open country.
The human effort is bounded by the ordering, not by your discipline — stop whenever the
distances stop being interesting.
The console also prints the counts: names resolved, how many came from the curated flux, entries refused, and the refusals broken down by motive.
2. Read the size of the file as a signal about the code
A long rejected.tsv is not a backlog of manual work. It means the resolvers are weak.
The first of them — projecting tags the database already holds — should absorb most of the
volume, so a long file says it did not. The command says so itself when refusals outnumber
resolutions.
Before working through a large file, check whether the fix belongs in
provisioner/src/NameResolver.php instead. Manual corrections do not scale and are lost on
a rebuild (§5); a resolver improvement is retroactive — bump NameResolver::VERSION and the
next opening retries every entry that version refused, and only those.
3. Write the corrections
Copy the report, keep the rows you want to fix, and give each one a name:
cd .docker/osm/data/zones/bretagne
cp rejected.tsv override.tsv
# edit override.tsv: keep the useful rows, fill in `name`
The required columns are the first six, in order, and the header row is skipped so you can edit the report in place:
source source_id category lat lon name
osm N/1234567 camp_site 48.512345 -2.765432 Camping municipal du Moulin
Three optional columns may follow, in this order: website, description,
opening_hours. Leave them empty or omit them entirely.
A malformed file is refused whole, naming the offending line. The parse completes before any statement runs and the insert is one transaction, so there is no such thing as a half-applied override.
4. Import them
make provision-override bretagne
# or, for a file elsewhere:
make provision-override bretagne /data/zones/bretagne/override.tsv
What happens, and what does not:
- The rows are inserted into
osm.accommodations/tourism.accommodationswith the zone that corrected them andON CONFLICT DO NOTHING. An override adds what the gate refused; it never rewrites a row already imported (ADR-049 §5). If you need to change a value that is already live, this file cannot do it — deliberately, because the alternative is a mechanism that can silently overwrite the sources. - Re-opening the zone will not re-analyse them: the enrichment cache holds a negative entry
for each, and the promotion's identity anti-join sees the row present. They also stop
appearing in
rejected.tsv, so you are not asked to fix them twice.
There is no endpoint, no authentication, no interface and no versioning. It is data, it does not belong in git, and it does not justify a table.
5. The limitation, stated rather than discovered
Nothing stores your file. The corrections live only in the live tables, so a database
rebuilt from scratch loses every one whose override.tsv you did not keep.
That is the accepted price of "no table, no versioning". Two consequences:
- Keep the file, somewhere that survives the database. The command reminds you.
- Prefer a resolver fix whenever a correction generalises. A pattern fixed in
NameResolverapplies to every zone, past and future, and survives any rebuild; a hand correction applies to one row until someone drops the database.
6. Check nothing reached git
The report and override files live under .docker/osm/data/, which is gitignored in full
(.docker/osm/data/*). If you moved a file elsewhere in the tree, check before committing:
git status --short