AIVIS Edge Connector — Full Specification
AIVIS-EDGE · Full specification 06 Aug 2026 · rev 1

Edge Connector — Full Specification

The complete build spec for the implementing agent: worker internals, caching & invalidation, provisioning, analytics, AIVIS-side work, security, failure modes, testing, milestones, and the customer documentation set.

Builder hand-off document Companion: Architecture overview (§ refs = this doc) Requirement IDs are normative

00 · Front matter

How to use this spec

The eight invariants (recap)

IDInvariant
I1Fail-open. Any internal error yields the origin response unmodified.
I2Bounded latency. ≈1 ms warm; hard cap (~150 ms) cold; over budget ⇒ skip-and-warm. Non-HTML untouched.
I3Parity. Identical HTML for every user agent. Never bot-conditional.
I4Additive only. Exactly one tagged script element inserted; nothing else modified or removed.
I5Secret containment. Bearer tokens live only as Worker secrets; never in pages, logs, or events.
I6Reversibility. Pause/uninstall restores the pre-connector serving path in < 60 s via route removal.
I7Zero-trust ingestion. AIVIS output is untrusted input. A fully compromised AIVIS must never achieve script execution on a customer site (§07).
I8Analytics off = zero egress. With analytics disabled, no request-derived byte leaves the customer's account toward AIVIS.

02 · Edge worker internals

The worker, precisely

W-01Runtime & repo layout

TypeScript on the Cloudflare Workers runtime, built with Wrangler. Tests run against workerd (Vitest + @cloudflare/vitest-pool-workers). One worker script serves one customer zone; multi-domain customers get one deployment per zone.

aivis-edge-connector/
  worker/
    src/index.ts          entry — fetch handler, top-level try/catch (I1)
    src/gate.ts           request/response gating (W-03)
    src/normalize.ts      URL normalization (C-01)
    src/resolve.ts        cache-first schema resolution (C-*)
    src/ingest.ts         zero-trust validation pipeline (S-*)
    src/inject.ts         HTMLRewriter injection (W-05)
    src/bots.ts           UA registry + classifier (A-*)
    src/events.ts         event buffer + flush (A-*)
    src/config.ts         env parsing + defaults (W-02)
    test/                 unit + integration fixtures
  ops/                    provisioning CLI (§04)
  docs/                   exported copies of these specs

W-02Configuration contract

All per-customer configuration arrives as Worker vars/secrets at deploy time. No runtime config fetches in v1 (keeps the hot path self-contained; the epoch var doubles as a coarse invalidation lever, C-08).

VarTypeDefaultMeaning
AIVIS_API_BASEstringe.g. https://app.aivis.example; no trailing slash; redirects are not followed (S-08)
AIVIS_TOKENsecretBusiness-scoped bearer token (V-02); read-JSON-LD + write-events only
BUSINESS_IDstringPinned tenant; payloads for other businesses are rejected (S-05)
PRIMARY_HOSTstringe.g. www.allianz.de; host binding for lookups + payload checks
ANALYTICSon|offoffOff ⇒ classifier and event code paths never run (I8, A-01)
INJECTon|offonOff ⇒ analytics-only mode: zero HTML mutation, worker only measures (A-07) — for composition with origin connectors such as the WordPress plugin
CACHE_TTL_Sint300Fresh window per entry (C-04)
SWR_Sint86400Stale-while-revalidate window (C-04)
NEG_TTL_Sint300Negative-cache window for 404s (C-05)
LKG_MAX_Sint604800Max age of last-known-good served on upstream failure (C-06)
BUDGET_MSint150Cold-path hard cap (I2)
EPOCHint1Participates in cache keys; bump = domain-wide invalidation (C-08)
VERIFY_SIGNATURESoff|warn|enforceoffSignature policy (S-06); enforce for enterprise
AIVIS_PUBKEYstringEd25519 public key (base64) pinned at deploy; required when enforcing
EXCLUDE_PATHScsv/__aivis/*Path prefixes never touched (admin panels, APIs, etc.)

W-03Gating — when the worker acts at all

  1. Request gates: method is GET; path not under EXCLUDE_PATHS; not a synthetic cache-key path (/__aivis/). Everything else: fetch(request) pass-through, zero further logic.
  2. Response gates: status 200; Content-Type starts with text/html. Redirects, errors, JSON, assets: returned as-is. Gate on the response content type, not the request Accept header — origins lie less than clients.
  3. HEAD requests: pass through (no body to rewrite).
  4. Requests carrying ?__aivis=off bypass injection (debug aid; the parameter is stripped before origin fetch so caches don't fragment). confirm param name with Daniel

W-04Concurrency model per request

Origin fetch and schema resolution start simultaneously. The response is held until the schema promise settles or BUDGET_MS elapses — whichever is first. Warm path: cache answers in ~1 ms, so the hold is unmeasurable. Cold path: at most BUDGET_MS added to TTFB, once per URL per colo per TTL. On timeout: skip injection, let waitUntil() finish the API call and populate the cache for the next request (I2).

W-05Injection mechanics

W-06Failure envelope

The entire pipeline runs inside one top-level try/catch that falls back to fetch(request). Rewriter stream errors after headers are sent are the one unfixable window — mitigated by doing all fallible work (resolution, validation) before constructing the rewriter, so the streaming phase touches no external systems. CPU-time and subrequest limits are respected by design: warm path ≈ 1 subrequest (origin only), cold path ≤ 2.

03 · Caching & invalidation

Freshness you can command, per URL and per domain

C-01URL normalization contract

One function, shared conceptually with the API (V-07), applied to every page URL before lookup or caching:

  1. Parse with new URL(); invalid ⇒ skip injection.
  2. Scheme ⇒ https; host lowercased; default ports stripped; fragment dropped.
  3. Query: drop the tracking blocklist (utm_*, gclid, fbclid, msclkid, mc_eid, ref) — then, v1 default, drop the remaining query entirely (AIVIS stores canonical page URLs without queries). A per-customer keep-list can override for genuinely content-bearing params. confirm AIVIS canonical form incl. trailing-slash policy — Open Q-1
  4. Path case preserved; trailing slash normalized to match AIVIS storage (pending Q-1).

C-02Cache design — purgeable by construction

Schema entries are stored in the Cloudflare cache under a synthetic URL on the customer's own zone:

cacheKey = https://{PRIMARY_HOST}/__aivis/c/{EPOCH}/{sha256(normalizedPageUrl)}

C-03Resolution algorithm

  1. cache.match(cacheKey). Hit & fresh ⇒ use. Hit & in SWR window ⇒ use, and revalidate via waitUntil.
  2. Miss ⇒ GET {AIVIS_API_BASE}/api/public/v1/jsonld?url={normalizedPageUrl}, bearer auth, AbortController at BUDGET_MS.
  3. 200 ⇒ run ingestion pipeline (S-*) ⇒ pass ⇒ cache.put + inject. Fail ⇒ treat as upstream-invalid (C-06).
  4. 404 ⇒ negative-cache marker for NEG_TTL_S (C-05); no injection.
  5. Timeout / 5xx / network error ⇒ last-known-good if present and younger than LKG_MAX_S, else skip (C-06).
  6. Best-effort request coalescing: an in-isolate in-flight map prevents duplicate API calls for the same key within one isolate.

C-04C-06 TTLs, negatives, last-known-good

StateWindowBehaviour
FreshCACHE_TTL_S (300 s)Serve from cache, no upstream traffic
Stale (SWR)SWR_S (24 h)Serve stale, revalidate in background
NegativeNEG_TTL_S (300 s)Page has no schema; don't ask again yet
Upstream failingLKG_MAX_S (7 d)Serve last-known-good — transport failures only, never after a confirmed 404 (C-10)
Nothing cached + failingSkip injection (I1); page unaffected

C-07Invalidation — the command surface

CommandMechanismPropagationTrigger
Per URLCloudflare single-file purge of the synthetic keyGlobal, secondsAuto: AIVIS regenerate→purge hook (V-03). Manual: ops invalidate --url, later a dashboard button
Per domainBatched single-file purges over the business's URL inventory (from /chains/{id}/urls), 30 files per API callGlobal, seconds–minuteManual: ops invalidate --domain. Auto candidate: chain-wide republish
Epoch bumpEPOCH var change + redeploy; old keys orphan and age outGlobal, ~seconds (deploy)Fallback for self-managed setups without a purge token

C-09Existing on-page schema

v1 is additive (I4). The rewriter detects pre-existing application/ld+json blocks and reports conflict:onpage_schema through events (when analytics is on) so strategists see overlap. De-duplication/replacement is explicitly a v2 conversation.

C-10Retraction — deletion wins over resilience

Publishing has an inverse: a bad JSON-LD must be removable, not just replaceable. Flow: unpublish in AIVIS (V-08) ⇒ /jsonld returns 404 for that URL ⇒ the purge hook (V-03) clears the edge cache key globally ⇒ the worker's next lookup gets the 404 and overwrites the cached entry — including last-known-good — with a negative marker.

Precedence rule: last-known-good exists to absorb transport failures (timeout, 5xx, network). A confirmed 404 is an authoritative statement of absence and permanently clears the LKG entry. Without this rule, a retracted schema could resurrect hours later during an API outage via the stale-if-error path — the exact opposite of a retraction. Tested explicitly (T-02).

Distinct case: removing a bad JSON-LD that the customer's own CMS ships inside the origin HTML. That is markup modification, fenced out of v1 by I4/D6, and listed as the v2 suppression/replacement conversation (C-09).

Freshness summary

EventVisible on site within
JSON-LD regenerated in AIVIS (auto-purge on)Seconds
Regenerated, no purge rights (self-managed, TTL-only)CACHE_TTL_S (5 min default)
Manual domain invalidationSeconds–minute
Retracted ("unpublished") JSON-LD gone from all pages — cannot resurrectSeconds
Worker config change (epoch, settings)Deploy time, ~seconds

04 · Provisioning & operations

Two modes, one artifact, a clean handover

The worker always runs in the customer's Cloudflare account. The modes differ only in who holds deployment rights — which is why the Allianz handover is a permissions change, not a migration.

Mode A — Aivis-operated

Default for SMB / mid-market

  • Customer creates one scoped API token in their CF dashboard (guided 5-minute doc, §11 Pack A)
  • AIVIS runs ops connect / deploy / verify; customer installs nothing
  • Worker fully visible in their dashboard at all times
  • Revoking the token instantly ends AIVIS's access — their kill switch, not ours
Mode B — self-managed

Enterprise (Allianz-class)

  • Customer IT receives the deployment package (P-05) and deploys with their own credentials
  • AIVIS never touches their account; the only secret inside is a business-scoped, read-only AIVIS token
  • Freshness: TTL-only, or an optional purge-only token grant
  • Updates ship as versioned packages their IT applies

P-02Cloudflare token scopes (Mode A) — least privilege

ScopeLevelWhy
Workers Scripts : EditAccountUpload/update/delete the worker + secrets
Workers Routes : EditZone (this zone only)Attach/detach the route — also the kill switch (I6)
Zone : ReadZoneResolve zone ID, sanity checks
Cache Purge : PurgeZonePer-URL / per-domain invalidation (C-07)

Exact scope names to be confirmed against the current CF token UI at build time verify at build. Token should be zone-restricted and, where the plan allows, IP-restricted to AIVIS ops egress.

P-03Ops CLI command surface

CommandDoes
ops connectVerify CF token (+ scopes), resolve zone, check it matches Business.baseUrl, store encrypted in the customer config store
ops deployUpload bundle, set vars + secrets, attach route {host}/*; idempotent
ops verifySynthetic check: fetch N live pages with cache-buster, assert exactly one data-aivis block, parse it, diff against the API's answer; check CSP headers for surprises
ops pause / resumeDetach / re-attach the route — < 60 s, zero code path (I6)
ops invalidate --url … | --domainC-07 purges, with throttling + progress output
ops uninstallRoute + script + secrets removed; prints confirmation checklist
ops upgrade [--canary|--all]Staged fleet rollout: internal zone → SMB cohort → enterprise; per-customer version pinning; rollback = redeploy previous bundle

P-04 Per-customer config lives as one reviewed YAML file in the private fleet repo (aivis-edge-fleet, §12 O-01), rendered to Worker vars at deploy; secrets in an encrypted store, never in the YAML — and never anywhere in the public connector repo.

P-05The self-managed deployment package

P-06Handover procedure (Mode A → B)

  1. Deliver package (P-05) + security pack (§11 Pack B) to customer IT.
  2. Joint session: walk the runbook; customer IT performs a no-op redeploy themselves.
  3. Customer revokes AIVIS's CF token. Nothing moves — the worker was in their account all along.
  4. Agree freshness mode (TTL-only vs purge-only token) and update-notification channel.

05 · Analytics

Optional by design — off means off

A-01 / I8. ANALYTICS=off is the deploy-time default. When off, the classifier and event modules are never invoked and the worker makes zero requests to AIVIS beyond schema pulls — a statement sales can put in a contract, verifiable by the customer in their own Workers logs. SMB deployments flip it on; enterprise stays off unless they opt in.

A-02Event schema (analytics on)

{
  "ts": "2026-08-06T10:31:04Z",     // minute precision is enough
  "host": "www.example.com",
  "path": "/products/x",             // normalized path only, never query strings
  "bot": "GPTBot",                   // matched registry family, or "none"
  "cat": "training|search|live|none",
  "injected": true,                  // true | false | "origin" (block already shipped by origin, A-07)
  "cache": "hit|miss|skip",
  "skip": "no_head|charset|budget|no_schema|conflict:onpage_schema|null",
  "wv": "1.4.2"                      // worker version
}

A-06Registry v1

Same table as the architecture overview §7: OpenAI (GPTBot, OAI-SearchBot, ChatGPT-User), Anthropic (ClaudeBot, Claude-SearchBot, Claude-User), Perplexity (PerplexityBot, Perplexity-User), Googlebot (note: Google-Extended is a robots directive, not a UA), Bingbot, CCBot, Bytespider, Amazonbot, Applebot, meta-externalagent, MistralAI-User, DuckAssistBot. Registry entries carry a verification hint (published IP ranges / reverse-DNS) for a later "verified bot" flag — matching alone is v1.

A-07Analytics-only mode & origin composition

With INJECT=off the worker becomes a pure measurement tap: no HTMLRewriter pass, no mutation of any response — only crawler classification and batched events. This is the recommended setup when the origin already delivers the JSON-LD, e.g. a WordPress site running the AIVIS WordPress Connector behind Cloudflare: the origin-shipped block rides inside cached HTML (zero added edge latency), and the worker's idempotency detection (W-05) recognizes data-aivis and records injected:"origin". Delivery at the origin, measurement at the edge — each layer where it is truthful. WordPress-side crawler analytics is permanently excluded (WP spec §22): PHP sees only cache-miss traffic, a systematically biased sample unfit for the Monitoring SKU.

06 · AIVIS-side work package

Changes in the aivis repo — all small, one prerequisite

Follow repo conventions: createApiHandler + Zod, jobs as one processor per JobKind, spec updates in docs/v21. Listed in build order:

V-02Business-scoped API tokens prerequisite for any external deploy

Today's aivis_ tokens are user-scoped: a worker secret in customer infrastructure could list every business of that user. Add a token type bound to one businessId with permission flags { jsonld:read, events:write }; /jsonld and /events enforce the binding. Existing user tokens keep working for the profile/API use case.

V-01Events ingest endpoint

POST /api/public/v1/events        Bearer (business-scoped, events:write)
body: { workerVersion, host, events: Event[≤100] }   → 202
storage: EdgeEvent (raw, 90-day retention) + EdgeEventDaily rollup (kept)
rate limit: per-token, generous (batches are small); reject >100 events/req

V-03Regenerate/retract→purge hook

New model EdgeConnection { businessId, mode(A|B), zoneId, accountId, cfTokenRef(encrypted), analytics, purgeEnabled, status }. After a successful generate_jsonld job — and after a retraction (V-08) — for a URL whose business has a connection with purgeEnabled: enqueue edge_purge (new JobKind) → single-file purge of that URL's synthetic key via the CF API. Domain-level purge = same job fed by the URL inventory. Failures retry ×3 then alert; purge failure is never user-facing breakage (TTL still bounds staleness).

V-04Serve-gate on /jsonld

Today the endpoint returns the latest artifact. With auto-purge, a bad regeneration reaches production in seconds — so add a per-business serve policy: latest (today's behaviour) or validated (only artifacts with validation.errors == 0; falls back to the previous passing artifact — requires keeping the previous artifact row instead of delete-and-recreate). Default validated for connected businesses. An explicit per-URL publish flag remains future scope.

V-05Artifact signing (enterprise option)

At artifact write time, sign businessId + "\n" + url + "\n" + generatedAt + "\n" + canonicalPayload with Ed25519; store { keyId, sig, canonicalPayload } on the artifact row. /jsonld returns the canonical string verbatim plus the signature block; the worker (when VERIFY_SIGNATURES=enforce) verifies against the pinned public key and parses that exact string. Signing keys live outside the app container (KMS or at minimum an isolated env not reachable from app code paths); honest limits of this scheme are stated in §07.

V-08Retract / unpublish action

Per-URL action (plus chain-level bulk) that withdraws a published JSON-LD without waiting for a replacement: set suppressedAt on the artifact — recommended over hard deletion (reversible, keeps the audit trail; the existing DELETE endpoint remains for true deletion). While suppressed, /jsonld returns 404 for that URL regardless of serve policy, and the purge hook (V-03) fires immediately. Combined with C-10 the block is off every page in seconds and cannot resurrect. Dashboard surface: an "Unpublish from edge" action next to regenerate.

V-06V-07 Supporting endpoints

07 · Security, tenancy & privacy

Zero-trust ingestion: a hacked AIVIS cannot hurt the customer

The question that shaped this section: should the worker check JSON-LD integrity so that even if AIVIS OS is hacked, Allianz is never affected? Yes — the worker treats AIVIS as hostile input. The one genuinely dangerous outcome would be a crafted payload containing </script><script>… escaping the data block and executing as JavaScript on the customer's page. The pipeline below makes that structurally impossible, and everything after it shrinks what's left.

S-01The ingestion pipeline — every payload, every time

API response untrusted 1 · strict parse JSON.parse only 2 · re-serialize < → \u003c 3 · shape + size ≤128 KiB · depth ≤32 4 · binding host + business 5 · signature optional Ed25519 any failure serve last-known-good, else skip — never inject cache stores only what passed
Nothing from the API reaches a page verbatim. The cache stores post-pipeline output only, so poisoned payloads can't hide behind a hit.
  1. S-02 Strict parse. JSON.parse or reject. No eval-anything, no lenient parsing.
  2. S-03 Sanitizing re-serialization — the XSS killer. JSON.stringify the parsed value, then replace every < with \u003c. The output is byte-equivalent JSON-LD to any consumer, but can never contain </script>, <script, or <!-- — script-context breakout becomes impossible regardless of payload content.
  3. S-04 Shape + size. Top level is an object or array; nodes carry @type/@id/@context keys consistent with Schema.org shape; serialized size ≤ 128 KiB; nesting depth ≤ 32. Violations reject.
  4. S-05 Domain binding. Response businessId must equal BUSINESS_ID; response url host must match PRIMARY_HOST (www-equivalence configurable). A payload for another tenant or domain never gets injected — kills cross-tenant injection even if the API mixes up tenants.
  5. S-06 Signature (enterprise, enforce). Ed25519 verify against the public key pinned in the customer's own deployment (V-05). The customer's account holds the trust anchor, not AIVIS's runtime.

S-07Honest threat model

ScenarioWorst case with this designWhy not worse
AIVIS app/API fully compromised, signing offWrong facts in structured data until detectedS-02…S-05: no code execution possible; blast bounded by purge-all + pause runbook (F-*)
AIVIS compromised, signing enforced, keys isolatedStale data (attacker can't sign new payloads)Worker rejects unsigned/invalid; serves last-known-good
AIVIS compromised incl. signing keysSame as row 1 — signing adds nothing if keys fallStated honestly in the security pack; key isolation (KMS) is the mitigation
Stolen AIVIS bearer tokenAttacker reads that one business's JSON-LD, writes fake eventsBusiness-scoped read-only token (V-02); rotate + revoke
Stolen customer CF token (Mode A)Worker/route tampering on that zoneZone-restricted, least-privilege scopes (P-02); customer can revoke instantly; anomaly = verify job failing
MITM worker↔AIVISTLS; AIVIS_API_BASE pinned; redirects not followed (S-08)
Supply-chain attack on the public repo (malicious PR, compromised maintainer)Tampered release, if all guards failProtected branches + required review, maintainer 2FA, secret scanning, pinned deps, signed releases + provenance (§12 O-04/O-05); customers pin versions and verify checksums before deploy

S-09 The /__aivis/ namespace returns 404 to real visitors; synthetic keys are unguessable (hashed) and carry no secrets anyway. S-10 Events contain no personal data (A-02) — the GDPR story is "bot traffic statistics, no natural persons," and ANALYTICS=off removes even that. Data-processing summary lives in §11 Pack B.

08 · Failure modes & SLOs

Every way it breaks, and what happens instead

FailureVisitor seesDetectionRecovery
AIVIS API down / slowPage as-is; schema from last-known-good or absentcache:skip events spike; daily verify jobNone needed — self-heals on API return (I1)
Malformed / hostile payloadPage as-is (pipeline rejected it)skip + sig-status eventsFix upstream; purge; LKG covered the gap
Worker exceptionPage as-is via top-level catchWorkers error metrics; verify jobRollback release (P-03)
Purge API failingSlightly stale schema, ≤ TTLedge_purge job retries/alertsTTL bounds staleness at 5 min
AIVIS token revoked/expiredPage as-is after LKG window401s in resolve; eventsRotate token, redeploy secret
CF token revoked (Mode A)Nothing — serving unaffectedOps commands failRe-issue with customer; or handover to Mode B
Origin downOrigin's own error (worker passes non-200 through untouched)Customer's incident, not ours — and provably so
Cloudflare colo issuesCF-level behaviour; worker adds nothingCF status

F-02Service-level objectives (targets to validate at build)

F-03 Runbooks (short, in ops/runbooks/): retract a single bad JSON-LD (V-08 + purge — the scalpel, seconds); pause a customer (the hammer); purge-all for a customer; roll back a release; rotate AIVIS token; rotate CF token; "AIVIS compromise" drill = pause all Mode-A customers (route detach loop) + notify Mode-B customers to pause, then purge-all after all-clear.

09 · Testing & verification

Proving the invariants, not just the features

LayerCoversKey cases
T-01 Unitnormalize, ingest, bots, injectNormalization table (Q-1 fixtures); XSS corpus: </script>, <script, <!--, pre-escaped unicode, 129 KiB payload, depth-33 nesting, wrong-business, wrong-host, bad signature; classifier fixtures per registry entry
T-02 Integration (workerd)Full request pipeline vs mock APIWarm/cold/negative/SWR/LKG paths; budget timeout ⇒ skip-and-warm; retraction precedence: confirmed 404 clears LKG, retracted URL must not resurrect during a simulated API outage (C-10); no-head page; existing data-aivis idempotency; non-HTML/redirect/404 pass-through byte-identical (I1/I4 assertion = response diff)
T-03 Live smokeReal dev APIGET /me; GET /jsonld?url=… with Daniel's token; payload passes ingestion; latency measured against budget assumptions
T-04 End-to-end stagingAIVIS-owned CF zone + demo siteDeploy via ops CLI; verify command green; regenerate in AIVIS ⇒ purge ⇒ page updated in seconds; unpublish in AIVIS ⇒ block gone in seconds (V-08); pause ⇒ block gone < 60 s; analytics on/off egress check (I8: capture worker subrequests, assert none to AIVIS when off)
T-05 Pre-customer checklistEach onboardingops verify green on top-20 URLs; Google Rich Results test + Schema.org validator on 3 samples; CSP reviewed; before/after WebPageTest diff within SLO; soak 48 h on staging zone if available

T-06 Each invariant I1–I8 must map to at least one automated test or checklist line; the mapping table lives in worker/test/INVARIANTS.md.

10 · Rollout milestones

Build order for the implementing agent

  1. M1Worker core.Gates, normalization, resolution with cache states, ingestion pipeline S-02…S-05, injection, fail-open. The public repo exists from the first commit with license + hygiene guards in place (§12 O-01). Exit: T-01/T-02 green; live smoke T-03 against dev API; deployed on an AIVIS-owned test zone with a demo page.
  2. M2Ops CLI.connect / deploy / verify / pause / resume / uninstall / invalidate. Exit: full lifecycle demonstrated on the test zone incl. per-URL and per-domain purge timing measurements.
  3. M3AIVIS-side package.V-02 scoped tokens (prerequisite), V-01 ingest, V-03 purge hook + EdgeConnection, V-04 serve-gate, V-07 tolerant lookup. Exit: regenerate-in-AIVIS ⇒ live-on-page in seconds, end to end (T-04).
  4. M4Analytics.Classifier, buffering, ingest storage + rollups; ANALYTICS on/off verified incl. the I8 egress test. Exit: bot hits from the test zone visible in AIVIS data.
  5. M5Hardening + SMB pilot.V-05 signing path (warn mode), F-03 runbooks, §11 Packs A+B drafted, upgrade/rollback drill, OSS launch checklist complete (O-05 release pipeline + O-07 community files). Exit: first real SMB customer live in Mode A; first public tagged release.
  6. M6Enterprise kit.P-05 package, P-06 handover procedure, signing in enforce mode, German documentation. Exit: a customer-IT team can deploy from the package alone — Allianz-ready.

M1–M2 and M3 can proceed in parallel after the C-01/V-07 normalization contract is agreed (Open Q-1 first).

11 · Customer documentation set

Three packs + a handover kit — EN master, DE for DACH

Pack A

Stakeholder brief (marketing / comms)

  • What changes on the site (one invisible data block) and what never does
  • Same page for humans and machines — the no-cloaking commitment
  • How fast updates go live; who to call
  • Mode A onboarding: the 5-minute token guide with screenshots
Pack B

Security & IT review pack

  • Architecture on one page: what runs in whose account
  • Exact permission table (P-02) + revocation effects
  • Data flows & GDPR statement (S-10); analytics off = zero egress (I8)
  • Zero-trust ingestion & the honest threat model (S-07) — incl. "a compromised AIVIS cannot execute code on your site"
  • Kill switch, uninstall, audit steps; SLO posture (F-02)
Pack C

Self-managed runbook (enterprise IT)

  • Deploy from package: wrangler + Terraform paths
  • Secrets, route, verify; pause & uninstall
  • Update policy, changelog, checksum verification
  • Freshness options: TTL-only vs purge-only token
  • Canonical copy lives in the public repo docs (§12 O-08)
Handover kit

Mode A → B checklist

  • P-06 procedure as a signable checklist
  • Token revocation confirmation
  • Support boundary + escalation contacts

12 · Open source & supply chain

Public by default — the connector is not the moat

Decision (locked, D10): the connector is an open-source project on GitHub from the first commit. Rationale: the worker runs inside customer accounts anyway, so source secrecy protects nothing — while public code turns every enterprise security review into a trust asset ("audit the exact code running in your account"), makes Mode B consumption normal OSS practice, and lets the bot registry benefit from outside contributions. The moat is the AIVIS platform — graph generation, validation, monitoring — which stays private.

O-01Repo boundary

RepoVisibilityContains
aivis-edge-connectorpublicworker/, ops/ CLI code, bot registry, public docs (O-08), examples (wrangler.toml, Terraform), CI workflows
aivis-edge-fleetprivatePer-customer YAML configs, encrypted token references, customer runbooks, deploy automation glue, live-smoke CI with real tokens
epoint-digital/aivisprivateThe platform: Public API implementation, generation pipeline, all §06 additions, signing keys

The rule: nothing customer-identifying and no real secrets ever enter the public repo — code, tests, fixtures, issues, commit messages, or history. Fixtures use invented domains and fake tokens. Public from the first commit means there is never a history to scrub.

O-02License & contributions

Apache-2.0 (recommended; explicit patent grant, enterprise-legal-friendly — MIT is the acceptable alternative, Q-8), with NOTICE file. Contributions under DCO sign-off (no CLA — needless friction at this size). The AIVIS name and logo remain trademarks: the code is free, the brand is not; a short trademark note lives in the README.

O-03The provider interface is documented, not gated

The worker consumes a documented HTTP contract — GET /jsonld?url=… with bearer auth, the response shape from the OpenAPI spec, and the optional signature block (V-05). Any conforming backend works; AIVIS is the reference provider. This is stated openly in the public docs: the connector is generic infrastructure, the value is in what AIVIS puts through it.

O-04O-06 Supply-chain hardening, releases, CI

O-07O-08 Community files & public docs

O-09O-10 Consequences elsewhere

Appendix · Open questions & risks

To resolve before / during M1

#QuestionBlocksOwner
Q-1AIVIS canonical URL form (trailing slash, query, www) — fixes the C-01/V-07 contractM1Daniel + builder
Q-2Confirm Cache API entries are single-file-purgeable on the target CF plansM2Builder (spike)
Q-3Purge API rate limits per plan → domain-purge throttle valuesM2Builder
Q-4Production hosting of AIVIS (dev is onepoint.ro) — API availability target the LKG window must absorbM5Daniel
Q-5Serve-gate default (validated) — confirm with strategists; requires keeping previous artifact rows (V-04)M3Daniel
Q-6Signing key custody (KMS vs isolated env) for V-05/S-07 honestyM5Daniel
Q-7Human-traffic sampling in events (1:100?) or bots-onlyM4Daniel
Q-8OSS final calls: license Apache-2.0 (recommended) vs MIT; GitHub org (epoint-digital vs a new aivis org); public project nameM1Daniel