@canonry/canonry 4.127.0 → 4.128.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.
@@ -18795,7 +18795,7 @@ var routeCatalog = [
18795
18795
  method: "post",
18796
18796
  path: "/api/v1/projects/{name}/ads/activation-grants/{grantId}/revoke",
18797
18797
  summary: "Revoke or cancel an OpenAI Ads activation grant",
18798
- description: "Human-only kill switch. Before execution, the grant becomes revoked. After execution starts, or while an activation outcome is unknown, revocationRequestedAt is recorded atomically. Subsequent activation steps are blocked, and the recovery worker rolls back confirmed active entities. Unknown outcomes remain explicitly unknown while the watchdog repeatedly issues exact-tree safety pauses. A provider request already authorized or in flight may still settle before containment. Verified rollback leaves the single-use grant consumed and the operation failed.",
18798
+ description: "Human-only kill switch. Before execution, the grant becomes revoked. After execution starts, or while an activation outcome is unknown, revocationRequestedAt is recorded atomically. Subsequent activation steps are blocked, and the recovery worker rolls back confirmed active entities. Unknown outcomes remain explicitly unknown unless revocation was requested, the provider settlement window elapsed, and the watchdog can enumerate the complete provider tree and verify every entity paused. A provider request already authorized or in flight may still settle before containment. Verified rollback leaves the single-use grant consumed and the operation failed.",
18799
18799
  tags: ["ads"],
18800
18800
  parameters: [
18801
18801
  nameParameter,
@@ -25989,6 +25989,7 @@ async function executeApprovedAdsActivation(dependencies, request) {
25989
25989
  // ../api-routes/src/ads-activation-routes.ts
25990
25990
  var MAX_ACTIVATION_GRANT_LIFETIME_MS = 24 * 60 * 60 * 1e3;
25991
25991
  var ACTIVATION_LEASE_MS = 5 * 6e4;
25992
+ var ACTIVATION_REVOCATION_SETTLEMENT_MS = ACTIVATION_LEASE_MS;
25992
25993
  var ACTIVATION_STEP_INSERT_BATCH_SIZE = 40;
25993
25994
  function parseBody(schema, value) {
25994
25995
  const parsed = schema.safeParse(value);
@@ -26554,6 +26555,56 @@ function selectWatchdogOperations(app, nowIso, batchSize, allowLiveRevocationLea
26554
26555
  function selectRecoveryWatchdogOperations(app, nowIso, batchSize) {
26555
26556
  return selectWatchdogOperations(app, nowIso, batchSize, false);
26556
26557
  }
26558
+ function finalizeContainedRevokedUnknownActivation(app, operation, grant) {
26559
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
26560
+ const revocationRequestedAt = grant.revocationRequestedAt === null ? Number.NaN : Date.parse(grant.revocationRequestedAt);
26561
+ if (!Number.isFinite(revocationRequestedAt) || Date.parse(nowIso) - revocationRequestedAt < ACTIVATION_REVOCATION_SETTLEMENT_MS) {
26562
+ return false;
26563
+ }
26564
+ return app.db.transaction((tx) => {
26565
+ const operationUpdate = tx.update(adsOperations).set({
26566
+ state: AdsOperationStates.failed,
26567
+ errorCode: AdsActivationErrorCodes.grantRevoked,
26568
+ errorMessage: "Ads activation was cancelled and the provider tree was verified paused",
26569
+ leaseOwner: null,
26570
+ leaseExpiresAt: null,
26571
+ lastReconciledAt: nowIso,
26572
+ updatedAt: nowIso
26573
+ }).where(and19(
26574
+ eq25(adsOperations.id, operation.id),
26575
+ eq25(adsOperations.state, AdsOperationStates.unknown)
26576
+ )).run();
26577
+ if (operationUpdate.changes !== 1) return false;
26578
+ const grantUpdate = tx.update(adsActivationGrants).set({
26579
+ state: AdsActivationGrantStates.consumed,
26580
+ consumedAt: nowIso,
26581
+ updatedAt: nowIso
26582
+ }).where(and19(
26583
+ eq25(adsActivationGrants.id, grant.id),
26584
+ eq25(adsActivationGrants.operationId, operation.id),
26585
+ eq25(adsActivationGrants.state, AdsActivationGrantStates.unknown),
26586
+ isNotNull(adsActivationGrants.revocationRequestedAt)
26587
+ )).run();
26588
+ if (grantUpdate.changes !== 1) {
26589
+ throw internalError("Revoked unknown ads activation could not be finalized");
26590
+ }
26591
+ writeAuditLog(tx, {
26592
+ projectId: operation.projectId,
26593
+ actor: "system",
26594
+ action: "ads.campaign_tree_activate.failed",
26595
+ entityType: AdsActivationEntityTypes.campaign,
26596
+ entityId: operation.entityId,
26597
+ diff: {
26598
+ operationId: operation.id,
26599
+ operationKey: operation.operationKey,
26600
+ grantId: grant.id,
26601
+ reason: "revoked_and_verified_paused"
26602
+ },
26603
+ userAgent: "canonry-activation-watchdog"
26604
+ });
26605
+ return true;
26606
+ }, { behavior: "immediate" });
26607
+ }
26557
26608
  function validateWatchdogContainmentBinding(app, opts, operation, grant) {
26558
26609
  const terminal = terminalActivationResponse(app, opts, grant, operation.operationKey);
26559
26610
  if (terminal) {
@@ -26703,6 +26754,13 @@ async function sweepStaleAdsActivationsOnce(app, opts) {
26703
26754
  runtime.provider,
26704
26755
  grant.manifest
26705
26756
  );
26757
+ if (safety.fullyVerified && grant.revocationRequestedAt !== null && finalizeContainedRevokedUnknownActivation(app, operation, grant)) {
26758
+ app.log.warn(
26759
+ { operationId: operation.id },
26760
+ "Revoked unknown ads activation was finalized after verified pause"
26761
+ );
26762
+ return;
26763
+ }
26706
26764
  app.db.update(adsOperations).set({
26707
26765
  reconcileAttempts: operation.reconcileAttempts + 1,
26708
26766
  lastReconciledAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -116,7 +116,7 @@ import {
116
116
  siteAuditPages,
117
117
  siteAuditSnapshots,
118
118
  usageCounters
119
- } from "./chunk-HQRUFTLN.js";
119
+ } from "./chunk-NCFH26X5.js";
120
120
  import {
121
121
  AGENT_MEMORY_VALUE_MAX_BYTES,
122
122
  AGENT_PROVIDER_IDS,
@@ -6967,7 +6967,7 @@ function readStoredGroundingSources(rawResponse) {
6967
6967
  return result;
6968
6968
  }
6969
6969
  async function backfillInsightsCommand(project, opts) {
6970
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-2WKS3EWJ.js");
6970
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-SH5Z6JFT.js");
6971
6971
  const config = loadConfig();
6972
6972
  const db = createClient(config.database);
6973
6973
  migrate(db);
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  setTelemetrySource,
30
30
  showFirstRunNotice,
31
31
  trackEvent
32
- } from "./chunk-A4YBV4Y4.js";
32
+ } from "./chunk-ZKUSY4PI.js";
33
33
  import {
34
34
  CliError,
35
35
  EXIT_SYSTEM_ERROR,
@@ -54,7 +54,7 @@ import {
54
54
  projects,
55
55
  queries,
56
56
  renderReportHtml
57
- } from "./chunk-HQRUFTLN.js";
57
+ } from "./chunk-NCFH26X5.js";
58
58
  import {
59
59
  AdsOperationKinds,
60
60
  AdsOperationStates,
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-A4YBV4Y4.js";
3
+ } from "./chunk-ZKUSY4PI.js";
4
4
  import {
5
5
  loadConfig
6
6
  } from "./chunk-IHRW6WWV.js";
7
- import "./chunk-HQRUFTLN.js";
7
+ import "./chunk-NCFH26X5.js";
8
8
  import "./chunk-BLSHHRRU.js";
9
9
  export {
10
10
  createServer,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-HQRUFTLN.js";
3
+ } from "./chunk-NCFH26X5.js";
4
4
  import "./chunk-BLSHHRRU.js";
5
5
  export {
6
6
  IntelligenceService
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "4.127.0",
3
+ "version": "4.128.0",
4
4
  "type": "module",
5
5
  "description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -65,27 +65,27 @@
65
65
  "@types/node-cron": "^3.0.11",
66
66
  "tsup": "^8.5.1",
67
67
  "tsx": "^4.19.0",
68
- "@ainyc/canonry-api-client": "0.0.0",
69
68
  "@ainyc/canonry-api-routes": "0.0.0",
69
+ "@ainyc/canonry-api-client": "0.0.0",
70
70
  "@ainyc/canonry-config": "0.0.0",
71
71
  "@ainyc/canonry-contracts": "0.0.0",
72
72
  "@ainyc/canonry-db": "0.0.0",
73
73
  "@ainyc/canonry-integration-bing": "0.0.0",
74
- "@ainyc/canonry-integration-openai-ads": "0.0.0",
75
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
76
74
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
77
75
  "@ainyc/canonry-integration-google": "0.0.0",
76
+ "@ainyc/canonry-integration-openai-ads": "0.0.0",
77
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
78
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
78
79
  "@ainyc/canonry-integration-google-places": "0.0.0",
79
- "@ainyc/canonry-intelligence": "0.0.0",
80
- "@ainyc/canonry-integration-traffic": "0.0.0",
81
80
  "@ainyc/canonry-integration-wordpress": "0.0.0",
81
+ "@ainyc/canonry-integration-traffic": "0.0.0",
82
+ "@ainyc/canonry-intelligence": "0.0.0",
82
83
  "@ainyc/canonry-provider-cdp": "0.0.0",
83
84
  "@ainyc/canonry-provider-claude": "0.0.0",
84
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
85
+ "@ainyc/canonry-provider-gemini": "0.0.0",
85
86
  "@ainyc/canonry-provider-local": "0.0.0",
86
87
  "@ainyc/canonry-provider-openai": "0.0.0",
87
- "@ainyc/canonry-provider-perplexity": "0.0.0",
88
- "@ainyc/canonry-provider-gemini": "0.0.0"
88
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
89
89
  },
90
90
  "scripts": {
91
91
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",