check_run:
  id: OPS-001
  status: partial
  evidence_collected: 7
  evidence_required: 4
  findings:
    - "Marker registered and CI excludes live tests: pyproject.toml:64-66 ([tool.pytest.ini_options] markers = ['live: live API tests (skipped in CI by default)']) and .github/workflows/ci.yml:26-28 runs `pytest tests/ -m \"not live\"` across a Python 3.11/3.12/3.13 matrix."
    - "Large mocked unit suite: 22 test modules, ~464 test functions for 23 tools (tests/test_oereb.py 61, test_stac.py 48, test_height.py 47, test_rest_api.py 40, test_geocoding.py 38, test_places.py 28, test_openplz.py 27, test_wmts.py 26, test_coords.py 24, test_geodata.py 23, plus regression suites test_responses.py, test_logging.py, test_egress_allowlist.py, test_input_validation.py, test_shared_client.py, test_http_app.py, test_retry.py, test_context.py). Well above the '5 unit tests per tool' bar."
    - "respx HTTP mocking is used where the transport matters: tests/test_places.py:12,96,109,117,128,134,142 (all zoning/municipality/layer_info paths), tests/test_coords.py, tests/test_openplz.py, tests/test_lv95_input.py, tests/test_retry.py. Other modules mock at the function boundary with monkeypatch instead (e.g. tests/test_responses.py:37,49,57)."
    - "The three new tools have proper three-way unit coverage: happy path (tests/test_places.py:96-107), error path (tests/test_places.py:142-147, upstream 500 -> is_error with body suppressed), and edge cases (tests/test_places.py:134-140 empty result as soft miss; :149-151 missing coordinates -> ValidationError; :172-184 historical-only municipality record -> soft miss)."
    - "Live tests exist for the new tools and are correctly marked: tests/test_places.py:282-299 (@pytest.mark.live class TestPlacesLive covering zoning_at, municipality_at, layer_info against Zurich LV95 2683531/1247914) and tests/test_coords.py:205-238 (@pytest.mark.live TestReframeLive with a WGS84->LV95->WGS84 roundtrip and a drift guard asserting the local polynomial stays within 1 m of REFRAME)."
    - "GAP — no nightly or manual live-test workflow: .github/workflows/ contains only ci.yml, publish.yml and security.yml. None has a `schedule:` trigger or a `pytest -m live` step, so the 17 live tests are never executed by automation and schema drift in the upstream APIs would go undetected until someone runs them by hand. This gap was already recorded in the 2026-05-29 run and is unchanged."
    - "GAP — 5 of 23 tools have no live test: swisstopo_find_features and swisstopo_get_feature (tests/test_rest_api.py:361-378 covers only search_layers and identify_features), swisstopo_get_collection (tests/test_stac.py:386 covers only search_geodata), swisstopo_get_egrid and swisstopo_get_oereb_extract (tests/test_oereb.py: 0 live markers despite 61 tests). tests/test_wmts.py also has 0 live markers, but swisstopo_map_url is a pure URL builder with no network call, so that is correct by design."
  gaps:
    - "No separate nightly/manual live-test workflow (`schedule:` + `workflow_dispatch` running `pytest -m live`) — the criterion is unmet and the live suite is effectively dead automation."
    - "Live-test coverage is 18/23 tools; find_features, get_feature, get_collection, get_egrid and get_oereb_extract have none. The two OEREB tools are the most exposed, since they hit cantonal endpoints (oereb.geo.zh.ch, www.oereb2.apps.be.ch) whose formats the README itself flags as inconsistent (README.md:404)."
    - "tests/test_unit.py and tests/test_live.py as named files do not exist; the repo splits per source module and separates live tests by marker within each file. Functionally equivalent to the check's intent, noted only for layout comparison."
  evaluator_notes: |
    PARTIAL. Five of the eight pass criteria are clearly met — marker
    registered, CI runs `-m "not live"`, respx mocking present, well over five
    unit tests per tool, and no credentials involved (all endpoints are
    key-less, so the production-key criterion is vacuously satisfied).

    Two criteria are unmet and both are substantive rather than cosmetic:

    1. 'Separater nightly/manueller Live-Test-Workflow' — absent. This matters
       more after this release than before it, because the tool surface just
       grew onto two upstream layers whose attribute schemas the handlers depend
       on by name (rest_api.py:412-422 reads ch_bez_d/ch_bez_f/ch_code_hn/
       bfs_no/kt_kz; rest_api.py:443-456 reads is_current_jahr/gemname/gde_nr/
       kanton). The unit fixtures pin those names, so a rename upstream would
       leave CI green and every zoning result silently null. The live tests that
       would catch it exist but nothing runs them.

    2. Live coverage is 18/23 tools. The OEREB pair is the notable hole.

    The layout deviation (no literal test_unit.py/test_live.py) is not counted
    against the status — the marker-based separation the check actually depends
    on is implemented correctly.
