v0.6.0
[0.6.0] - 2026-07-30
Reparatur-Release. In 0.5.0 lieferten drei der sechs Tools nichts —
meteo_current für jede Station einen 404, meteo_forecast und
meteo_school_check gar keine Daten. Drei unabhängige Ursachen, zwei davon
Änderungen bei Datenquellen, eine ein Fehler im Server selbst. Alle drei sind
live gegen die echten APIs verifiziert.
Für Clients nicht breaking: Tool-Namen, Parameter und Rückgabetypen sind
unverändert. Einzig die Beschreibung von meteo_forecast wurde präzisiert
(siehe «Changed»), was tool-hashes.json ändert.
Behoben
-
Ortsnamen mit Zusatz waren gar nicht auflösbar
(#37). Die
Geocoding-API kennt nur einzelne Ortsnamen und liefert für
«Schulhaus Leutschenbach Zürich» nichts._geocode()schickte den vollen
String in beiden Versuchen — der «Fuzzy»-Retry liess nur die
Sprachrestriktion weg und kürzte die Anfrage nie. Damit scheiterten auch die
Beispiele, die die Tools selbst dokumentieren (meteo_forecast-Docstring und
dielocation-Beschreibung vonmeteo_school_check).Neu werden bei Misserfolg führende Tokens nach und nach weggelassen —
Schweizer Ortsangaben sind konventionellGattungswort… Ort Stadt, das
verallgemeinert also von spezifisch nach allgemein und endet bei der Stadt.
Zusätzlich wird jedes führende Token einzeln probiert, aber nur mit
Namensprüfung: «Leutschenbach» →Leutschenbachwird angenommen,
«Schulhaus» →Dübendorf / Schulhaus Wilverworfen. Ohne diese Prüfung
bekäme eine Zürcher Anfrage stillschweigend Wetter aus einer anderen
Gemeinde — schlimmer als der bisherige harte Fehler.Live verifiziert:
Anfrage Ergebnis Schulhaus Leutschenbach ZürichLeutschenbach, ZH (47.4175, 8.5648) Sportanlage Heerenschürli ZürichZurich, ZH (47.3667, 8.5500) Zürich/Bernunverändert exact, ein einziger Requestmatch_typekennt dafür neu"shortened"— Aufrufende sehen damit, dass die
Antwort allgemeiner ist als die Frage. Ein Volltreffer löst weiterhin genau
einen Request aus; gekürzt wird nur, wenn der volle String scheitert. -
meteo_forecastundmeteo_school_checklieferten gar nichts mehr
(#35). Open-Meteo hat
die provider-eigenen Pfade abgeschafft;/v1/meteoswissantwortet mit 404.
Modelle werden neu übermodels=auf/v1/forecastgewählt.Ein reiner URL-Tausch reicht nicht, denn keines der MeteoSwiss-Modelle
liefert, was die beiden Tools zusagen. Live gemessen für
meteoswiss_icon_seamless(ICON-CH1 + ICON-CH2):- Reichweite 5 Tage.
forecast_days=16liefert darüber hinaus nur
Nullwerte — das ist der ICON-CH2-Horizont, kein Parameterproblem.
meteo_forecastverspricht aber bis zu 16 Tage. - Kein UV-Index, auch nicht stündlich (0 von 72 Werten über 3 Tage).
Open-Meteo bezieht UV aus CAMS, nicht aus dem Modelloutput.
meteo_school_checkwarnt aber ab UV 6.
Der Server holt deshalb neu beide Modelle und mischt sie entlang der
Zeitachse: MeteoSwiss ICON gewinnt überall, wo es einen Wert hat,None
fällt aufbest_matchzurück. Dieselbe Regel erledigt die 5-Tage-Grenze und
die UV-Lücke. Gemischt wird bewusst über Zeitstempel statt Listenindizes —
der ICON-Block ist kürzer, und ein Indexversatz würde Werte still auf den
falschen Tag schieben.Die Herkunft steht in jeder Antwort, statt im Ungefähren zu bleiben: die
Markdown-Fussnote und die JSON-Feldermodell/modell_detailsweisen aus,
welche Tage aus MeteoSwiss ICON stammen, ab wannbest_matchübernimmt und
dass UV durchgehend von dort kommt. Fällt der ICON-Request aus, trägt
best_matchdie Antwort allein — und sagt das ebenfalls, statt einen
Totalausfall zu produzieren.Kein Test hätte das finden können: die Unit-Tests deckten ausschliesslich
Geocoding-Fehlerpfade ab, der erfolgreiche Prognosepfad war komplett
ungetestet. Neu 11 Tests für Merge-Logik (inklusive Zeitachsen-Versatz),
Provenance-Label, den vollen Hybrid-Pfad in Markdown und JSON, den
ICON-Ausfall und die UV-Herkunft inmeteo_school_check. - Reichweite 5 Tage.
Changed
-
meteo_forecast-Beschreibung präzisiert — sie nannte pauschal
«MeteoSwiss ICON-CH1/CH2-EPS» und verschwieg damit, dass Tage jenseits von 5
und der UV-Index ausbest_matchstammen.tool-hashes.jsonentsprechend neu
generiert (Rug-Pull-Signal, SEC-022). Für Clients nicht breaking: Parameter
und Rückgabetyp sind unverändert,daysakzeptiert weiterhin 1–16. -
meteo_currentlieferte für jede Station 404
(#33). Die STAC-Item-ID
ist der nackte Stationscode in Kleinschreibung (…/items/klo); der Server
stellte ihm die Collection-ID voran (…/items/ch.meteoschweiz.ogd-smn-klo).
Live gegen die BGDI-API verifiziert:/items/klo→ 200, die Präfix-Variante
und die Grossschreibung → je 404. Die URL wurde an drei Stellen dupliziert
(Fetch, Fehlermeldung, JSON-Provenance) — jetzt einmal in
_smn_stac_item_url().Beim Beheben kamen drei weitere Fehler zum Vorschein, die der 404 verdeckt
hatte — sie hätten nach dem URL-Fix plausibel aussehende, aber falsche Daten
geliefert:- Die Asset-Auswahl konnte nie greifen. Gesucht wurde nach
/now/im
Pfad, doch die Granularität steckt im Dateinamen
(ogd-smn_klo_t_now.csv); ein Verzeichnis/now/existiert nicht. Der
Fallback nahm daraufhin das erste CSV im Item —d_historical, also
Tageswerte ab 1980, ausgegeben als «aktuelle Beobachtung». Neu wird gezielt
_t_nowgewählt, ersatzweise_t_recent; gibt es beides nicht, ist das ein
Fehler statt eines stillen Griffs ins Archiv. - Der Zeitstempel war immer
–. Gelesen wurdetime/Date/datum, die
OGD-CSV führt aberreference_timestamp. - Die Zeile «Luftdruck (reduziert auf Meeresniveau)» blieb immer leer.
prestah0gibt es in der CSV nicht; der QNH-Wert heisstpp0qnhs0.
- Die Asset-Auswahl konnte nie greifen. Gesucht wurde nach
Tests
Alle drei Fehler oben hatten einen Test, der sie hätte finden müssen, aber so
formuliert war, dass auch der Fehlerfall ihn erfüllte. Das ist das eigentliche
Thema dieses Releases:
-
meteo_current(live): prüfte"KLO" in result or "Zürich" in result—
beides steht auch in der Fallback-Fehlermeldung. Der Test lief also durch
einen Totalausfall hindurch grün. Verlangt jetzt echte Messwerte. -
meteo_forecast/meteo_school_check: der erfolgreiche Prognosepfad war
komplett ungetestet, abgedeckt waren nur Geocoding-Fehlerpfade. Zudem mockten
die Tests die eigene Endpoint-Konstante — sie konnten das Abschalten upstream
gar nicht bemerken. -
_geocode(live): prüfte nur einen Koordinatenbereich (8.4–8.7), den
Dübendorf mit 8.62 ebenfalls erfüllt — der Fehlgriff auf eine andere Gemeinde
wäre durchgewinkt worden. Verlangt jetzt den Ortsnamen im Ergebnis. -
Cache-Isolation zwischen Tests. Der TTL-Cache ist modul-global und
überlebte den einzelnen Test. Ein Test sah dadurch Einträge eines früheren,
umging sein eigenes respx-Mock und schlug je nach Ausführungsreihenfolge fehl
— oder bestand aus dem falschen Grund. Eine autouse-Fixture räumt jetzt vor
und nach jedem Test auf.