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 the app map in your release workflow. Blue Jetty records who supplied it, preserves complete revisions, checks publisher authority and exposes current freshness separately from the publisher's content.
Canonical API: https://bluejetty.ai. Every owner operation below requires Authorization: Bearer $BLUEJETTY_API_KEY. Keep credentials in local environment variables or your CI secret store. OpenAPI lists the complete HTTP contract.
1. Know what is public
Public packets omit optional fields without publishable values, after current app-entitlement checks. Missing values are not negative feature claims or instructions to clear stored data. Owner configuration and submission reset semantics remain unchanged; see public packet field semantics.
Packet retrieval versus proof binding
Use urls.packetJson as the default packet retrieval URL; urls.packetMarkdown is an alternative for compatible clients. app.publisherAuthorization.packetUrl records the exact URL bound into the ownership proof. Existing proofs use the .md URL, which remains valid evidence and does not express a Markdown-first preference. Do not rewrite that value or the publisher's proof file to change a discovery link: changing the binding can invalidate verification. No re-verification is needed simply to make a website link prefer JSON.
An app's public pages, packet JSON/Markdown, entities, feeds, lookup, search and sitemap entries require all of these:
- Public publication intent (
publication.publicSelectionMetadata: trueon submission). - Current publisher authorization for the exact organization, website hostname, app store identities and packet URL.
- A successful nonempty current entity corpus.
Before authorization, the app is an owner-readable draft. Samples stay private even with valid authorization. Unverified, expired or revoked publisher records return 404 from anonymous app surfaces and disappear from the public catalog. Independent pre-seed discovery profiles have a separate publication policy and do not inherit publisher authority.
Use publisher authorization to publish the scoped proof file and connect your website. Preserve the site's own SEO canonical. Public packet links in /llms.txt support discovery; the proof file and independently corroborated store identity establish authority.
Discovery after updates
Use the delivery guide for fixed first-party proxy paths, or keep direct Blue Jetty URLs. Stable discovery pointers need no redeployment when app metadata changes. Public JSON and Markdown packets use format/content-specific ETags; an explicitly conditional client may send If-None-Match. Eligibility is checked before 200 or 304. If-Modified-Since alone is not sufficient because offers, entitlements and authorization can change independently of the app assertion timestamp. The safe release configuration is no-store, including the CDN; immutable public history and positive shared caching are not enabled.
After changing publisher-site discovery configuration, run POST /v1/apps/{appId}/publisher-site-verification using the saved Onboarding-Run-Id. Reuse it across retries and repairs. Evidence expires after 24 hours and after app changes; scheduled bounded checks refresh evidence but never send completion emails. API/dashboard reads do not crawl the website. A deliberately new onboarding run can receive one confirmation naming the checked website and detected paths.
Detailed crawler activity includes discoveryLatency: first public eligibility of each revision to its first origin-observed successful packet fetch or revalidation, with unfetched revisions and sample sizes. Private drafts are excluded. Pre-release public records have a labeled rollout baseline excluded from medians. These are declared User-Agent observations; CDN cache hits and self-hosted reads may be invisible. Changes to time-dependent projection fields without a new revision are not additional latency samples. Data is retained for 90 days.
Revocation removes eligibility immediately on subsequent origin reads. It retains owner data and history. Previously downloaded copies are outside Blue Jetty's control. Changing the organization, website or store identity invalidates the proof, including when an old identity is later restored.
2. Read before updating
GET /v1/apps/{appId}/publication returns the owner app/source preview, current version, etag, revisionId, authorization and up to 20 history summaries. Use data.etag as the write precondition. The owner /status endpoint returns data.publication.etag; both endpoints also expose X-BlueJetty-Publication-ETag and are private/no-store.
curl --fail-with-body --include \
"https://bluejetty.ai/v1/apps/$APP_ID/publication" \
--header "Authorization: Bearer $BLUEJETTY_API_KEY"For example, a response containing X-BlueJetty-Publication-ETag: "bj-publication-3" means the next publisher write should send that exact quoted value:
curl --fail-with-body \
"https://bluejetty.ai/v1/apps/$APP_ID" \
--request PATCH \
--header "Authorization: Bearer $BLUEJETTY_API_KEY" \
--header 'If-Match: "bj-publication-3"' \
--header "Content-Type: application/json" \
--data '{"description":"Compare beginner-friendly surf spots and open their guides in the app."}'Read the canonical token from data.etag or the X-BlueJetty-Publication-ETag response header and copy it unchanged into If-Match. A CDN may prefix the standard HTTP ETag with W/ during compression; that transport header is not the update token. Do not send the weakened value.
Use the version you actually read. Each successful mutation advances the app-wide publication version. Concurrent writers using the same version have one winner; a stale writer gets 412 BJ_PUBLICATION_CONFLICT with the current version and commits nothing. Re-read, compare and reconcile before retrying. Missing preconditions return 428 BJ_PUBLICATION_PRECONDITION_REQUIRED.
If-Match is required for app metadata updates/deletion, source creation/updates/deletion, source refresh, entity snapshots, full publication restore, and submissions that update an existing app. First app creation and replay of a completed idempotent submission do not require it. Configuration staging/activation retain their expectedActiveRevisionId contract; activation also records a complete publication revision. Proof operations retain their separate authorization expectedVersion. Store observations use their observation timestamps to reject older replacements.
3. Replace a source safely
Profile 0.1 uses complete snapshots. Send the complete intended source contents, a new snapshotId, the current publication ETag and, for /v1/submissions, a new Idempotency-Key. A successful snapshot tombstones omitted records. Review those deletions explicitly.
A full snapshot containing any malformed or duplicate record is rejected as a whole with 422 BJ_CONTRACT_INVALID. Nothing is partially published or deleted. Validation previews expose accepted/rejected counts and valid: false when records need repair. An empty snapshot cannot clear a source; delete the source explicitly if that is the intended operation.
Entity IDs are stable within an app. An entity ID already assigned to another source returns 409 BJ_ENTITY_SOURCE_CONFLICT; ordinary refreshes cannot silently move it. A committed snapshotId cannot be reused, even with another idempotency key. 409 BJ_SNAPSHOT_ID_REUSED asks you to inspect current state and use a new ID for a new update.
The submission's app metadata, source definition, entities, history and stored success response commit in one transaction. A failed update preserves the last successful corpus and revision. A conflicting idempotency request cannot change the original request's result. Retry an ambiguous submission with the same key and identical body; a successful replay performs no writes. An interrupted processing claim becomes retryable after five minutes. Do not switch keys to bypass a processing conflict.
Pull feeds are fetched before the write lock. Their result commits only if the app is still at the version captured before the fetch. Fetch/parsing/incomplete-sitemap failures record a safe source error and failed run, retain the last success, and schedule a bounded retry. Truncated or partly failed sitemap extraction cannot replace an existing corpus. Use an explicit complete feed when discovery exceeds the page limit.
Inline submissions remain capped at 4,000,000 bytes and 1,000 entities by default. These are transport limits, separate from the app-mapping guidance. Keep large dynamic datasets in the app unless selected richer metadata materially improves agent understanding or routing.
4. Export, compare and restore
Every successful publisher-data mutation creates an immutable publication revision. It contains:
- App identity, publisher text, indexed versions, publication intent and complete managed configuration.
- Source definitions and references to immutable source-record snapshots.
- A monotonically increasing version, opaque revision ID, SHA-256 content hash, parent ID, actor, reason and timestamp.
Current account membership, billing state, authorization proof, store observations and destination checks are evaluated independently. They are excluded from restorable publisher assertions. Source snapshots retain original profile records and stable entity IDs. The latest 100 publication revisions are retained per app; unreferenced archives are removed with history cleanup. Export revisions you need to retain longer. App deletion removes its entire publication history and corpus.
List: GET /v1/apps/{appId}/publication?offset=0 (20 summaries per page; offset 0–100).
Inspect: GET /v1/apps/{appId}/publication/revisions/{revisionId}. diffFromActive reports changed app fields and added, removed or changed sources. The response includes complete publisher assertions and source snapshot references.
Export: add ?export=jsonl to the revision URL. The download streams one publication_revision line followed by source_record lines containing the source ID, immutable snapshot ID and raw entity record. Consume the complete stream and retain the revision hash. Exports are owner-only and private/no-store.
Restore: POST /v1/apps/{appId}/publication/revisions/{revisionId}/restore, with the current If-Match. This replaces current publisher assertions and source contents atomically and appends a new revision with restoredFromRevisionId. Sources absent from the historical revision are removed. Capability permissions and platform configuration are rechecked. An unavailable archive or invalid configuration leaves current state unchanged.
Restore never rolls back billing, the installed app, store versions or current account rights. It uses a new configuration revision and resets destination checks. Old verified link evidence cannot become current again. Identity changes revoke authorization; unchanged identity still depends on its current proof. After an ambiguous restore response, read publication history to confirm the new revision before trying another write.
5. Read freshness as current evidence
- Entity freshness is evaluated at read time: fresh through seven days, aging through 30 days, then stale. Missing or future publisher timestamps are unknown. Fetching unchanged data does not advance the publisher's content timestamp.
- Destination HTTP observations apply to the exact URL checked. Changing a URL clears its old health. Checks older than seven days become unknown for routing; configuration execution evidence exposes its separate stale state. Results commit only against the publication version that started the check, so an in-flight check cannot certify a replacement or restored publication, even if its URL is identical.
- Observations posted by a publisher are publisher-declared even when their
sourcenames an authorized store API. Automatic Growth iOS App Store observations retain their separate Blue Jetty observation source. Future timestamps are rejected. Older observations and conflicting same-time observations return409; identical same-time observations are harmless. After seven days, the derived release comparison becomes unknown until a new observation arrives. - A caller cannot set
public_corroboratedthrough source creation/update. Source origin at ingestion is retained with the record. Labels supplied by a publisher do not establish independent verification. - Public packet/entity publication version and revision identifiers connect current representations to owner-readable assertion history. Authorization and HTTP evidence retain their own clocks.
6. Put maintenance in your release workflow
- GET the current owner publication, inspect its revision and retain its ETag with the proposed release change.
- Validate the full source snapshot, review omitted IDs, then submit with that ETag and a release-specific idempotency key. Save the returned app/source/publication IDs.
- Stage and activate managed configuration using its own current configuration revision. Retain both revision identifiers in release artifacts.
- After store rollout, post a current store observation. Use the owner API to inspect drafts or expired publications; public release endpoints require current publication eligibility.
- Recheck changed destinations. Inspect authorization and source status; do not infer device arrival or attribution credit from an HTTP check.
- Compare with the previous publication and restore deliberately if the app map needs rollback. Recheck affected proof and links afterward.
The onboarding CLI accepts --expected-version N for an existing app. Obtain N from the owner publication API and review current data before using it. The CLI intentionally leaves conflict reconciliation to the publisher or authorized agent.
Scheduled checks and recovery
Authorization is rechecked approximately six hours after success, with a maximum 24-hour validity bounded by underlying relationship evidence. The scheduler polls every ten minutes in bounded batches. Transient failures use 15-minute exponential backoff capped at six hours; current publication fails closed when authorization fails or expires. Android normally uses automatic Google Play identity/website checks. Exceptional operator reviews require renewal before their own expiry.
Daily sources become due 24 hours after successful ingestion. Jobs use per-record five-minute leases and oldest-due-first ordering, so overlapping invocations cannot claim the same work. Failed source status includes a safe error code, attempt time, consecutive failure count and next scheduled retry. A process interruption leaves work reclaimable after lease expiry.
Scheduled refresh fetches use a two-second per-request/DNS timeout, at most two same-domain redirects, and a 45-second sitemap inspection budget checked between pages. Exceeding the budget retains the previous corpus and records a retryable failure. Publish a compact complete feed if sitemap inspection regularly exceeds these limits.
Owner authorization/source APIs expose maintenance status. Authenticated cron responses report backlog counts and oldest due time; structured operator log events flag failed work or backlog. These are operational signals. Email or external-monitor delivery requires a separately configured and tested destination.
Migration from earlier clients
Existing app IDs, source IDs and stored payload versions are preserved. Use configuration 0.5 for new maps; profile 0.1 remains the entity submission contract. Older configuration 0.2/0.3 revisions retain their compatibility behavior; see contract versions. Legacy records start at publication version 0. Their first successful mutation captures the current stored corpus as a baseline; Blue Jetty cannot reconstruct revisions from before history existed.
Update clients to read an ETag and send If-Match before their next existing-app write. Complete current publisher authorization before expecting anonymous packet access. Replace any caller-supplied public_corroborated source label with the appropriate origin assertion. Keep store observations recent and retain revision exports if you need history beyond 100 changes.
Link-recipe changes
Optional configuration 0.4 recipes follow the same preconditions, staging/activation and complete publication history. Re-test choices, bindings and examples when app routes or provider settings change. Removing a recipe preserves its history and concrete fallback URL. Restoring configuration never restores authorization or stale testing evidence. HTTP observations cover the fixed execution URL, not every assembled variant. See assistant-assembled links.
