Five correctness issues in the GEO agents: wrong Content-Signal keys, tools that can't return the data the steps ask for, and a wrong RFC number
Summary
Five correctness issues in the GEO analysis agents, found while reviewing a vendored copy at 6b6825b. Each one is verified against a primary source below. Three would make an agent report a wrong result rather than fail loudly, which is why I'm filing them together.
1. geo-ai-visibility.md — Content-Signal key list does not match the draft
The agent declares the valid keys as ai-train, search, ai-personalization, ai-retrieval.
The draft it cites (draft-romm-aipref-contentsignals) defines exactly three labels:
+=============+==========+=============+
| Category | Label | Reference |
+=============+==========+=============+
| Search | search | Section 3.1 |
| AI Input | ai-input | Section 3.2 |
| AI Training | ai-train | Section 3.3 |
+-------------+----------+-------------+
Table 1: Usage category labelsSo ai-input is missing and ai-personalization / ai-retrieval do not appear in the draft. A real-world directive such as Content-Signal: ai-train=no, search=yes, ai-input=no is parsed incompletely — the ai-input preference is silently dropped from the report.
Source: https://www.ietf.org/archive/id/draft-romm-aipref-contentsignals-00.txt
2. geo-technical.md Step 1 — WebFetch cannot capture response headers
Step 1 says "Use WebFetch to retrieve the target URL" and then asks to capture Content-Type, Cache-Control, ETag, X-Robots-Tag, Server, Content-Encoding, and all Link: header values.
WebFetch returns processed page content, not raw HTTP response headers, so none of these can be read through it. Step 10's RFC 8288 service-discovery analysis depends on those Link: values, so it has no input.
This repo already ships the fix: scripts/fetch_page.py populates result["headers"] = dict(response.headers). Pointing Step 1 at that script (as geo-schema.md already does) would resolve it.
3. geo-schema.md Step 1 — Microdata and RDFa cannot be scanned
Step 1 says to "scan the full HTML source for structured data in all three formats", using fetch_page.py <url> page.
That mode's result dict carries url, status_code, redirect_chain, headers, title, meta_tags, canonical, heading_structure, and structured_data — but not the response body. JSON-LD works because it arrives pre-parsed in structured_data; Microdata (itemscope / itemprop) and RDFa attributes have nothing to scan, so the agent reports false negatives for two of the three formats it claims to check.
Adding a raw-HTML field to the page mode output would fix both this and any other step that needs the body.
4. geo-technical.md — wrong RFC number for api-catalog
The file reads:
Identify high-value rel types:
api-catalog(RFC 9609),describedby,service-doc,mcp-server-card.
api-catalog is registered by RFC 9727 ("api-catalog: A Well-Known URI and Link Relation to Help Discovery of APIs", Standards Track, June 2025). The IANA link-relations registry entry points at rfc9727. RFC 9609 is an unrelated ICANN BCP.
Sources: https://www.rfc-editor.org/rfc/rfc9727.html · https://www.iana.org/assignments/link-relations/link-relations.xml
5. geo-technical.md — Markdown content-negotiation template has no error state
Step 10 asks for errors and non-200 responses to be skipped and recorded, and the template's trailing comment says <!-- If request errored: note the error, skip recommendation -->. But the status line only offers two values:
**Status:** Supported / Not SupportedA request that timed out or returned 500 therefore gets written up as a confirmed "Not Supported", which is a different claim. An Error / Skipped value plus a field for the detail would keep the two apart.
Notes
Issues 1 and 4 are single-line corrections. Issues 2 and 3 are the substantive ones — both are cases where the agent's instructions ask for data the chosen tool never returns, so the analysis silently proceeds on missing input.
Happy to send a PR for any of these if that's useful.
Source: zubair-trabzada/geo-seo-claude