@ainyc/canonry 5.1.3 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/assets/agent-workspace/skills/aero/SKILL.md +43 -9
  2. package/assets/agent-workspace/skills/aero/references/agent-operations.md +231 -0
  3. package/assets/agent-workspace/skills/aero/references/orchestration.md +11 -5
  4. package/assets/agent-workspace/skills/aero/references/portfolio-analysis.md +93 -0
  5. package/assets/agent-workspace/skills/aero/references/reporting.md +10 -1
  6. package/assets/agent-workspace/skills/aero/references/site-health.md +104 -0
  7. package/assets/agent-workspace/skills/aero/soul.md +5 -0
  8. package/assets/assets/{AuditHistoryPanel-Dc_pymFg.js → AuditHistoryPanel-D0H5TtxC.js} +1 -1
  9. package/assets/assets/{BacklinksPage-BkSo48YX.js → BacklinksPage-DRihwG5O.js} +1 -1
  10. package/assets/assets/{HistoryPage-BbswsdU7.js → HistoryPage-BQ2nEXly.js} +1 -1
  11. package/assets/assets/{MeasurementPropertyPage-BbgtalkM.js → MeasurementPropertyPage-Bp6EURzJ.js} +1 -1
  12. package/assets/assets/ProjectPage-Cd03Phwx.js +8 -0
  13. package/assets/assets/{RunRow-2cNW8FHz.js → RunRow-Bo_Adiy0.js} +1 -1
  14. package/assets/assets/{RunsPage-Cz3lJ6VJ.js → RunsPage-CDkbzjuo.js} +1 -1
  15. package/assets/assets/{SettingsPage-BQwB0r9k.js → SettingsPage-CF4i_EzR.js} +1 -1
  16. package/assets/assets/SiteHealthSection-BrzBV7dt.js +4 -0
  17. package/assets/assets/{TrafficPage-DTic3zhO.js → TrafficPage-BHSz1N4P.js} +1 -1
  18. package/assets/assets/{TrafficSourceDetailPage-BKfabnCw.js → TrafficSourceDetailPage-DzHLwhpy.js} +1 -1
  19. package/assets/assets/{extract-error-message-BzB8j3fC.js → extract-error-message-WHM24Sai.js} +1 -1
  20. package/assets/assets/{index-DQGEzxrN.js → index-5W4ZZnwg.js} +22 -22
  21. package/assets/assets/index-DCLmKL1s.css +1 -0
  22. package/assets/assets/{react-sigma_core.esm.min-rYv0aKKx.js → react-sigma_core.esm.min-BB2Lcq4W.js} +1 -1
  23. package/assets/assets/{v2-overview-adapter-CWWPfsm-.js → v2-overview-adapter-ebrNjcUG.js} +1 -1
  24. package/assets/assets/vendor-lucide-D_WBzb76.js +1 -0
  25. package/assets/index.html +3 -3
  26. package/dist/{chunk-MMSPU72Z.js → chunk-2U5IW3G5.js} +4 -0
  27. package/dist/chunk-5VONCLVQ.js +652 -0
  28. package/dist/chunk-AOJU5LKX.js +8 -0
  29. package/dist/{chunk-KJM4DRZN.js → chunk-C7PITYL3.js} +5 -3
  30. package/dist/{chunk-5ZOLPHTO.js → chunk-CW2KPN3L.js} +331 -943
  31. package/dist/{chunk-AEE5DGTE.js → chunk-IOP36L3C.js} +4 -7
  32. package/dist/chunk-RB2F4D3Z.js +67 -0
  33. package/dist/{chunk-EBUX3C5H.js → chunk-YQNKULAD.js} +30 -10
  34. package/dist/cli.js +100 -5
  35. package/dist/demo-server-BIPT53EY.js +2125 -0
  36. package/dist/index.js +6 -4
  37. package/dist/intelligence-service-SJO5E7WN.js +9 -0
  38. package/dist/mcp.js +4 -3
  39. package/package.json +11 -11
  40. package/assets/assets/ProjectPage-CAcRQp-T.js +0 -8
  41. package/assets/assets/SiteHealthSection-C0aJ_UhN.js +0 -4
  42. package/assets/assets/index-CjEprBri.css +0 -1
  43. package/assets/assets/vendor-lucide-CW2qe0uH.js +0 -1
  44. package/dist/intelligence-service-25NQCETC.js +0 -7
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: aero
3
- description: "Diagnose AEO regressions and report on them: why mention or citation coverage moved, which queries and answer engines changed, and what to do about it. Use when a coverage number moved and needs explaining, when preparing a client report or month-over-month comparison, or when a `cnry` sweep completed and needs analysis. Coordinates canonry sweeps with aeo-audit site analysis and keeps durable project memory. Use the canonry skill for setup and operations instead."
3
+ description: "Diagnose AEO regressions and interpret Canonry AI visibility, Advanced multi-property portfolios, and Site Health evidence. Use when a mention or citation coverage number moved and needs explaining, when comparing Properties or markets, diagnosing crawl or page findings, preparing a client report or month-over-month comparison, or analyzing a completed `cnry` sweep or site audit. Preserves measurement scope, missing-data states, and comparison limits. Use the canonry skill for setup and operations."
4
4
  metadata:
5
5
  homepage: https://canonry.ai
6
6
  repository: https://github.com/AINYC/aero
@@ -8,13 +8,44 @@ metadata:
8
8
 
9
9
  # Aero Orchestration Skill
10
10
 
11
- You coordinate across two tools to deliver comprehensive AEO monitoring:
12
- - **canonry** — the source of truth for project state (runs, snapshots, timelines, insights, audit log, **GA4 traffic + AI/social referrals**, **server-side crawler + referral events**). Query it with `cnry <command> --format json` (the CLI is also installed as `canonry` the two are interchangeable); never maintain a parallel copy in agent memory. For a specific scalar use `cnry get <project> <path>` instead of pulling a full payload.
13
- - **aeo-audit** on-demand site analysis and fix generation.
11
+ Use Canonry's stored evidence to explain AI visibility and site readiness. In
12
+ built-in Aero, call the available `canonry_*` tools directly. Project-scoped
13
+ tools use the session's project; they do not accept a different project from
14
+ the model. External agents can use connected MCP or `cnry <command> --format
15
+ json`. CLI examples in the references are for hosts with a shell; built-in
16
+ Aero should use the corresponding exposed tool, not invent shell access.
17
+
18
+ Canonry is the source of truth for runs, measurement plans, Property evidence,
19
+ Site Health audits, integrations, and history. Read stored page audits before
20
+ proposing fresh `aeo-audit` work. New crawls and provider work require approval
21
+ covering that work; an existing explicit authorization remains valid.
22
+
23
+ ## Choose the evidence scope
24
+
25
+ - **Simple portfolio:** use project overview, visibility statistics, and stored
26
+ answer evidence. **Advanced portfolio:** read the active plan and use the
27
+ measurement tools. Preserve Property/Target identity, market, plan revision,
28
+ run, provider/model, location, and query class. Read
29
+ `references/portfolio-analysis.md` before ranking Properties or comparing
30
+ Advanced results.
31
+ - **Site Health:** read `references/site-health.md` before diagnosing scores,
32
+ crawl coverage, internal links, or page findings. Technical readiness is a
33
+ separate signal from measured mentions and citations.
34
+ - Missing runs, `not_measured`, unavailable metrics, and unchecked signals
35
+ are not zero. Use returned numerators, denominators, and availability
36
+ reasons; do not average Property percentages or sum overlapping markets.
37
+ - The dashboard chat supplies the project and message, not its selected
38
+ Property, market, filters, or graph page. Resolve explicit names/URLs from
39
+ stored data. If "this Property" or "this page" remains ambiguous, ask which
40
+ one before making a scoped claim. State the scope used for broad questions.
41
+ - Read `references/agent-operations.md` for shared vocabulary, evidence,
42
+ comparison, and authority rules. Its MCP onboarding instructions apply to
43
+ external hosts; built-in Aero already has its tool catalog and skill-doc
44
+ readers. Tool descriptions define the parameters actually available.
14
45
 
15
46
  Persist only *user-scoped* context (operator preferences, communication style) in your platform's native memory. Project-scoped facts live in canonry and must be read back, not remembered.
16
47
 
17
- **Two signals, not one.** Every (query × provider) snapshot tracks **mentioned** (brand in answer text) and **cited** (domain in source links) independently. Lead with **Mention Coverage** when narrating health it is the primary gauge — and report **Citation Coverage** as the secondary signal. Never compute one from the other, and never collapse them into a single "visibility" headline. The downloadable report (`cnry report`) and the dashboard hero both honor this split.
48
+ **Two signals, not one.** Every (query × provider) snapshot tracks **mentioned** (brand in answer text) and **cited** (domain in source links) independently. Lead with **Mention Coverage** when narrating AI visibility and report **Citation Coverage** as the secondary signal. Never compute one from the other, and never collapse them into a single "visibility" headline. For Site Health questions, lead with the requested audit or crawl evidence.
18
49
 
19
50
  When a project has GA4 connected, traffic is a first-class signal alongside
20
51
  mentions and citations. Use `cnry ga traffic` and `cnry ga attribution --trend`
@@ -37,7 +68,7 @@ command reference is in the co-installed
37
68
 
38
69
  ## Judgment Rules
39
70
 
40
- ### What to Prioritize
71
+ ### AI visibility priorities
41
72
 
42
73
  Mention is the primary gauge (see "Two signals, not one" above); citation is the secondary signal on the same query. Rank work accordingly:
43
74
 
@@ -49,7 +80,7 @@ Mention is the primary gauge (see "Two signals, not one" above); citation is the
49
80
 
50
81
  ### What NOT to Do
51
82
  - Don't promise fixes will appear in the next sweep (AEO changes take weeks/months)
52
- - Don't give generic SEO advice — always ground recommendations in mention and citation data, leading with the mention signal
83
+ - Ground AI visibility recommendations in mention and citation evidence. Ground Site Health recommendations in persisted audit and crawl findings.
53
84
  - Don't run sweeps, probes, syncs, audits, discovery sessions, or any other write or quota-consuming operation without explicit user approval
54
85
  - Don't edit client's code without showing diffs and getting approval
55
86
  - Don't conflate "not mentioned" with "page doesn't exist" — and don't conflate "not cited" with "not mentioned" either; check first. The two signals are independent (see "Two signals, not one") and are never computed from each other.
@@ -76,7 +107,7 @@ A real (non-probe) sweep is appropriate when the user explicitly asks to refresh
76
107
 
77
108
  ### How to Communicate
78
109
  - Data first: show the numbers before the interpretation
79
- - Lead with the mention transition, keep citation as a trailing clause: "ChatGPT stopped mentioning you for 'roof repair phoenix' between Mar 28-Apr 2, and your mention share fell from 50% to 0% as a competitor took the slot" then, second, note that you also lost the citation for that query. Not "your visibility decreased."
110
+ - For AI visibility, lead with the mention transition, then the citation change. For Site Health, lead with the requested score or finding and its affected pages and crawl limits.
80
111
  - Action-oriented: every observation ends with a recommended next step
81
112
 
82
113
  ## References
@@ -85,6 +116,9 @@ Detailed playbooks live alongside this file. Read them on demand when the task m
85
116
 
86
117
  | File | Read when |
87
118
  |---|---|
119
+ | `references/portfolio-analysis.md` | Interpreting Simple or Advanced portfolios, ranking Properties or markets, or comparing measurement runs |
120
+ | `references/site-health.md` | Diagnosing site/page scores, crawl completeness, internal links, or changes between scans |
121
+ | `references/agent-operations.md` | Checking shared scope, evidence, comparison, or permission rules; generated from the canonical operations guide |
88
122
  | `references/orchestration.md` | Planning a multi-step or recurring workflow (baseline, weekly review, content-gap analysis) |
89
123
  | `references/regression-playbook.md` | A query lost a mention (primary) or a citation (secondary) and you need to triage and respond |
90
124
  | `references/aeo-discovery.md` | Expanding a tracked-query basket, auditing competitive surface, or responding to `aeo-discover-probe.completed` |
@@ -92,4 +126,4 @@ Detailed playbooks live alongside this file. Read them on demand when the task m
92
126
  | `references/reporting.md` | Producing a client-facing weekly or monthly summary |
93
127
  | `references/wordpress-elementor-mcp.md` | Editing WordPress pages with the Elementor MCP integration |
94
128
 
95
- Aero (canonry's built-in agent) additionally exposes `list_skill_docs` / `read_skill_doc` MCP tools that walk this directory programmatically. External agents (Claude Code, Codex) should `Read` the files directly.
129
+ Aero (canonry's built-in agent) exposes `list_skill_docs` / `read_skill_doc` tools that walk this directory programmatically. External agents (Claude Code, Codex) can read the files directly.
@@ -0,0 +1,231 @@
1
+ ---
2
+ name: agent-operations
3
+ description: Shared Canonry vocabulary, evidence scope, comparison rules, and authority boundaries. Read when interpreting unfamiliar data or checking an operation.
4
+ ---
5
+
6
+ <!-- Generated from docs/agent-operations/v1.md by pnpm guide:sync. Do not edit. -->
7
+
8
+ > **Built-in Aero:** your available `canonry_*` tools are already loaded, and
9
+ > you read this guide through `read_skill_doc` (slug `agent-operations`). Your
10
+ > catalog does not include `canonry_help` or `canonry_load_toolkit`; the
11
+ > connection and navigation steps below are for external MCP hosts. Your
12
+ > project-scoped tools use the current session's project. Dashboard selections
13
+ > are not passed to chat: resolve the requested Property, market, filters, or
14
+ > page before making a scoped claim. The `portfolio-analysis` and `site-health`
15
+ > skill docs cover those investigations for Simple and Advanced portfolios.
16
+
17
+ # Canonry Operations Guide v1
18
+
19
+ Canonry is an agent-first AI visibility platform. MCP is the universal entry
20
+ point for connected agents. Host-native skills are optional upgrades, not a
21
+ prerequisite or a permission mechanism.
22
+
23
+ ## Connect and choose a route
24
+
25
+ Read the initialization guidance, then call `canonry_help` with an `intent`:
26
+ `status`, `diagnose`, `operations`, `prospecting`, `measurement`, `integrations`,
27
+ `reports`, or a short task
28
+ description. Select an accessible project with `canonry_projects_list` before
29
+ using its exact name in project tools. Inspect each listed tool's input schema;
30
+ help suggests tool names, not invented arguments or authorization.
31
+
32
+ Help returns a versioned, compact route: connection `mode`, available `next`
33
+ tools, workflow guidance, approval boundaries, and this guide's URL. It performs
34
+ no provider calls, reads no project data, and changes no permissions.
35
+ `next` lists stored reads. Optional `actions` lists loaded tools for work that
36
+ requires approval; listing an action does not authorize or execute it.
37
+ `includeCatalog: true` additionally returns toolkit details when needed.
38
+
39
+ Hosted connections use a fixed catalog. Help only suggests tools offered by that
40
+ connection; it never tells a hosted agent to dynamically load a toolkit. A
41
+ progressive local stdio connection may return `loadToolkits`: call
42
+ `canonry_load_toolkit` with one returned name, await it, then call help again.
43
+ Loading only changes local tool discovery, never server authority.
44
+
45
+ The optional `canonry://agent-operations/v1` MCP resource contains this same
46
+ guide. If the host cannot read resources or open links, continue through help.
47
+ Do not install a plugin, local runtime, or skill merely to use connected MCP.
48
+ An installed Codex or Claude Canonry skill contains a generated copy of this
49
+ guide plus links to host-native references. It does not replace runtime help.
50
+
51
+ ## Vocabulary and evidence
52
+
53
+ - **Mentioned** means the brand appears in answer text. **Cited** means its
54
+ domain appears in source links. Either, both, or neither can occur; never
55
+ compute one signal from the other.
56
+ - `answerMentioned: null` means not checked, not false. Missing runs and empty
57
+ populations mean no measurement, not zero visibility.
58
+ - Preserve project, time window, provider, requested/served model, location,
59
+ sample size, and query class when comparing evidence. Use server-returned
60
+ metrics; do not invent a score from incompatible populations.
61
+ - Simple projects and Advanced portfolios share the workflow. For Advanced
62
+ results, preserve Property, Target, market, plan revision, and class scope.
63
+ Groups organize navigation; do not infer an unrequested fan-out.
64
+ - Research is isolated evidence, not tracked measurement. A probe still spends
65
+ quota and persists evidence but is excluded from normal tracking metrics.
66
+
67
+ ## Workflows
68
+
69
+ **Status:** read the stored overview and freshness first. Say when evidence is
70
+ missing instead of silently creating it.
71
+
72
+ **Diagnose:** inspect stored history and comparable evidence. Explain what
73
+ changed separately from why it might have changed. A hypothesis is not a
74
+ measured cause. Propose bounded verification if stored evidence is insufficient.
75
+
76
+ **Prospecting:** generate a one-shot company snapshot without creating a project.
77
+ Inspect stored provider settings first. Agree on the company, domain, selected
78
+ providers, and queries before starting the quota-spending snapshot action.
79
+ Browser-only selection requires manual queries. Progressive stdio help offers
80
+ the discovery toolkit when this connection permits snapshots; load it, then
81
+ call help again. Fixed catalogs offer only already available actions. Read-only
82
+ and restricted connections must not bypass missing snapshot access.
83
+
84
+ **Measurement:** inspect the existing setup and results before proposing edits.
85
+ Keep research, query tracking, plan publication, and sweep execution separate.
86
+ For direct research, submit the final editable query text in one context. For a
87
+ reviewed batch, submit each explicit destination with its final text and one
88
+ idempotency key. Pattern substitution happens in the client before either
89
+ request; choosing a market or Property records a destination only and never
90
+ rewrites a query or creates an automatic fan-out. `research.run` does not
91
+ authorize saving patterns, changing tracking, publishing plans, or settings.
92
+ Use a supported preview where available, inspect its exact destination and
93
+ revision, then seek approval for the actual change. A preview may itself require
94
+ write permission; never treat a dry-run flag as a universal safety guarantee.
95
+
96
+ **Integrations:** inspect stored connection state and snapshot freshness first.
97
+ Provider configuration evidence does not prove a browser event fired or a
98
+ conversion was recorded. Connection, resource selection, refresh/sync, and live
99
+ reads are separate actions. Credentials belong in the operator's secure setup
100
+ flow, never in chat, tool arguments, reports, or public guidance.
101
+
102
+ **Reports:** use saved evidence for the requested period and scope. Keep mention
103
+ and citation signals separate, include dates and sample sizes, and state missing
104
+ or stale inputs. For Advanced Property mention rankings, use
105
+ `canonry_measurement_portfolio_summary` and its `mentionRanking.strongest`,
106
+ `.weakest`, and `.excluded` lists. It defaults to non-brand questions; state the
107
+ returned class and report branded results separately. An unavailable portfolio
108
+ aggregate does not invalidate available Property mention rates. Flag excluded
109
+ Properties individually; do not silently replace mention ranking with citation
110
+ ranking. Keep sample sizes and ties visible. Preparing a report does not
111
+ authorize new measurement.
112
+
113
+ ## Authority and approval
114
+
115
+ ### Agent operations
116
+
117
+ Use `canonry_key_self` (CLI `canonry key whoami --format json`) to inspect the
118
+ current credential's scopes, project boundary, and host-derived `operator`
119
+ authority without exposing its token. Missing `operator` means unapproved.
120
+ `canonry_settings_get` and
121
+ `canonry_telemetry_get` describe the connected server, not the agent's local
122
+ machine. Telemetry reports configured preference, effective state, and any
123
+ environment override; inspecting status never creates an anonymous identifier.
124
+ After approval, `canonry_telemetry_update` changes that preference and
125
+ `canonry_provider_settings_update` changes an already-configured provider's
126
+ model/quota. Both require `settings.write`; neither accepts credentials.
127
+ Server telemetry reads and updates additionally require operator authority.
128
+ Ordinary audit-history reads omit internal telemetry events and their state.
129
+
130
+ Operator authority is deny-by-default and separate from customer admin roles.
131
+ The deployment owner must approve a dedicated, instance-wide API key's ID in
132
+ the server environment variable `CANONRY_OPERATOR_KEY_IDS` (comma-separated IDs),
133
+ then restart the server. Empty/unset approves nobody; wildcards are invalid.
134
+ Keep the bearer private to internal operators; never approve a customer-held or
135
+ shared proxy/bootstrap key. Use `logs.read` for read-only diagnostics, adding
136
+ `settings.write` only when telemetry control is required. Ordinary key creation,
137
+ account roles, OAuth consent, and caller headers cannot grant operator status.
138
+ Revoking an approved key invalidates it immediately. Host enrollment is a trust
139
+ bootstrap step, intentionally unavailable through customer-facing APIs.
140
+ API, CLI, and MCP enforce the same boundary; MCP hides internal tools unless
141
+ the server confirms operator authority, including in explicit read-only mode.
142
+ Project analytics, research, and normal project permissions are unchanged.
143
+
144
+ `canonry_logs_list` reads bounded, redacted runtime events from both the
145
+ application logger and Fastify request/error logging. It requires an
146
+ instance-wide `logs.read` grant (or wildcard) and a host-approved direct bearer.
147
+ Browser sessions, OAuth/delegated credentials, customer admins, and project-scoped
148
+ keys cannot use it, even with a project filter or a matching allowlist ID.
149
+ A `logs.read`-only key is read-only automatically, without a
150
+ second `read` marker. Named `*.read` scopes cannot grant mutations; an explicit
151
+ write grant is needed and remains subject to its route gates. Returned messages
152
+ are sanitized and bounded; raw request or response bodies, headers, cookies,
153
+ provider payloads, and stacks are not
154
+ part of the queryable surface. The same secret-redaction policy runs before
155
+ console output and storage. Do not deliberately log secrets: redaction is a
156
+ defense in depth, not permission to put credentials into diagnostic strings.
157
+ Opaque escaped payloads containing secret assignments are omitted when safe
158
+ partial masking cannot be guaranteed; correlate their retained error codes and IDs.
159
+
160
+ File-backed hosts retain runtime logs in SQLite across restarts, bounded to
161
+ 10,000 events and seven days. In-memory hosts report `retention: "process"`.
162
+ Filter by `actor`, `requestId`, `runId`, `projectId`, `module`, `level`, or an
163
+ inclusive `since`/`until` interval. Keep filters unchanged when resuming an
164
+ opaque cursor; retention eviction can invalidate it. Inspect `retentionPolicy`,
165
+ `captureErrors`, `dropped`, `truncated`, and `retention` before drawing
166
+ conclusions. Missing logs are not proof that an action did not happen. Use
167
+ `canonry_project_history` or `canonry_history_global` for persistent audit events;
168
+ offset pages have deterministic ordering but are not snapshots of concurrent writes.
169
+
170
+ Audit `actor` comes from authenticated identity (`user:<id>` or `api-key:<id>`),
171
+ not a caller-supplied header. A delegated MCP credential records its originating
172
+ user as actor and the actual credential in `credentialId`. `requestId` correlates
173
+ HTTP events; `userAgent` and `actorSession` are bounded, untrusted client hints,
174
+ never identity or permission grants. Older audit rows are not backfilled with
175
+ identities the server cannot prove.
176
+
177
+ Both shipped HTTP hosts issue restart-safe UUID request IDs and return them in
178
+ `x-request-id`. Use that value to correlate a CLI/API failure with log entries;
179
+ HTTP diagnostics retain the method and route template, not raw URL parameters.
180
+ Request-bound loggers retain completion attribution, while generic background
181
+ continuations stop inheriting caller identity after the response completes.
182
+ Capture covers the owning server process after initialization, not arbitrary
183
+ console output, other worker processes, or host/container logs. Run one server
184
+ instance per process and database, as required by the single-tenant deployment
185
+ model; this is not a cross-tenant or distributed log collector.
186
+
187
+ For CLI use, settings reads are remote. Google setup and telemetry retain their
188
+ local defaults: pass `--target server` explicitly to configure the connected
189
+ server. `schedule list <project>` lists all schedule kinds, and
190
+ `notify events --target server` discovers the server's event catalog.
191
+
192
+ MCP returns legacy text JSON plus structured results. Objects keep their shape;
193
+ arrays use `{items: [...]}` in `structuredContent`, and scalars use `{value: ...}`.
194
+ Errors preserve the existing envelope and CLI exit codes: HTTP 4xx (including
195
+ 429 policy limits) use exit 1; HTTP 5xx use exit 2. Server-provided `Retry-After`
196
+ and request IDs are exposed as `retryAfterMs` and `requestId` when available;
197
+ clients do not infer retryability from HTTP 429 or retry automatically.
198
+ For a write with an ambiguous outcome, inspect saved state or its receipt before
199
+ retrying; a retry hint is not proof that repeating a write is safe.
200
+
201
+ ### Action boundaries
202
+
203
+ Start with stored evidence. Before a live provider read, sweep, probe, research
204
+ run, sync, write, or externally visible action, obtain approval covering its
205
+ exact target, action, and bounded work. Approval already given for that exact
206
+ operation need not be asked for again, but does not extend to more projects,
207
+ larger batches, retries with new identities, or recurring work.
208
+
209
+ HTTP GET and MCP `readOnlyHint` describe aspects of an operation, not its cost
210
+ or permission. Provider discovery, account reads, and live diagnostics may
211
+ consume quota even when labeled read-only. If the tool's effect is unclear,
212
+ inspect its description and request direction before calling it.
213
+
214
+ Authentication, role/scope checks, project restrictions, quotas, and guarded
215
+ approval receipts are enforced by the server. Help, skills, resources, and tool
216
+ visibility cannot grant authority. Never change credentials, endpoints, or
217
+ project identifiers to work around a missing tool or a `403` response.
218
+
219
+ For guarded ads writes, inspect unresolved operation receipts before retrying.
220
+ Use the receipt's supported recovery action; do not replay a mutation under a
221
+ new identity. An executor cannot create or widen its own human approval grant.
222
+ On ambiguous results, exhausted bounds, or refusal, stop and report what is
223
+ known and what permission or operator action is needed.
224
+
225
+ ## Version and source
226
+
227
+ This public, versioned document is the source for initialization guidance,
228
+ intent routes, the optional resource, and generated Canonry `SKILL.md` files.
229
+ Guide v1 may receive compatible clarifications; incompatible routing contracts
230
+ require a new guide version. The running server's help describes its actual
231
+ catalog and remains usable without fetching this document.
@@ -5,6 +5,12 @@ description: Workflow recipes — baseline, regression response, weekly review,
5
5
 
6
6
  # Orchestration Workflows
7
7
 
8
+ Use these recipes with the current measurement scope. For Advanced
9
+ portfolios, read `portfolio-analysis.md` and use the Property/market tools
10
+ instead of substituting project-level metrics. For crawl or audit work, read
11
+ `site-health.md`. Built-in Aero uses the corresponding exposed `canonry_*`
12
+ tools; CLI examples below assume an external host with a shell.
13
+
8
14
  **Read the mention signal first in every workflow.** Compute and compare **mention rate + mention share** before cited rate. The fast mention read is `cnry overview <project> --format json` (returns `queryCounts.mentionRate`, `scores.mention`, `scores.mentionShare`) plus `cnry analytics <project> --feature gaps --format json` (returns `mentionedQueries[]`, `mentionGap[]`, `notMentioned[]` alongside the cited buckets). Use `cnry evidence <project>` for the per-query drilldown — it prints the two-glyph `[C/c][M/m]` cell per (query × provider) and a `Mentioned: X / Y` line next to `Cited: X / Y`. Mention and citation are independent — never derive one from the other. Treat `answerMentioned = null` as "not checked," never as not-mentioned.
9
15
 
10
16
  ## Workflow 1: New Client Baseline
@@ -17,7 +23,7 @@ Steps:
17
23
  3. With explicit operator approval for the crawl and persisted run, `cnry technical-aeo run <project> --wait`, then `cnry technical-aeo score <project> --format json` for site readiness. Use `cnry site-health overview <project> --format json` only to add crawl metadata (root, completeness, budgets, and termination); it never replaces the score. The crawl discovers the in-scope URL inventory from the root, sitemaps, and internal links. The default page budget is 1,000; the edge budget is unset by default and the crawl engine derives it from the page count, so `--max-edges` sets a ceiling rather than lifting one. Use `--max-pages`, `--max-edges`, or `--max-depth` to tighten them. Dead-link checks remain off unless `--check-dead-links` is explicit. For architecture investigation, use bounded Site Health subgraph/path/changes reads rather than attempting to load the visualization graph. Treat `countAccuracy: "lower-bound"` subgraph counts as minimums, and qualify an incomplete path's unreachable/truncated result with `complete: false` plus `termination`; neither is a site-wide conclusion. Persists to the dashboard and is trendable via `cnry technical-aeo trend <project>`.
18
24
  4. Identify top 3 gaps — lead with `mentionGap[]` / `notMentioned[]` (where competitors are named and you aren't), then the cited gaps with fixable site issues.
19
25
  5. Generate onboarding report with baseline + action plan
20
- 6. Store baseline metrics in memory (include mention rate + mention share, not just cited rate)
26
+ 6. Read baselines back from stored runs; remember only operator-confirmed context that Canonry cannot observe.
21
27
 
22
28
  ## Workflow 2: Regression Response
23
29
 
@@ -28,11 +34,11 @@ Steps:
28
34
  2. `cnry history <project>` → trend for affected query
29
35
  3. Check competitor mention share BEFORE cited displacement: did a competitor take the **mention** share you lost (`mentionGap[]`)? Only then ask whether a competitor gained the **citation** you lost.
30
36
  4. Check indexing: `cnry google coverage <project>` → is the page still indexed? (a deindexed/thin page starves both signals)
31
- 5. Audit the page: `npx @canonry/aeo-audit@4 "<page-url>" --format json`
37
+ 5. Read the page's persisted audit with `canonry_site_health_page_audit`. Propose a bounded new audit only if the stored evidence cannot answer the question.
32
38
  6. Diagnose cause: indexing issue / content issue / competitive displacement (mention-share loss first, citation loss second)
33
39
  7. Recommend fix with evidence — lead with what restores the mention
34
40
  8. If content fix: generate diff (schema, llms.txt, or content changes)
35
- 9. Update memory with regression event + diagnosis (record which signal regressed: mention, citation, or both)
41
+ 9. Ground the diagnosis in stored run and page evidence; do not save metrics or unvalidated causes as durable facts.
36
42
 
37
43
  **Want to verify the regression is real / reproducible before reporting?**
38
44
  Propose the exact provider/query and get explicit approval, then use a probe
@@ -50,7 +56,7 @@ Trigger: Scheduled (weekly, or on-demand)
50
56
 
51
57
  Steps:
52
58
  1. `cnry overview <project> --format json` → current metrics, mention first (`queryCounts.mentionRate`, `scores.mention`, `scores.mentionShare`); `cnry analytics <project> --feature gaps --format json` for the mention gaps; `cnry evidence <project> --format json` for the per-query `[C/c][M/m]` drilldown
53
- 2. Compare to baseline/prior week from memory — mention rate + mention share first, cited rate second
59
+ 2. Compare compatible stored periods/runs using the reporting or portfolio playbook — mention rate + mention share first, cited rate second
54
60
  3. Compute deltas: mentions gained/lost/stable (primary), then citations gained/lost/stable (secondary)
55
61
  4. Flag any new regressions not yet addressed (lead with lost mentions)
56
62
  5. Check competitor movement — mention share swing first, then cited-domain displacement
@@ -64,6 +70,6 @@ Steps:
64
70
  1. `cnry overview <project> --format json` + `cnry analytics <project> --feature gaps --format json` → confirm the gap, mention first: is the query in `notMentioned[]` (not named at all) or `mentionGap[]` (a competitor is named, you aren't)? Then `cnry evidence <project>` for the per-query `[C/c][M/m]` cell to see whether you also lack the citation. Mention gap leads the diagnosis; the missing citation is the secondary lens.
65
71
  2. Check if a relevant page exists on the domain
66
72
  3. If no page: recommend content creation (topic, target queries) — give the engine a reason to name you
67
- 4. If page exists: `npx @canonry/aeo-audit@4 "<page-url>"` diagnose why neither mentioned nor cited
73
+ 4. If page exists, inspect its persisted page audit and answer evidence. Treat a technical finding as a possible contributor, not proof of why an answer engine omitted the brand.
68
74
  5. Check schema completeness, llms.txt coverage, indexing status
69
75
  6. Generate prioritized fix list — fixes that earn the mention first, then the citation
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: portfolio-analysis
3
+ description: Interpret Simple and Advanced portfolios, compare Properties and markets, trace answer evidence, and qualify missing or incompatible measurements.
4
+ ---
5
+
6
+ # Portfolio analysis
7
+
8
+ ## Establish the measurement
9
+
10
+ Use `canonry_project_get` and `canonry_measurement_plan_get` to establish the
11
+ project and active plan. A Simple portfolio uses the standard project flow;
12
+ an Advanced portfolio uses a versioned measurement plan. "Multiportfolio"
13
+ may mean Properties within one project or several projects. Built-in Aero's
14
+ project-scoped tools operate on the current session's project. Do not present
15
+ one project's results as an account-wide comparison.
16
+
17
+ Resolve Property and market names to returned stable keys. A Property is
18
+ addressed by `targetKey`; a reporting group by `groupKey`. Preserve these
19
+ keys alongside labels, plan revision, displayed run, provider, requested and
20
+ served model when available, location, date window, and query class. A market
21
+ group and provider location are distinct scopes. Use only the filters exposed
22
+ by each tool; never invent a model or market parameter.
23
+
24
+ The chat does not inherit dashboard selections. Resolve names and URLs from
25
+ the request; ask for the selection when a reference such as "this market"
26
+ cannot be resolved. For an unqualified portfolio ranking, use non-brand
27
+ questions and state the returned scope. Keep branded recall separate. An
28
+ explicit request for all classes permits a combined coverage read, not an
29
+ invented combined share-of-voice ratio.
30
+
31
+ ## Choose the read
32
+
33
+ | Question | Stored evidence |
34
+ |---|---|
35
+ | How is a Simple portfolio doing? | `canonry_project_overview`, `canonry_visibility_stats`; preserve sample sizes and returned class |
36
+ | Which Advanced Properties are strongest or weakest? | `canonry_measurement_portfolio_summary`; use `mentionRanking.strongest`, `.weakest`, and `.excluded` |
37
+ | What is measured for one Property or market? | `canonry_measurement_overview` with `scope: property` / `targetKey` or `scope: group` / `groupKey` |
38
+ | Which questions explain a Property's gaps? | `canonry_measurement_property_questions`, then `canonry_measurement_question_result` with a returned `resultId` |
39
+ | What was mentioned or linked in individual answers? | `canonry_measurement_property_evidence` with `shape: answers` |
40
+ | Who appeared instead? | `canonry_measurement_property_competitors`; report stored replacement names as observations |
41
+ | Did performance change? | `canonry_measurement_changes` for Advanced; `canonry_visibility_compare` for Simple month comparisons |
42
+ | Can these results support a conclusion? | `canonry_measurement_data_quality` for Advanced completeness, capture, retrieval, and comparability |
43
+
44
+ For schema-v1 plans use `canonry_measurement_report` pinned to the requested
45
+ revision. Do not assume v2 Property/question-class reads are supported or
46
+ change the plan to make a read work.
47
+
48
+ ## Interpret the denominator
49
+
50
+ - Quote the server's numerator and denominator with a rate. Mention and
51
+ citation are independent signals; `mentioned: null` or
52
+ `answerMentioned: null` means unchecked, not a measured miss.
53
+ - An empty result with `measurement.state: not_measured` means no
54
+ measurement. An unavailable aggregate does not invalidate available
55
+ Property metrics. Report ranked Properties and list excluded Properties
56
+ with the returned reasons, including ambiguous identity.
57
+ - `mentionRanking` ranks all eligible Properties before applying its limit.
58
+ Do not recompute a best/worst ranking from one overview page. Tied rates
59
+ are ties; stable label/key order does not establish a unique winner or
60
+ statistical significance.
61
+ - Markets can share Properties and do not sum to a portfolio total. Do not
62
+ average Property percentages, add overlapping market counts, or substitute
63
+ project-brand performance for an individual Property's performance.
64
+ - `shape: sources` returns cited URLs. Answers without citations are absent
65
+ from that shape, so source-row counts cannot measure answer coverage or
66
+ prove the absence of mentions. Use `shape: answers` to explain gaps.
67
+ - Overview's omitted query class combines classes; portfolio summary defaults
68
+ to non-brand. Pass an explicit class for a sequence of comparable reads
69
+ and report what the response actually served.
70
+
71
+ ## Compare and drill down safely
72
+
73
+ A ranking describes one snapshot. Use the comparison tool's compatibility
74
+ decision before describing a trend; a plan revision, model, assignment, or
75
+ capture change can make raw rates incomparable. Report an unavailable or
76
+ incompatible comparison with its reason instead of subtracting rates by hand.
77
+ For Simple month comparisons, honor the returned interval, continuity,
78
+ `within-noise`, and low-sample qualifications from the reporting playbook.
79
+
80
+ Carry the displayed run and the supported filters into follow-up reads.
81
+ Reuse cursors unchanged with the same scope, class, sort, shape, and filters.
82
+ A revision or evidence change can invalidate a cursor; restart that read
83
+ without merging pages from incompatible snapshots. Overview search narrows
84
+ displayed rows without changing metric denominators.
85
+
86
+ Tool output can be trimmed. Inspect `__truncated`, `__omittedRows`, and
87
+ `__omittedRowsByField` as well as API pagination metadata. Request a smaller
88
+ page or narrower scope before treating the returned rows as exhaustive.
89
+
90
+ Lead the answer with the scoped result, give numerator/denominator and the
91
+ evidence explaining it, state missing data or comparison limits, then suggest
92
+ an action supported by that evidence. Reads do not authorize a new sweep,
93
+ probe, draft publication, or recurring measurement.
@@ -7,7 +7,16 @@ description: Weekly and monthly report templates with metric tables, regression/
7
7
 
8
8
  ## Month-over-month AEO (do this right)
9
9
 
10
- For ANY month-over-month AEO claim, use `cnry visibility-compare <project> --from <YYYY-MM> --to <YYYY-MM>` — never diff two `visibility-stats --month` calls by hand. It returns the statistically honest comparison. **Share of voice is less exposed to an engine's broad naming propensity than an absolute rate**, and is computed over non-brand queries only (see the branded caveat below), but it does **not** bypass model continuity. The comparison is restricted to the query/provider PAIRS present in BOTH months, then to providers with one known, identical configured model id in both months. Every figure carries a Wilson interval and a `verdict`:
10
+ For Advanced Property or market reports, read `portfolio-analysis.md` first
11
+ and use `canonry_measurement_changes` for compatible stored-run comparisons.
12
+ Do not substitute a project-wide month comparison for Property-scoped data.
13
+ For Site Health reports, read `site-health.md` and keep crawl and audit
14
+ provenance separate from answer-visibility periods.
15
+
16
+ For Simple month-over-month AEO claims, use `canonry_visibility_compare`
17
+ (CLI: `cnry visibility-compare <project> --from <YYYY-MM> --to <YYYY-MM>`),
18
+ never diff two `visibility-stats --month` calls by hand. It returns the
19
+ statistically honest comparison. **Share of voice is less exposed to an engine's broad naming propensity than an absolute rate**, and is computed over non-brand queries only (see the branded caveat below), but it does **not** bypass model continuity. The comparison is restricted to the query/provider PAIRS present in BOTH months, then to providers with one known, identical configured model id in both months. Every figure carries a Wilson interval and a `verdict`:
11
20
 
12
21
  - **`within-noise`** — the periods' intervals overlap. **No confirmed change; never report it as a rise or a decline.**
13
22
  - **`moved`** — disjoint intervals; a real directional move (the point sign is the direction).
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: site-health
3
+ description: Diagnose Site Health scores, page findings, crawl coverage, internal links, and scan changes while preserving run provenance and incomplete-data limits.
4
+ ---
5
+
6
+ # Site Health diagnosis
7
+
8
+ Site Health is the product label for the `technical-aeo` audit and crawl
9
+ surface. It measures technical readiness. Mention coverage and citation
10
+ coverage come from answer-engine measurements; neither is derived from an
11
+ audit score, link score, or graph position.
12
+
13
+ ## Start with stored evidence
14
+
15
+ Read `canonry_site_health_overview` for the selected or latest crawl's root,
16
+ run identity, completeness, counts, budgets, versions, termination, and
17
+ dead-link check state. Pair it with `canonry_technical_aeo_score` for the
18
+ aggregate score, factor distributions, issues, and prioritized fixes. Pin
19
+ the score and subsequent reads to the returned run when available. Overview
20
+ is crawl metadata, not the scorecard. Older scorecard-only audits can lack
21
+ a graph; report the available scores and missing crawl evidence separately.
22
+
23
+ Use `canonry_technical_aeo_pages` for low-scoring or failed pages and
24
+ `canonry_site_health_page_audit` for one page's exact factor scores, finding
25
+ codes/messages, recommendations, and critical defects. Prefer a returned
26
+ `nodeKey`; use the exact URL when no node key is available. The chat does not
27
+ receive the selected graph node, so resolve the requested page or ask for it.
28
+
29
+ ## Choose a bounded investigation
30
+
31
+ | Question | Read |
32
+ |---|---|
33
+ | Which URLs were discovered and audited? | `canonry_technical_aeo_crawl_pages`; filter audit/fetch/indexability state and follow its cursor |
34
+ | How is the site organized? | `canonry_technical_aeo_structure` for one path level |
35
+ | What links to/from this page? | `canonry_technical_aeo_link_neighbors`; inbound and outbound truncation are independent |
36
+ | What is around this page? | `canonry_site_health_subgraph`; refocus or expand only as needed |
37
+ | Can the root reach this page? | `canonry_site_health_path` for a directed followable path |
38
+ | Which editorial or template links exist? | `canonry_technical_aeo_internal_links` with supported filters |
39
+ | What changed between scans? | `canonry_site_health_changes` for compatible complete snapshots |
40
+ | Were broken links checked? | `canonry_technical_aeo_dead_links` |
41
+ | How have scores moved? | `canonry_technical_aeo_trend`, then inspect the relevant runs and coverage |
42
+
43
+ Use semantic reads rather than requesting the full interactive graph or
44
+ inferring importance from visualization coordinates. Defaults for subgraphs
45
+ are 25 nodes and 50 edges; a bounded neighborhood is not the whole site.
46
+
47
+ ## Interpret states before findings
48
+
49
+ - `hasData: false`, no crawl, details unavailable, page not found, and page
50
+ not audited are different states. None means a zero score or a passing
51
+ page. `scores-only` permits discussing scores but not inventing findings.
52
+ - `complete: false` and `termination` qualify conclusions. A budget-limited
53
+ scan does not establish site-wide coverage. Raw found/checked/failed
54
+ counts are not a completion percentage when total discovery is unknown.
55
+ - Subgraph `countAccuracy: lower-bound` means counts are minimums. An
56
+ unreachable or truncated path in an incomplete crawl does not prove a
57
+ site-wide orphan. Absence from a bounded result is not absence from the site.
58
+ - Crawler-derived indexability is technical eligibility, not Google index
59
+ coverage. Verify Google indexing with its own stored integration evidence.
60
+ - Link score indicates structural importance, not an audit failure. Pair
61
+ important pages with their actual audit findings when prioritizing fixes.
62
+ - Dead-link checks are opt-in. `disabled` means unchecked, not zero broken
63
+ links. A listed dead link requires a recorded HTTP 4xx/5xx. Fetch failures
64
+ such as timeouts can be `unverified`; do not label them broken URLs.
65
+ - Link template classification carries `templateSource` and scan-level
66
+ `templateDetection`. An empty content-only result under unmeasured
67
+ classification cannot establish that the site has no editorial links.
68
+ Different classification rules are not equivalent measurements.
69
+
70
+ ## Compare scans and prioritize
71
+
72
+ Use the changes tool's resolved run IDs and filters; keep them fixed when
73
+ paging. Its first page carries the exact summary; continuation pages omit
74
+ summary/total. Retain that first summary and do not treat its absence on later
75
+ pages as zero. Inspect API and Aero truncation markers before claiming a
76
+ complete list. Reject/refusal states do not justify joining partial or
77
+ incompatible scans manually.
78
+
79
+ Before attributing a score delta to fixes, check root/scope, completeness,
80
+ audited-page population, effective budgets, and scoring/crawl versions. A
81
+ changed sample can move an aggregate without any page improving. Explain
82
+ page-level before/after evidence where available and qualify remaining gaps.
83
+
84
+ For Simple portfolios, relate findings to the requested site or pages. For
85
+ Advanced portfolios, read `portfolio-analysis` and resolve each Property's
86
+ Target/URL scope from its plan. The project-wide score is not a Property
87
+ score. Label a filtered page sample as such, preserve the Property and market
88
+ context, and do not invent a Property aggregate. Shared paths can affect
89
+ multiple Properties; avoid counting the same finding as independent proof
90
+ for each one.
91
+
92
+ Rank persisted critical defects and fixes using severity and affected-page
93
+ evidence, with business or link importance where available. State the run,
94
+ scope, finding, affected page(s), and supported next step. A technical issue
95
+ can be a hypothesis for an AI-visibility gap, but the crawl alone cannot prove
96
+ why an answer engine omitted a Property. Join the corresponding answer
97
+ evidence before making that connection.
98
+
99
+ Read existing data first. If absent or stale, propose an explicitly bounded
100
+ `canonry_technical_aeo_run` when a new audit is needed. Existing authorization
101
+ for that run remains valid; a diagnostic question alone does not authorize
102
+ a crawl. Dead-link checks remain off unless requested. After an approved
103
+ run, follow its returned ID with `canonry_run_get`, then inspect that run's
104
+ crawl and score rather than silently switching to another scan.
@@ -7,6 +7,11 @@ description: Aero's persona, values, and voice — context-agnostic identity tha
7
7
 
8
8
  You are **Aero** — an AEO analyst. You help operators understand whether AI answer engines NAME their brand (mention) and, secondarily, whether they CITE their domain, and you act decisively on what the data shows. Mention is the primary gauge; citation is the secondary signal. The two are independent — never compute one from the other.
9
9
 
10
+ For multi-property portfolios, keep each Property's identity and measurement
11
+ scope intact. For Site Health, explain the stored audit findings and crawl
12
+ limits first. A technical score does not measure AI visibility, and a crawl
13
+ finding alone does not prove why an answer engine omitted a brand.
14
+
10
15
  ## Values
11
16
 
12
17
  - **Evidence over opinion.** Numbers before interpretation. "ChatGPT stopped mentioning you for 'roof repair phoenix' between March 28 and April 2, and your mention share fell from 50% to 0%" beats "your visibility decreased" — then note the lost citation second.