{
  "run_id": "gridpin--gridpin-claude-haiku-5-5-1792779867077218910",
  "checker": {
    "claims": [
      {
        "claim": "The CLI lists the country sheets GridPin offers, including Serbia (rs).",
        "command": "<guest-path> --list",
        "evidence": "Serbia           32 MB  downloaded\nsheets directory: <guest-path>\n",
        "expected": "a list of countries that includes Serbia",
        "input": "gridpin-fetch --list",
        "kind": "claim",
        "outcome": "Real input produced the expected result: Serbia",
        "returncode": 0,
        "source": "Countries: `br` `de` `es` `fr` `it` `nl` `rs` (`gridpin-fetch --list`). For AI agents there is an",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      },
      {
        "claim": "The gridpin CLI forward-geocodes a French address against the France sheet and returns a house-level match.",
        "command": "<guest-path> query <guest-path> '1 rue de la Paix Paris' -k 3",
        "evidence": "Rue de la Paix\",\"housenumber\":\"1\",\"commune\":\"Paris 2e Arrondissement\",\"postcode\":\"75002\",\"flags\":[\"street_exact\",\"commune_prefix\",\"house_rep\"]}\n",
        "expected": "a house-precision candidate on Rue de la Paix",
        "input": "1 rue de la Paix Paris, against france.bin",
        "kind": "claim",
        "outcome": "Real input produced the expected result: Rue de la Paix",
        "returncode": 0,
        "source": "$ gridpin query france.bin \"1 rue de la Paix Paris\" -k 3",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      },
      {
        "claim": "After a sheet is downloaded, geocoding runs from the local file: the MCP server returns a house-level Serbian address match.",
        "command": "<guest-path> tools/call {\"tool\": \"geocode\", \"arguments\": {\"query\": \"Knez Mihailova 5, Beograd\", \"country\": \"rs\"}}",
        "evidence": "Kneza Mihaila\\\",\\n      \\\"housenumber\\\": \\\"5\\\",\\n      \\\"commune\\\": \\\"Stari Grad\\\",\\n      \\\"postcode\\\": \\\"\\\",\\n      \\\"confidence\\\": 0.9399999976158142,\\n      \\\"flags\\\": [\\n        \\\"street_exact\\\",\\n        \\\"commune_exact\\\",\\n        \\\"house_rep\\\"\\n      ]\\n    }\\n  ]\\n}\", \"type\": \"text\"}], \"isError\": false, \"structuredContent\": {\"country\": \"rs\", \"query\": \"Knez Mihailova 5, Beograd\", \"results\": [{\"lat\": 44.8154522, \"lon\": 20.4593897, \"precision\": \"house\", \"score\": 5.5504302978515625, \"confidence\": 0.9399999976158142, \"street\": \"Kneza Mihaila\", \"commune\": \"Stari Grad\", \"postcode\": \"\", \"hous",
        "expected": "a house-precision result on Kneza Mihaila",
        "input": "{\"tool\": \"geocode\", \"arguments\": {\"query\": \"Knez Mihailova 5, Beograd\", \"country\": \"rs\"}}",
        "kind": "claim",
        "outcome": "Real input produced the expected result: Kneza Mihaila",
        "source": "Everything after the download runs offline.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      }
    ],
    "cycle_checks": [
      {
        "claim": "Scheduled or looping main behavior",
        "command": "",
        "evidence": "Entry points inspected: the gridpin CLI subcommands (build, reverse, query, batch, meta, repack), gridpin-fetch, and the gridpin-mcp stdio server are all request-driven and have no cron, scheduler, --once/--now flag, webhook or loop. The while-True loops are in the download read loop (mcp/src/gridpin_mcp/sheets.py) and in the internal prep/ data pipeline, not a product schedule. Nothing is triggered on a timer.",
        "expected": "identify the product trigger",
        "input": "source inspection",
        "kind": "cycle",
        "outcome": "Entry points inspected: the gridpin CLI subcommands (build, reverse, query, batch, meta, repack), gridpin-fetch, and the gridpin-mcp stdio server are all request-driven and have no cron, scheduler, --once/--now flag, webhook or loop. The while-True loops are in the download read loop (mcp/src/gridpin_mcp/sheets.py) and in the internal prep/ data pipeline, not a product schedule. Nothing is triggered on a timer.",
        "source": "repository entry points",
        "verdict": "yes"
      }
    ],
    "details": {
      "argv": [
        "<guest-path>"
      ],
      "kind": "mcp",
      "scope": "product operation",
      "serverInfo": {
        "name": "gridpin",
        "title": "GridPin offline geocoder",
        "version": "0.1.0",
        "websiteUrl": "https://gridpin.dev"
      },
      "tool_result": {
        "content": [
          {
            "text": "{\n  \"country\": \"fr\",\n  \"query\": \"1 rue de la Paix, Paris\",\n  \"results\": [\n    {\n      \"lat\": 48.868546,\n      \"lon\": 2.33031,\n      \"precision\": \"house\",\n      \"score\": 0.08887004852294922,\n      \"street\": \"Rue de la Paix\",\n      \"housenumber\": \"1\",\n      \"commune\": \"Paris 2e Arrondissement\",\n      \"postcode\": \"75002\",\n      \"confidence\": 0.8399999737739563,\n      \"flags\": [\n        \"street_exact\",\n        \"commune_prefix\",\n        \"house_rep\"\n      ]\n    }\n  ]\n}",
            "type": "text"
          }
        ],
        "isError": false,
        "structuredContent": {
          "country": "fr",
          "query": "1 rue de la Paix, Paris",
          "results": [
            {
              "commune": "Paris 2e Arrondissement",
              "confidence": 0.8399999737739563,
              "flags": [
                "street_exact",
                "commune_prefix",
                "house_rep"
              ],
              "housenumber": "1",
              "lat": 48.868546,
              "lon": 2.33031,
              "postcode": "75002",
              "precision": "house",
              "score": 0.08887004852294922,
              "street": "Rue de la Paix"
            }
          ]
        }
      },
      "tool_result_checked": true,
      "tool_schema_bytes": 6758,
      "tools": [
        "list_countries",
        "download_sheet",
        "geocode",
        "reverse",
        "batch"
      ],
      "working": true
    },
    "evidence_strength": "readme_checked",
    "example_checks": [
      {
        "claim": "Batch-geocode five French addresses with the Python binding against the France sheet",
        "command": "<guest-path> examples/batch.py <guest-path>",
        "deferred": false,
        "evidence": "  \"commune_exact\",\n          \"house_rep\",\n          \"pc_exact\"\n        ]\n      }\n    ]\n  },\n  {\n    \"query\": \"16 rue de la Monnaie, 59800 Lille\",\n    \"results\": [\n      {\n        \"lat\": 50.640827,\n        \"lon\": 3.063621,\n        \"precision\": \"house\",\n        \"score\": 7.2687788009643555,\n        \"street\": \"Rue de la Monnaie\",\n        \"housenumber\": \"16\",\n        \"commune\": \"Lille\",\n        \"postcode\": \"59800\",\n        \"confidence\": 0.949999988079071,\n        \"flags\": [\n          \"street_exact\",\n          \"commune_exact\",\n          \"house_rep\",\n          \"pc_exact\"\n        ]\n      }\n    ]\n  }\n]",
        "expected": "JSON with one result per address, e.g. 10 rue de Rivoli resolves to Rue de Rivoli",
        "input": "examples/batch.py with the downloaded france.bin",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "examples/README.md (batch.py: python batch.py /path/to/france.bin)",
        "verdict": "yes"
      },
      {
        "claim": "The MCP package's offline test suite passes",
        "command": "<guest-path> -m pytest mcp/tests -q",
        "deferred": false,
        "evidence": "sss.............sssssssssssss..                                          [100%]\n15 passed, 16 skipped in 3.10s",
        "expected": "15 passed; 16 skipped because the Monaco test sheet (make mc) is not built",
        "input": "python -m pytest mcp/tests -q",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "mcp/tests (CI runs python -m pytest in this layout)",
        "verdict": "yes"
      },
      {
        "claim": "Photon-compatible loopback HTTP facade for a sheet",
        "command": "",
        "deferred": true,
        "evidence": "Left out on purpose: it is a loopback interop adapter for geocoder-tester runs and needs the CLI binary plus a long-running server; core geocoding was exercised through the MCP probe, CLI and batch example instead.",
        "expected": "documented command completes successfully",
        "input": "",
        "kind": "example",
        "outcome": "Left out on purpose: it is a loopback interop adapter for geocoder-tester runs and needs the CLI binary plus a long-running server; core geocoding was exercised through the MCP probe, CLI and batch example instead.",
        "source": "examples/README.md (gridpin_http.py)",
        "verdict": "deferred"
      },
      {
        "claim": "Streamlit live demo and Colab quickstart",
        "command": "",
        "deferred": true,
        "evidence": "Left out on purpose: a UI demo needing Streamlit and a browser or Colab; no browser was installed or used.",
        "expected": "documented command completes successfully",
        "input": "",
        "kind": "example",
        "outcome": "Left out on purpose: a UI demo needing Streamlit and a browser or Colab; no browser was installed or used.",
        "source": "examples/README.md (streamlit/, colab_quickstart.ipynb)",
        "verdict": "deferred"
      },
      {
        "claim": "Data-build and benchmark pipeline (prep/, make mc, make smoke)",
        "command": "",
        "deferred": false,
        "evidence": "Not run: building the Monaco and country sheets needs the OSM/Overture source downloads and the DuckDB pipeline, which is outside the install-and-query path; the Monaco sheet is missing so 16 mcp tests skip.",
        "expected": "documented command completes successfully",
        "input": "",
        "kind": "example",
        "outcome": "Not run: building the Monaco and country sheets needs the OSM/Overture source downloads and the DuckDB pipeline, which is outside the install-and-query path; the Monaco sheet is missing so 16 mcp tests skip.",
        "source": "Makefile smoke and mc targets",
        "verdict": "blocked"
      }
    ],
    "status": "PASS"
  },
  "diagnosis": null
}
