@canonry/canonry 7.87.0 → 7.87.2
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.
- package/assets/agent-workspace/skills/aero/references/ai-traffic-tracking.md +6 -1
- package/assets/agent-workspace/skills/canonry/references/ai-traffic-tracking.md +6 -1
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +5 -1
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +27 -11
- package/dist/{backfill-LIMS34H6.js → backfill-6AYHWEQX.js} +5 -5
- package/dist/{bootstrap-AZYQXBHN.js → bootstrap-27NOBWTP.js} +1 -1
- package/dist/{chunk-YKB67YKH.js → chunk-3FHBPJ5R.js} +2 -2
- package/dist/{chunk-EQGCGZZY.js → chunk-AI75KS7G.js} +2183 -2076
- package/dist/{chunk-O26FQ7RI.js → chunk-AYYZ4HKJ.js} +30 -0
- package/dist/{chunk-L5NMS7AU.js → chunk-BVJA3TV2.js} +3 -3
- package/dist/{chunk-D5V6YQXA.js → chunk-IE4D47JE.js} +4 -4
- package/dist/{chunk-OJKWT6U6.js → chunk-IVGVPPQT.js} +8 -8
- package/dist/{chunk-JGGDENAA.js → chunk-LYTBHEID.js} +31 -31
- package/dist/{chunk-VDYXB6SV.js → chunk-POMLL2OZ.js} +83 -12
- package/dist/{chunk-KOBOKZXF.js → chunk-T2MGGW6Y.js} +2 -2
- package/dist/{chunk-EJZHL67Y.js → chunk-TFB2S6TQ.js} +1 -1
- package/dist/{chunk-ITOK75B6.js → chunk-ZCNKGBIV.js} +2 -2
- package/dist/{chunk-G44S34CE.js → chunk-ZJVQ72VC.js} +1 -1
- package/dist/{cli-commands-J6KWSWIS.js → cli-commands-H7BFVUGC.js} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{dashboard-5QMYF4ZP.js → dashboard-KT2ACPI5.js} +3 -3
- package/dist/{demo-KGQL5EJM.js → demo-LWSLULEZ.js} +1 -1
- package/dist/{demo-server-ERIR2T2N.js → demo-server-UENMDVMG.js} +5 -5
- package/dist/index.d.ts +202 -67
- package/dist/index.js +9 -9
- package/dist/{init-HOBW5K2Q.js → init-TF3OPCEC.js} +2 -2
- package/dist/{intelligence-service-2AH42Y4Q.js → intelligence-service-LEH5UVIC.js} +4 -4
- package/dist/{serve-WF5ZXWW6.js → serve-LLIUILD2.js} +10 -10
- package/dist/{session-HEDEP77R.js → session-2NQKSF2N.js} +5 -5
- package/dist/{src-SJYGA7NH.js → src-JQYZ2TP6.js} +3 -1
- package/dist/{tools-KYG67FBW.js → tools-UPJRW4DN.js} +4 -4
- package/dist/{traffic-B7Q4WPOV.js → traffic-GWBZKYR5.js} +1 -1
- package/package.json +1 -1
|
@@ -31,7 +31,12 @@ rarely. Report every step separately; never pool them.
|
|
|
31
31
|
|
|
32
32
|
Server-side hits are requests and GA4 counts sessions, and each instrument
|
|
33
33
|
misses some visits the other sees, so the two never match exactly. Compare
|
|
34
|
-
their trend, not their totals.
|
|
34
|
+
their trend, not their totals. Server-side arrivals stored before Canonry
|
|
35
|
+
7.87.2 also counted a visitor's later pages, assets and API calls that carried
|
|
36
|
+
the landing page's utm, about one per minute of the visit, so those hours can
|
|
37
|
+
read several times high and cannot be corrected. Never read a trend across
|
|
38
|
+
that upgrade; for earlier hours quote GA4, or AI visitor journeys where they
|
|
39
|
+
exist.
|
|
35
40
|
|
|
36
41
|
## Check the instrument before you report a zero
|
|
37
42
|
|
|
@@ -24,7 +24,12 @@ rarely. Report every step separately; never pool them.
|
|
|
24
24
|
|
|
25
25
|
Server-side hits are requests and GA4 counts sessions, and each instrument
|
|
26
26
|
misses some visits the other sees, so the two never match exactly. Compare
|
|
27
|
-
their trend, not their totals.
|
|
27
|
+
their trend, not their totals. Server-side arrivals stored before Canonry
|
|
28
|
+
7.87.2 also counted a visitor's later pages, assets and API calls that carried
|
|
29
|
+
the landing page's utm, about one per minute of the visit, so those hours can
|
|
30
|
+
read several times high and cannot be corrected. Never read a trend across
|
|
31
|
+
that upgrade; for earlier hours quote GA4, or AI visitor journeys where they
|
|
32
|
+
exist.
|
|
28
33
|
|
|
29
34
|
## Check the instrument before you report a zero
|
|
30
35
|
|
|
@@ -1054,7 +1054,8 @@ more than 1,000 messages remain afterwards and names the cause. After
|
|
|
1054
1054
|
`deadline` or `batch-cap` the drain hit its limit: if the operator approves a
|
|
1055
1055
|
manual drain, run a manual sync, and if the backlog recurs, get approval to
|
|
1056
1056
|
shorten the schedule interval or raise the time limit. After `empty-pulls`
|
|
1057
|
-
Cloudflare still counted messages it would not return
|
|
1057
|
+
Cloudflare still counted messages it would not return, even after waiting
|
|
1058
|
+
between pulls; later syncs pull them.
|
|
1058
1059
|
|
|
1059
1060
|
Read the [server-side traffic guide](server-side-traffic.md) for token safety,
|
|
1060
1061
|
route checks, activation order, smoke tests, rollback, and troubleshooting.
|
|
@@ -1103,6 +1104,9 @@ operators, crawled paths, referral products, landing paths, daily history, and
|
|
|
1103
1104
|
equal prior-window changes. It does not start a sync or provider work. The
|
|
1104
1105
|
scope is project-wide for Simple and Advanced portfolios; there is no Property,
|
|
1105
1106
|
Target, or market attribution. Server sessions and GA sessions remain separate.
|
|
1107
|
+
Referral arrivals stored before Canonry 7.87.2 also counted a visitor's later
|
|
1108
|
+
same-site requests, so a window or prior window that reaches back before that
|
|
1109
|
+
upgrade reads high on that side.
|
|
1106
1110
|
|
|
1107
1111
|
## Google Analytics 4
|
|
1108
1112
|
|
|
@@ -33,10 +33,21 @@ Legitimate peaks can qualify and small automated bursts can escape the rule.
|
|
|
33
33
|
`--burst-threshold` changes the default 100-hit review trigger; the default has
|
|
34
34
|
not been calibrated against live traffic distributions.
|
|
35
35
|
|
|
36
|
-
Server counts
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
Server counts are arrivals, not GA sessions or verified people. A request
|
|
37
|
+
whose referer is outside the site (the AI engine's page, or none) is an
|
|
38
|
+
arrival; requests from one visitor (IP and user agent) to the same landing
|
|
39
|
+
page within a minute count once. A later page, asset or API call whose same-site
|
|
40
|
+
referer still carries the engine's utm belongs to that visitor's arrival from
|
|
41
|
+
the same engine for 30 days, in any sync or push, even one that reaches
|
|
42
|
+
Canonry before the landing does. It counts as the arrival only when the
|
|
43
|
+
visitor had none from that engine in those 30 days: a site whose pages a cache
|
|
44
|
+
serves before the logs see them shows nothing else, so a second click from
|
|
45
|
+
the same engine within 30 days is not counted there. Hours stored before Canonry 7.87.2
|
|
46
|
+
counted every later minute of a visit as another arrival and read high;
|
|
47
|
+
hourly rows keep no visitor, so they cannot be corrected. Normalized paths
|
|
48
|
+
can combine pages; multiple sources can overlap. No Property, Target or
|
|
49
|
+
market attribution is available. These limits apply equally to Simple and
|
|
50
|
+
Advanced portfolios.
|
|
40
51
|
|
|
41
52
|
The observed server/GA quotient, rounded to 2 decimals, uses
|
|
42
53
|
dimension-deduplicated GA sessions, but complete matching coverage and the GA
|
|
@@ -61,7 +72,8 @@ Four tables store the shared output from every adapter:
|
|
|
61
72
|
| `ai_user_fetch_likely_fake_hourly` | One row per `(project, source, hour, bot, first trust reason)` — requests that claimed a user-triggered agent but were judged likely fake |
|
|
62
73
|
| `agent_scanner_clients` | One row per `(project, source, client)` — the latest run of scanner probes from one IP (stored as a keyed hash), kept two days so a burst split across batches is still recognized |
|
|
63
74
|
| `journey_visitor_aliases` | One row per `(project, alias key)` — a visitor key found to be another visitor seen from a new IP (same AI-tagged page, same browser, within 5 seconds); requests under the alias key are kept under that visitor. Both are keyed hashes, never an IP |
|
|
64
|
-
| `ai_referral_events_hourly` | One row per `(project, source, hour, product, source_domain, evidence_type, landing_path, status)` — click-through arrivals rolled up by hour |
|
|
75
|
+
| `ai_referral_events_hourly` | One row per `(project, source, hour, product, source_domain, evidence_type, landing_path, status)` — click-through arrivals rolled up by hour; a visitor's later same-site requests are not arrivals |
|
|
76
|
+
| `ai_referral_visitors` | One row per `(project, source, visitor)`: each visitor's latest AI arrival (the visitor is a keyed hash of IP and user agent, never the address), kept 44 days so a later request of the same visit in a later batch is not counted again |
|
|
65
77
|
| `raw_event_samples` | Bounded forensic samples for spot checks. Source writes plus a startup/daily global sweep enforce 30-day retention; Cloudflare also uses a per-source, per-hour cap |
|
|
66
78
|
|
|
67
79
|
Each `traffic_sources` row is one server-log integration for a project.
|
|
@@ -947,10 +959,13 @@ usable value, receipts keep Cloudflare's 14-day maximum plus the margin.
|
|
|
947
959
|
Each Queue sync drains in batches of up to 100 messages for as long as
|
|
948
960
|
Cloudflare reports a backlog, up to a 4-minute time limit per sync
|
|
949
961
|
(`CANONRY_CLOUDFLARE_QUEUE_SYNC_DEADLINE_MS`, 30 seconds to 15 minutes) and a
|
|
950
|
-
300-pull safety cap. Cloudflare can return a partial or
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
962
|
+
300-pull safety cap. Cloudflare can return a partial or empty batch while a
|
|
963
|
+
backlog waits (on a busy Queue, about 3 pulls in 10 come back empty). While 100
|
|
964
|
+
or more messages wait, the sync waits after each empty pull, 0.5, 1, 2, 4 and
|
|
965
|
+
then 8 seconds, and pulls again. It stops when Cloudflare reports no backlog,
|
|
966
|
+
when every wait came back empty, when fewer than 100 messages wait and two
|
|
967
|
+
pulls in a row came back empty, or at the limit. If a pull fails after earlier
|
|
968
|
+
batches were saved, the run ends `partial` and keeps them.
|
|
954
969
|
|
|
955
970
|
Each sync run records what it did and why it stopped in `syncSummary`: pulls,
|
|
956
971
|
empty pulls, messages pulled and acknowledged, redelivered (duplicate) events,
|
|
@@ -964,8 +979,9 @@ the drain) and warns above that, with the cause taken from the last stop
|
|
|
964
979
|
reason. After `deadline` or `batch-cap` the drain hit its limit: shorten the
|
|
965
980
|
`traffic-sync` interval or raise the time limit, or messages will pass the
|
|
966
981
|
Queue's retention and be dropped. After `empty-pulls` or `unleased-only`
|
|
967
|
-
Cloudflare still counted messages it would not return
|
|
968
|
-
visible); later syncs pull them, and raising the time limit
|
|
982
|
+
Cloudflare still counted messages it would not return, even after the waits
|
|
983
|
+
(leased or not yet visible); later syncs pull them, and raising the time limit
|
|
984
|
+
does not help.
|
|
969
985
|
|
|
970
986
|
## Syncing data
|
|
971
987
|
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
backfillSnapshotAttributionCommand,
|
|
11
11
|
backfillTrafficClassificationCommand,
|
|
12
12
|
replayQueryAuditLog
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-IE4D47JE.js";
|
|
14
|
+
import "./chunk-BVJA3TV2.js";
|
|
15
15
|
import "./chunk-2FJB3CSS.js";
|
|
16
16
|
import "./chunk-HGMYEDAQ.js";
|
|
17
17
|
import "./chunk-JAYUWQAV.js";
|
|
@@ -19,10 +19,10 @@ import "./chunk-IBGZ6D6R.js";
|
|
|
19
19
|
import {
|
|
20
20
|
backfillProjectAnswerMentions,
|
|
21
21
|
backfillProjectAnswerMentionsInChunks
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-AI75KS7G.js";
|
|
23
|
+
import "./chunk-POMLL2OZ.js";
|
|
24
24
|
import "./chunk-GBWCEOZR.js";
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-AYYZ4HKJ.js";
|
|
26
26
|
import "./chunk-F643WELJ.js";
|
|
27
27
|
import "./chunk-MLKGABMK.js";
|
|
28
28
|
export {
|
|
@@ -28,7 +28,7 @@ async function buildSetupState() {
|
|
|
28
28
|
}
|
|
29
29
|
if (dbPath && fs.existsSync(dbPath)) {
|
|
30
30
|
try {
|
|
31
|
-
const { createClient, projects, queries: queriesTable } = await import("./src-
|
|
31
|
+
const { createClient, projects, queries: queriesTable } = await import("./src-JQYZ2TP6.js");
|
|
32
32
|
const db = createClient(dbPath);
|
|
33
33
|
project_count = db.select({ id: projects.id }).from(projects).all().length;
|
|
34
34
|
const firstQuery = db.select({ id: queriesTable.id }).from(queriesTable).limit(1).all();
|
|
@@ -47,7 +47,7 @@ function queueServeHandoff() {
|
|
|
47
47
|
async function runPendingServeHandoff(format) {
|
|
48
48
|
if (!pendingServeHandoff) return;
|
|
49
49
|
pendingServeHandoff = false;
|
|
50
|
-
const { serveCommand } = await import("./serve-
|
|
50
|
+
const { serveCommand } = await import("./serve-LLIUILD2.js");
|
|
51
51
|
await serveCommand(format);
|
|
52
52
|
}
|
|
53
53
|
|