Search visibility is not a project with an end date. It is maintenance: titles drift, structured data rots, internal links break, competitors publish, and the answer engines re-decide who gets quoted every time they run. Doing that work by hand does not scale past a handful of pages. Doing it with a cron job and a script does not scale past a handful of regexes. This post is about the third option — background coding agents that treat SEO and GEO as a scheduled engineering workflow, not a monthly panic.
Search is now two channels
Classic SEO optimizes for the crawl-index-rank loop: keyword-aligned titles and descriptions, clean canonicals, sitemaps, page speed, internal linking. GEO — generative engine optimization optimizes for the quoters: ChatGPT, Perplexity, Google AI Overviews, and every assistant that assembles an answer instead of a result page. Answer engines favor pages that say the thing plainly, early, in text they can parse — not pages that hide the answer behind a canvas of JavaScript.
Both channels reward the same underlying discipline: frequent, small, evidence-backed changes to real content. That is exactly the shape of work agents are good at.
The loop: schedule, isolate, ship
tellnova runs each task in its own git worktree on its own branch, so an agent reworking your metadata never touches your working copy. The loop for automated search work looks like this:
- Schedule fires — daily, hourly, or weekly, with an idempotent occurrence key so a restart can never double-dispatch.
- The agent reads evidence — analytics exports, search console data, crawl results — with only the permissions it declared (
analytics:read,network:read). - It implements exactly one change in an isolated worktree and runs your repository checks.
- The diff arrives as a pull request intent. In v1 a system cannot merge its own pull request — a human ships it.
That last point matters more than any ranking factor. Automated SEO that can silently rewrite your site is a liability; automated SEO that prepares one reviewable diff per run is a flywheel.

A website-improver system, concretely
The tellnova repo ships an example system that does precisely this. Its manifest is short enough to read in one glance:
{
"schema": "tellnova.dev/system/v1",
"name": "website-improver",
"permissions": [
"analytics:read",
"repository:read",
"repository:write",
"pull_requests:write"
],
"automations": [
{
"name": "Daily website improvement",
"source": { "type": "schedule", "cadence": "daily", "hour": 9 },
"task": {
"repo": "${input.repository}",
"provider": "openrouter",
"model": "anthropic/claude-sonnet-4.5",
"prompt": "Read the previous 24 hours of website analytics. Compare them with the seven-day baseline. If there is a clear evidence-backed improvement, implement exactly one change, run the repository checks, and explain the evidence and expected effect. If the evidence is weak, make no code changes and report why."
},
"policy": { "overlap": "skip", "maxRunsPerDay": 1, "maxCostUsd": 0.5 },
"delivery": { "mode": "pull_request", "merge": false }
}
]
}
Install it against a repository and every morning you have either one evidence-backed diff or a note explaining why today was not the day. Overlap policies, timeouts, daily run limits, and cost caps are part of the contract, so the automation cannot stampede. Installed systems are immutable snapshots — upgrading is a deliberate act, never a silent one. And if the target machine is unreachable, the run fails closed rather than hopping somewhere it should not be.
The weekly agent playbook
Given that loop, here is what we actually schedule against marketing sites:
- Title and meta hygiene — flag pages whose titles exceed the result-layout budget or whose descriptions no longer match the content, and prepare the corrected front matter.
- Structured data checks — validate every JSON-LD block (Organization, SoftwareApplication, FAQ, HowTo) against the schema, because one invalid
datePublishedsilently disables a rich result. - Internal link repair — find orphaned pages and broken internal links, then draft the smallest set of contextual links that fixes both.
- Sitemap and canonical audits — every URL in the sitemap must return 200, carry a self-referencing canonical, and appear in exactly one place.
- Answer-position reviews — for each money query, check that the direct answer appears in the first hundred words of server-rendered text, not behind a hydration boundary.
Each of those is a prompt, not a bespoke script — and each lands as a pull request you can read over coffee.
Being quotable to answer engines
GEO has one foot in content strategy and one in infrastructure. The infrastructure half is what agents excel at:
- Serve the answer as server-rendered text. This very blog renders full HTML with meta, OpenGraph, and JSON-LD from the server, because crawlers and answer engines read rendered text, not intention.
- Mark up FAQ and HowTo structures with schema.org types so quotable passages have machine-readable shape.
- Maintain an
llms.txtand honestnoscriptfallbacks so assistants crawling raw HTML still receive the substance. - Monitor citations — an agent with a browser can periodically ask the major answer engines your money queries and log whether you are quoted, building a GEO rank tracker out of tasks instead of a SaaS subscription.
Guardrails that keep it honest
The failure mode of "AI SEO" is obvious: a model confidently rewriting ten thousand meta descriptions at midnight. The defenses are structural. One change per run. Declared permissions that installations reject if unknown. Cost caps and run limits in the policy. Delivery defaults to a pull request a human merges. And every prompt we run includes the escape hatch that makes automation trustworthy — if the evidence is weak, change nothing and say why.
The post you are reading is itself a small proof: it was published through tellnova's blog API, which runs a server-side SEO audit on every submission and refuses posts scoring under 70. Agents do the writing; the contract does the guarding. That is the whole idea — download tellnova and put the fleet to work on your own site.
