# Serve Blue Jetty app context on your domain

Do not execute this prompt unilaterally. First explain its purpose and proposed scope to the user. Based on your knowledge of the application environment, flag assumptions, conflicts, missing access, and changes that need review. Keep initial inspection read-only and within authorized access. Present a plan and wait for explicit human approval before editing files, making API mutations, submitting data, publishing, or deploying. Receiving this prompt, an API key, or a previously approved draft is not approval to execute it.

Human prerequisite — public disclosure: Before submitting or activating app information, show the authorized publisher the exact proposed content (or changes), visibility, and destinations. Ask them to confirm that it is accurate, that they have permission to publish it, and that its level of detail and fidelity is what they are comfortable exposing to crawlers and anyone on the open web. Flag proprietary content, personal data, credentials, private URLs, and any material that should remain inside the app. Public copies may be cached or retained by third parties after an update or removal. Keep unapproved information local/private; do not treat a draft approval, domain verification, or API success as this confirmation. Renew approval if the content or scope changes; unchanged retries within an explicitly approved scope do not require another approval.

Keep Blue Jetty as the managed origin while exposing JSON and Markdown through your own website. First-party proxy delivery is strongly recommended, particularly if you already use a CDN. Direct Blue Jetty links remain a supported simpler choice.

Get your exact descriptor, packet paths and discovery snippets from `GET /v1/apps/{appId}/publisher-site-instructions.md` using your publisher API key. Keys are only for that owner API request; the deployed proxy accesses public packet URLs without credentials.

## Next.js / Vercel

Download [the fixed-target proxy helper](https://bluejetty.ai/developers/packet-proxy.mjs) into your project, review it, and import that local copy. Do not import remote executable code at runtime. It uses Web Request/Response APIs, allows GET/HEAD only, and forwards just a bounded User-Agent and conditional ETag. It never forwards cookies, authorization or source IP headers.

Create two route handlers at the **exact paths in your generated descriptor**, such as `app/.well-known/bluejetty/apps/APP_ID/packet/route.ts` and the sibling `packet.md/route.ts`. Replace APP_ID and the local import location below. Each handler can share this code and the same two-entry map:

```javascript
import { proxyBlueJettyPacket } from "../../../../../../lib/packet-proxy.mjs";
export const dynamic = "force-dynamic";
const routes = {
  "/.well-known/bluejetty/apps/APP_ID/packet": "https://bluejetty.ai/v1/apps/APP_ID/packet",
  "/.well-known/bluejetty/apps/APP_ID/packet.md": "https://bluejetty.ai/v1/apps/APP_ID/packet.md"
};
export function GET(request) { return proxyBlueJettyPacket(request, routes); }
export function HEAD(request) { return proxyBlueJettyPacket(request, routes); }
```

Adapt the relative import to your repository. TypeScript projects may use `.js` with `allowJs`, or supply a local declaration for the helper. Preserve existing routes and framework configuration. Avoid a generic external rewrite that forwards the incoming request's credentials; the explicit allowlist above makes the security boundary inspectable. [Next.js route handlers](https://nextjs.org/docs/app/api-reference/file-conventions/route) support GET and HEAD.

Append the generated HTTP `Link` value to homepage GET and HEAD responses in your server or existing edge middleware. Preserve preload and other Link values. Keep this response-level setup alongside the required descriptor and llms.txt; install the recommended readable body packet link and both required describedby references for extraction coverage.

## Cloudflare Workers / an existing CDN

Import the same reviewed helper locally. Route only your two fixed packet paths to a Worker that calls it:

```javascript
import { proxyBlueJettyPacket } from "./packet-proxy.mjs";
const routes = {
  "/.well-known/bluejetty/apps/APP_ID/packet": "https://bluejetty.ai/v1/apps/APP_ID/packet",
  "/.well-known/bluejetty/apps/APP_ID/packet.md": "https://bluejetty.ai/v1/apps/APP_ID/packet.md"
};
export default {
  fetch(request) { return proxyBlueJettyPacket(request, routes); }
};
```

Merge this into existing Worker routing when applicable; preserve all unrelated website behavior. Configure a cache bypass for both paths and remove conflicting cache rules. Do not use `caches.default`, `cacheEverything`, stale-on-error or a fallback copy. Configure homepage Link headers through your existing Worker/response-header rule; keep existing headers. Cloudflare's [Request API](https://developers.cloudflare.com/workers/runtime-apis/request/) describes fetch options and header handling.

## Cache, updates and withdrawal

### Domain compatibility

The current proxy helper accepts fixed packet targets on both `https://bluejetty.ai` and `https://bluejettyai.com`. Use one origin consistently for a packet's JSON and Markdown pair. Existing `.com` targets remain supported directly; changing a marketing canonical does not require a publisher proxy update. Older downloaded helpers accept only `.com`, so do not change their upstream target without updating and reviewing the helper. Versioned schema identifiers and ownership-proof bindings retain their original URLs.

The release default is **no-store at the origin and proxy**. Every request checks current public availability. The helper preserves ETags for explicitly conditional clients; a 304 confirms the current representation only after origin authorization succeeds. An authorization withdrawal returns 404, even when the client presents an old ETag. Origin/network errors remain failures; they never return a cached successful packet.

A packet update needs no publisher homepage or descriptor redeployment because their URLs stay stable. JSON, Markdown and consumer-specific responses retain separate validators. Keep the User-Agent and optional `consumer` query intact as supported by the helper; they remain declared identities. Never rewrite the publisher's MMP or deep links.

Positive CDN caching is not enabled by this recipe. Enable short caching only after proving per-app/format/consumer isolation and immediate withdrawal invalidation on your own host. A TTL alone delays removal. HTTP directives govern conforming caches, not AI search-index refreshes. [RFC 9111](https://www.rfc-editor.org/rfc/rfc9111.html) defines HTTP reuse and revalidation.

## Direct hosting and self-hosted exports

For direct hosting, omit the descriptor's `delivery` object and use the two Blue Jetty origin URLs in every packet reference. The descriptor remains on your domain; no proxy is required.

For advanced self-hosting, declare `delivery.mode: "self_hosted"` and retain the exact source URLs. Export **only the anonymous public responses**, never owner APIs or private assertion history. Preserve JSON/Markdown identity, revision and handoff content. Publish both formats atomically, with no-store responses. Refresh after every app/configuration change and before any time-limited offer or authorization expires; remove copies immediately on withdrawal. Fail closed if synchronization fails. A periodic copy alone cannot ensure immediate withdrawal: use the live proxy unless you own a reliable synchronization/removal mechanism. Blue Jetty checks current content equality at verification time; that observation is not a continuous managed-freshness guarantee for an exported file.

## Validate after deployment

1. Fetch both first-party paths without cookies or authentication: direct 200, expected content types, no redirects/challenges, no-store and correct app ID.
2. Check homepage GET **and HEAD** for both packet Link references. Verify the descriptor and llms.txt point to those same first-party paths; preserve the website's SEO canonical.
3. Compare each format to its origin using identical User-Agent/consumer inputs. Test a second request and an update without changing the descriptor. Inspect actual CDN headers and bypass behavior.
4. Rehearse revoked/unavailable origin behavior on a controlled test fixture. No stale bytes may be returned. Do not revoke a live customer's authorization for a test.
5. POST publisher-site-verification with the saved `Onboarding-Run-Id`, then read status. Report required failures accurately; a readable initial-HTML body link to the JSON packet with rel="describedby" is strongly recommended, not required. A new UUID is for a deliberately new onboarding run, not every retry.

Blue Jetty analytics measure requests observed **at Blue Jetty's origin**. Forwarded User-Agent values remain declared. CDN cache hits and self-hosted reads may be invisible; no edge-hit collector is installed by this helper. The no-store proxy makes each supported request reach the origin, subject to network success. See [all discovery options](https://bluejetty.ai/insights/how-publishers-make-blue-jetty-discoverable-to-ai).
