Fixes & verification

A closed list of deterministic patches. Each declares the verification it needs, and the outcome never claims more than was achieved.

Fix classes

ClassMeaningWho may apply
safeAdditive, local, deterministic; no owner policy; exact/absent provenance; every precondition holdsfix --apply
guardedDeterministic, but needs owner intent or production contextInteractive yes, or --approve <fixId>
contextualNeeds code or architecture judgementThe agent, after per-change approval
editorialChanges visible copy or claimsA human approves each change
unsupportedUnmapped source, external infrastructure or unsafe conditionsNobody automatically

Variants (single source of truth)

VariantRuleClassRequiresWhy
S1 Add a Sitemap line to the sole literal robots.txtGEO-011safeV2The file is served verbatim; the static re-check is conclusive.
S2 Add the configured lang to the literal root <html>GEO-012safeV2Literal markup with exact provenance.
G1 Remove a literal noindex from a sitemap-listed routeGEO-014guardedV4Headers or middleware outside the literal can still emit noindex; only the served response proves indexability.
G2 Add a canonical to a static Next.js routeGEO-015guardedV4The rule includes target status and indexability, which are runtime properties.
G3 Create a static-only app/sitemap.tsGEO-011guardedV4Generated output must be served and valid.
G4 .well-known app-link filesGEO-101guardedV4Phase 2: not in this release.
G5 Crawler-specific robots groupsGEO-009guardedV2 / V4Phase 2: needs the RFC 9309 equivalence proof.

Lifecycle

  1. Dry run (the default): diff, provenance, every precondition, required verification. Variants whose preconditions fail are listed with the reason.
  2. Guards: dirty target files need --allow-dirty; the default branch needs confirmation; every approval is settled before the first byte is written.
  3. Snapshot and splice: originals go to .geo/runs/<runId>/fix/; edits are AST-located, byte-minimal splices; multi-file fixes are atomic.
  4. Verify V1–V4 and compare the rule condition and new findings, not fingerprint absence.
  5. Outcome: verified; applied_unverified (exit 6) when no check failed but the required level was not reached; rolled_back (exit 5) when an executed check failed — only that fix is restored.
  6. Rollback: fix --rollback <runId> restores byte-exact snapshots and refuses any file edited afterwards.

Verification levels

  • V1 — syntax. Touched files parse.
  • V2 — static rule. The affected sub-check now passes on a fresh re-scan and no new finding appears on an affected subject. A disappearance into not_evaluated is unverified.
  • V3 — configured commands. Only exact owner-configured argv commands, with interactive confirmation, an exact --verify-cmd, or GEO_ALLOW_VERIFY_COMMAND=1.
  • V4 — runtime observation. Requires confirmed source freshness and the rule now passing on the served response.

Freshness: the GEO-started serve process

A changed response is not proof that the app rebuilt from the edited source. In this release, source_freshness: confirmed means exactly one thing: GEO itself started the server after the last write.

  1. Authorise like V3: fix.serve.command and fix.serve.url in config, and --serve, an interactive yes, or GEO_ALLOW_SERVE_COMMAND=1. Config alone never starts a process, so a pull request that edits config cannot start one in CI.
  2. The port must be free. If something is already listening, GEO refuses (runtime_unavailable: port_in_use) — it cannot prove it would be talking to its own process.
  3. GEO spawns the argv with no shell from the repository root, after the last write, and polls the URL until it answers (or serve_not_ready).
  4. It fetches the affected URLs, re-evaluates, records process_started_after_write, and always terminates the process tree.
Stated limit. “Confirmed” means the process started after the edit. A command that serves stale prebuilt output — next start without a rebuild — defeats it. Use a from-source dev command such as pnpm exec next dev --port 3100.

Against a server you run yourself (--url), V4 is observation only: freshness stays unconfirmed and a V4-required fix is applied_unverified. An unconfirmed runtime never triggers a rollback; a confirmed-fresh runtime that still fails does. GEO never injects marker code into your project and never runs builds on its own.