Content Intelligence (Search Visibility)

Adapted from docs/admin/ContentIntelligence.md in the Wikantik repository; current as of release 2.4.56.

This page is for administrators and content curators who want to know what to write or fix next. Content Intelligence combines search-engine visibility data with Wikantik's own retrieval and verification data into a ranked opportunity backlog. It covers the Search Visibility screen at /admin/insights, the data that feeds it, how to load that data, and how to act on or decline an opportunity. The module is wikantik-insights; the full design is in docs/superpowers/specs/2026-08-16-content-intelligence-design.md.

The subsystem is on by default (wikantik.insights.enabled, default true) and needs a configured datasource. Without one, the backlog endpoint and the two MCP tools answer that the subsystem is not available.

Use the Search Visibility screen

Open Admin → Search Visibility (/admin/insights, InsightsPanel.jsx and BacklogPanel.jsx). It has two parts.

Acquisition. The screen always asks for the site wiki.wikantik.com (a constant in InsightsPanel.jsx); call the endpoint yourself to see another site. One row per search engine for the most recent snapshot date: clicks, impressions, click-through rate, average position, and a clicks sparkline over the last 90 days. Backed by GET /admin/insights/acquisition?site=&days= (InsightsResource; days is clamped to 1-400). Totals come from page-rollup rows only, because every engine omits low-volume queries and summing query rows would undercount. An engine that sends no page-rollup rows (Yandex, at the time of writing) is absent, not shown as zero, and a missing position is shown as an em dash, not 0, since 0 would mean rank 1.

Opportunity backlog. The ranked list, with a Type filter and an Include snoozed checkbox. Each row shows type, target, priority, first-seen date, suggested action and the evidence that fired the rule. Backed by GET /admin/insights/backlog (InsightsBacklogResource) with site, type, minPriority, limit (1-200, default 50) and includeSnoozed.

Read three things beside the list:

Know what feeds it

SourceWhat it suppliesWhere it lands
jakemon search-visibility snapshotsper-engine page and query clicks, impressions and position (Google, Bing, Yandex)search_visibility_snapshot (V050)
jakemon detector outputfive imported opportunity typesimported_opportunity (V056)
jakemon expected-CTR curvemeasured CTR by position, positions 1-10expected_ctr_curve (V057)
Wikantik's own retrieval logqueries that agents ask and get weak or empty answers forretrieval_query_log (signal columns added by V051)
Page frontmatter and verification statepage age, verification and confidenceread live from the wiki

jakemon is the observability plane that collects the search-engine data; Wikantik only stores and reads it. See SimpleAgilityObservabilityPlane for the boundary.

Opportunity types

Four native rules are computed inside Wikantik (OpportunityEngine):

TypeFires whenGated by traffic?Target
agent_gapa query comes back empty or weak on every agent surface, with minimum occurrences and distinct sessionsnothe query text
engine_divergencea page ranks materially better on one engine than another (a diagnostic, not a fix)yesa page path
vocabulary_gapa query with real clicks lands on a page whose metadata does not mention the query's content wordsyesa page path
stale_high_traffica page with real traffic whose verification is old, missing, or not authoritativeyesa page path

Five imported types arrive pre-built from jakemon and pass straight through: striking_distance, ctr_gap, content_gap, cannibalization and decay. Imported ctr_gap and striking_distance rows are suppressed for a page when engine_divergence explains them.

Tune the engine

The settings are in wikantik.properties under [Content Intelligence]; the generated Wikantik Configuration Reference lists every key with its default. The ones you are most likely to change:

PropertyDefaultEffect
wikantik.insights.rules.siteswiki.wikantik.com,wikantik.comsites the rules act on; the first is the default site
wikantik.insights.rules.gate.impressions28d5000site impressions in 28 days below which the three volume-driven rules do not run
wikantik.insights.opportunity.stale.days180age after which a high-traffic page counts as stale
wikantik.insights.imported.max_age_days7the backlog reads only the latest imported set, and only if it is this recent
wikantik.insights.calibration.min_verdicts20evaluated changes needed before a type's weight is recalibrated
wikantik.insights.change.cooldown.days60at most one automatic optimisation per page per this many days

Set your own site names in wikantik.insights.rules.sites; the defaults name the public Wikantik sites. The backlog uses the first entry when no site is given.

Load search-visibility data

POST /admin/insights/ingest accepts one jakemon snapshot document per request. It is gated by AdminAuthFilter like every /admin/* path. Use an administrator, or better, a service account that holds only the insights area (see below).

curl -u shipper:... -X POST http://localhost:8080/admin/insights/ingest \
     -H 'Content-Type: application/json' --data @snapshot.json

The document has a top-level engine, site, snapshot_date (ISO date) and optional window_days (default 28), plus the data arrays:

A successful response reports counts:

{"rows_upserted": 1200, "rows_rejected": 0}

opportunities_upserted / opportunities_rejected and expected_ctr_upserted / expected_ctr_rejected appear only when the payload carried those keys. A bad row is counted in the *_rejected fields rather than failing the request; the endpoint never returns 500 for a malformed payload.

PropertyDefaultEffect
wikantik.insights.ingest.max_bytes4194304largest accepted body; larger requests get 413
wikantik.insights.ingest.enginesgoogle,bing,yandexengines accepted; others are rejected and counted
wikantik.insights.ingest.sitesblanksites accepted; blank accepts every site

Give the shipper least privilege

The shipper only needs /admin/insights/*. Grant it that one area instead of putting its account in the Admin group. Post the grant to /admin/policy:

{"principalType":"user","principalName":"jakemon-shipper","permissionType":"admin",
 "target":"insights","actions":"access"}

Details of scoped admin grants are in the "Scoped admin access" section of the Security Guide.

Act on or decline an opportunity

Two MCP tools on /wikantik-admin-mcp expose the same backlog to an agent, using the same service as the screen so the two never disagree (see MCP Integration):

The suggested action depends on the type. For agent_gap, curate the Knowledge Graph relations or write the missing section. For stale_high_traffic, re-verify or refresh the page.

Where to go next


Cluster Hub: Wikantik Platform Development Hub: Architecture, MCP Protocols, and Agent Briefings (wikantik-development)