canonry

Architecture

Overview

Canonry is a self-hosted AEO monitoring application built on the published @ainyc/aeo-audit npm package. It tracks how AI answer engines (Gemini, OpenAI, and Claude) cite or omit a domain for tracked keywords.

Locations are modeled as project-scoped run context. A project can define named locations and an optional default location, while keywords remain project-wide.

Local Architecture (Phase 2)

The local installation runs as a single Node.js process — no Docker, no Postgres, no message queue.

flowchart LR
  User["Analyst"]
  Target["AI answer engines"]

  subgraph Process["canonry serve"]
    direction LR
    SPA["Static SPA\n/"] --> API["Fastify API\n/api/v1/*"]
    API --> JobRunner["In-process\njob runner"]
    API --> SQLite["SQLite"]
    JobRunner --> Registry["Provider\nRegistry"]
    Registry --> Gemini["provider-gemini"]
    Registry --> OpenAI["provider-openai"]
    Registry --> Claude["provider-claude"]
    JobRunner --> SQLite
  end

  User --> SPA
  User -. CLI .-> API
  Gemini --> Target
  OpenAI --> Target
  Claude --> Target

Key components

Data flow

  1. Analyst runs canonry run <project> with the project default location, an explicit --location, --all-locations, or no location context
  2. API creates a run record and enqueues a job
  3. Job runner resolves the run location, fans out executeTrackedQuery for each keyword across all configured providers via the provider registry, and passes the location hint to providers
  4. Raw observation snapshots (cited / not-cited) are persisted per keyword per run, tagged with the run’s location label when present
  5. Transitions (lost, emerging) are computed at query time by comparing consecutive snapshots
  6. Dashboard polls API for results and renders visibility data

Cloud Architecture (Phase 4+)

Concern Local Cloud
Database SQLite Managed Postgres
Process model Single process API + Worker + CDN
Job queue In-process async pg-boss
Auth Auto-generated local key Bootstrap endpoint + team keys
Web hosting Fastify static CDN

The same API routes, contracts, Drizzle schema, and dashboard code are used in both modes. The cloud deployment replaces the single-process server with separate services.

Service Boundaries

Design Constraints

Score Families

These remain separate to avoid mixing technical readiness with live-answer visibility.