Skip to content

cloudflare

AssetR2Object = object

Native R2 metadata: checksums are validated by R2, not custom metadata claims.

readonly version: string

readonly size: number

readonly checksums: object

readonly optional sha256?: ArrayBuffer


AssetR2Bucket = object

Native R2 operations required to verify and serve one asset build.

head(key): Promise<AssetR2Object | null>>

Read immutable object metadata without loading its body.

string

Promise<AssetR2Object | null>

get(key): Promise<AssetR2Object & object | null>>

Read immutable object metadata and its streaming body.

string

Promise<AssetR2Object & object | null>


AppReleaseTransitionObligation = object

Durable catalog-scoped fact awaiting delivery to a separately owned Team.

readonly sequence: number

readonly transition: ReleaseTransition

readonly transitionId: AppTransitionId

readonly affectedPublicSurfaceIds: readonly PublicSurfaceId[]

readonly affectedSurfaces: readonly AppReleaseAffectedSurface[]

Catalog-owned material needed by a Team without a second catalog read.

readonly enumeration: object

The last opaque Global Team cursor and whether enumeration is complete.

readonly cursor: string | null

readonly complete: boolean

readonly state: "pending" | "acknowledged"


AppReleaseAffectedSurface = object

Catalog-owned public-Surface material carried with a transition obligation.

readonly publicSurfaceId: PublicSurfaceId

readonly appId: AppId

readonly stableRoute: StableRoute


AppReleaseTeamRecipient = object

Durable delivery state for one Team recipient of a transition obligation.

readonly teamId: string

readonly state: "pending" | "applied" | "no-op" | "expired"


AppReleaseTeamRecipientPage = object

One ordered page of Team IDs returned by the separately owned Team directory.

readonly optional cursor?: string | null

Null identifies the first page; all later cursors remain opaque strings.

readonly optional nextCursor?: string | null

readonly teamIds: readonly string[]

readonly complete: boolean


AppReleaseTeamRecipientOutcome = "applied" | "no-op" | "expired"

Terminal delivery outcome recorded for one Team recipient.


AppReleaseTransitionObligationStore = object

D1-only at-least-once read/ack seam; Team routing remains outside App Release.

readByTransitionId(transitionId): Promise<AppReleaseStoreResult<AppReleaseTransitionObligation | { kind: "absent"; }>>

Read one obligation by its immutable transition identity, or report it absent.

AppTransitionId

Promise<AppReleaseStoreResult<AppReleaseTransitionObligation | { kind: "absent"; }>>

read(options): Promise<AppReleaseStoreResult<readonly AppReleaseTransitionObligation[]>>

Read pending obligations after a sequence cursor in ascending sequence order.

number

number

Promise<AppReleaseStoreResult<readonly AppReleaseTransitionObligation[]>>

recordTeamRecipientPage(sequence, page): Promise<AppReleaseStoreResult<AppReleaseTransitionObligation | { kind: "absent"; }>>

Persist the next ordered Team-recipient page; identical replays are idempotent.

number

AppReleaseTeamRecipientPage

Promise<AppReleaseStoreResult<AppReleaseTransitionObligation | { kind: "absent"; }>>

readPendingTeamRecipients(options): Promise<AppReleaseStoreResult<readonly AppReleaseTeamRecipient[]>>

Read pending recipients for one obligation in stable Team-ID order.

number

number

Promise<AppReleaseStoreResult<readonly AppReleaseTeamRecipient[]>>

recordTeamRecipientOutcome(sequence, teamId, outcome): Promise<AppReleaseStoreResult<AppReleaseTeamRecipient | { kind: "absent"; }>>

Record a pending recipient’s terminal outcome; conflicting replays fail.

number

string

AppReleaseTeamRecipientOutcome

Promise<AppReleaseStoreResult<AppReleaseTeamRecipient | { kind: "absent"; }>>

acknowledge(sequence): Promise<AppReleaseStoreResult<AppReleaseTransitionObligation | { kind: "absent"; }>>

Acknowledge only after enumeration is complete and no recipients remain pending.

number

Promise<AppReleaseStoreResult<AppReleaseTransitionObligation | { kind: "absent"; }>>


AppReleaseSurfaceTransitionBasis = { kind: "absent"; } | { kind: "ambiguous"; } | { kind: "none"; appId: AppId; publicSurfaceId: PublicSurfaceId; } | { kind: "selected"; appId: AppId; publicSurfaceId: PublicSurfaceId; releaseId: ReleaseId; sequence: number; eligibility: "eligible" | "ineligible"; checkedAt: number; }

Selected Release basis from the same D1 authority snapshot, including its transition sequence.

{ kind: "absent"; }


{ kind: "ambiguous"; }


{ kind: "none"; appId: AppId; publicSurfaceId: PublicSurfaceId; }


{ kind: "selected"; appId: AppId; publicSurfaceId: PublicSurfaceId; releaseId: ReleaseId; sequence: number; eligibility: "eligible" | "ineligible"; checkedAt: number; }

readonly kind: "selected"

readonly appId: AppId

readonly publicSurfaceId: PublicSurfaceId

readonly releaseId: ReleaseId

readonly sequence: number

readonly eligibility: "eligible" | "ineligible"

readonly checkedAt: number

Authority-read start time; consumers may only shorten its horizon.


AppReleaseD1QueryResult = object

Structural result returned by the D1 operations used by App Release.

readonly success: boolean

Whether D1 completed the operation successfully.

readonly results: readonly unknown[]

Untrusted row values returned by the operation.


AppReleaseD1PreparedStatement = object

Structural prepared-statement surface needed by the D1-backed store.

bind(…values): AppReleaseD1PreparedStatement

Bind positional values and return the statement to execute.

…unknown[]

AppReleaseD1PreparedStatement

first(): Promise<object | null>>

Read the first untrusted row, or null when none exists.

Promise<object | null>

all(): Promise<AppReleaseD1QueryResult>>

Read all matching rows.

Promise<AppReleaseD1QueryResult>

run(): Promise<AppReleaseD1QueryResult>>

Execute a mutating statement.

Promise<AppReleaseD1QueryResult>


AppReleaseD1Database = object

Structural D1 surface kept independent of Cloudflare vendor declarations.

prepare(query): AppReleaseD1PreparedStatement

Prepare one SQL statement for binding and execution.

string

AppReleaseD1PreparedStatement

batch(statements): Promise<readonly AppReleaseD1QueryResult[]>

Execute a group of statements atomically in native D1.

readonly AppReleaseD1PreparedStatement[]

Promise<readonly AppReleaseD1QueryResult[]>


AppReleaseR2Object = object

Structural R2 object surface needed by the artifact reader.

readonly version: string

Native immutable object version checked for referenced App children.

readonly size: number

Object size in bytes, checked before the body is buffered.

readonly optional httpMetadata?: object

HTTP metadata retained with the object, when present.

readonly optional contentType?: string

Declared media type for the stored object.

arrayBuffer(): Promise<ArrayBuffer>>

Read the immutable object body.

Promise<ArrayBuffer>


AppReleaseR2Bucket = object

Structural R2 surface kept independent of Cloudflare vendor declarations.

get(key): Promise<AppReleaseR2Object | null>>

Read one object by its opaque storage key.

string

Promise<AppReleaseR2Object | null>


ErasureBucket = AppReleaseR2Bucket & object

R2 operations used by the scoped Team erasure owner.

head(key): Promise<object | null>>

Read the metadata for an exact object key.

string

Promise<object | null>

delete(key): Promise<void>>

Delete an exact object key after catalog references are checked.

string

Promise<void>


ArtifactSnapshotPolicy = Readonly<{ maxBytes: number; maxManifestBytes?: number; }>

Trusted composition limit for reading one immutable artifact.

const APP_RELEASE_D1_FRESH_SCHEMA: “\nCREATE TABLE app_release_apps (app_id TEXT PRIMARY KEY) STRICT;\nCREATE TABLE app_release_releases (release_id TEXT PRIMARY KEY, app_id TEXT NOT NULL REFERENCES app_release_apps(app_id), artifact_ref TEXT NOT NULL, artifact_digest TEXT NOT NULL, source_revision TEXT NOT NULL, source_tree_digest TEXT NOT NULL, build_recipe_digest TEXT NOT NULL) STRICT;\nCREATE TABLE app_release_release_verifications (release_id TEXT PRIMARY KEY REFERENCES app_release_releases(release_id), artifact_digest TEXT NOT NULL) STRICT;\nCREATE TABLE app_release_release_verification_formats (release_id TEXT PRIMARY KEY REFERENCES app_release_releases(release_id), media_type TEXT NOT NULL) STRICT;\nCREATE TABLE app_release_public_surfaces (public_surface_id TEXT PRIMARY KEY, app_id TEXT NOT NULL REFERENCES app_release_apps(app_id), stable_route TEXT NOT NULL) STRICT;\nCREATE TABLE app_release_transitions (sequence INTEGER PRIMARY KEY AUTOINCREMENT, transition_id TEXT NOT NULL UNIQUE, operation_kind TEXT NOT NULL, idempotency_key TEXT NOT NULL, release_id TEXT NOT NULL, public_surface_id TEXT, UNIQUE (operation_kind, idempotency_key)) STRICT;\nCREATE INDEX app_release_public_surfaces_stable_route_idx ON app_release_public_surfaces (stable_route, public_surface_id);\nCREATE INDEX app_release_transitions_selected_surface_idx ON app_release_transitions (public_surface_id, operation_kind, sequence DESC) WHERE operation_kind IN (‘promotion’, ‘rollback’);\nCREATE INDEX app_release_transitions_revoked_release_idx ON app_release_transitions (release_id, operation_kind) WHERE operation_kind = ‘revocation’;\nCREATE TABLE app_release_transition_obligations (sequence INTEGER PRIMARY KEY REFERENCES app_release_transitions(sequence), transition_id TEXT NOT NULL UNIQUE, operation_kind TEXT NOT NULL, idempotency_key TEXT NOT NULL, release_id TEXT NOT NULL, public_surface_id TEXT, state TEXT NOT NULL CHECK(state IN (‘pending’,‘acknowledged’))) STRICT;\nCREATE INDEX app_release_transition_obligations_pending_idx ON app_release_transition_obligations(state, sequence);\nCREATE TABLE app_release_transition_obligation_enumeration (sequence INTEGER PRIMARY KEY REFERENCES app_release_transition_obligations(sequence), cursor TEXT, started INTEGER NOT NULL DEFAULT 0 CHECK(started IN (0, 1)), complete INTEGER NOT NULL DEFAULT 0 CHECK(complete IN (0, 1))) STRICT;\nCREATE TABLE app_release_transition_obligation_pages (sequence INTEGER NOT NULL REFERENCES app_release_transition_obligations(sequence), cursor TEXT, cursor_is_initial INTEGER NOT NULL CHECK(cursor_is_initial IN (0, 1)), cursor_key TEXT NOT NULL, next_cursor TEXT, complete INTEGER NOT NULL CHECK(complete IN (0, 1)), team_ids_json TEXT NOT NULL CHECK(json_valid(team_ids_json)), PRIMARY KEY(sequence, cursor_is_initial, cursor_key)) STRICT;\nCREATE TABLE app_release_transition_obligation_teams (sequence INTEGER NOT NULL REFERENCES app_release_transition_obligations(sequence), team_id TEXT NOT NULL CHECK(length(team_id) BETWEEN 1 AND 256), state TEXT NOT NULL CHECK(state IN (‘pending’, ‘applied’, ‘no-op’, ‘expired’)), PRIMARY KEY(sequence, team_id)) STRICT;\nCREATE INDEX app_release_transition_obligation_teams_pending_idx ON app_release_transition_obligation_teams(sequence, state, team_id);\nCREATE TABLE app_release_team_publishers (app_id TEXT PRIMARY KEY REFERENCES app_release_apps(app_id), team_id TEXT NOT NULL CHECK(length(team_id) BETWEEN 1 AND 256), source_provider TEXT NOT NULL CHECK(source_provider IN (‘artifacts’,‘github’)), source_repository TEXT NOT NULL CHECK(length(source_repository) BETWEEN 1 AND 1024), source_branch TEXT NOT NULL CHECK(source_branch = ‘main’), template_app_id TEXT, template_seed_revision TEXT, CHECK((template_app_id IS NULL) = (template_seed_revision IS NULL))) STRICT;\nCREATE INDEX app_release_team_publishers_team_idx ON app_release_team_publishers(team_id, app_id);\nCREATE TABLE app_release_release_verification_metadata (release_id TEXT PRIMARY KEY REFERENCES app_release_release_verifications(release_id), artifact_digest TEXT NOT NULL, description_json TEXT NOT NULL CHECK(json_valid(description_json))) STRICT;\nCREATE TABLE publisher_template_seed_receipts (template_repository TEXT NOT NULL, seed_revision TEXT NOT NULL, platform_app_id TEXT NOT NULL, source_revision TEXT NOT NULL, source_tree_digest TEXT NOT NULL, recipe_json TEXT CHECK(recipe_json IS NULL OR json_valid(recipe_json)), build_recipe_digest TEXT CHECK(build_recipe_digest IS NULL OR (length(build_recipe_digest) = 71 AND substr(build_recipe_digest, 1, 7) = ‘sha256:’ AND substr(build_recipe_digest, 8) NOT GLOB ‘*[^0-9a-f]*’)), CHECK((recipe_json IS NULL) = (build_recipe_digest IS NULL)), PRIMARY KEY (template_repository, seed_revision)) STRICT;\nCREATE TABLE publisher_artifacts_repositories (repository_name TEXT PRIMARY KEY CHECK(length(repository_name) BETWEEN 1 AND 128), provider_id TEXT NOT NULL CHECK(length(provider_id) > 0), default_branch TEXT NOT NULL CHECK(default_branch = ‘main’), remote TEXT NOT NULL CHECK(length(remote) > 0), parent_repository TEXT REFERENCES publisher_artifacts_repositories(repository_name), CHECK(parent_repository IS NULL OR parent_repository <> repository_name)) STRICT;\nCREATE TRIGGER app_release_apps_write_once BEFORE UPDATE ON app_release_apps BEGIN SELECT RAISE(ABORT, ‘App Release apps are write-once’); END;\nCREATE TRIGGER app_release_releases_write_once BEFORE UPDATE ON app_release_releases BEGIN SELECT RAISE(ABORT, ‘App Release releases are write-once’); END;\nCREATE TRIGGER app_release_verifications_write_once BEFORE UPDATE ON app_release_release_verifications BEGIN SELECT RAISE(ABORT, ‘App Release verifications are write-once’); END;\nCREATE TRIGGER app_release_verification_formats_write_once BEFORE UPDATE ON app_release_release_verification_formats BEGIN SELECT RAISE(ABORT, ‘App Release verification formats are write-once’); END;\nCREATE TRIGGER app_release_public_surfaces_write_once BEFORE UPDATE ON app_release_public_surfaces BEGIN SELECT RAISE(ABORT, ‘App Release public Surfaces are write-once’); END;\nCREATE TRIGGER app_release_transitions_write_once BEFORE UPDATE ON app_release_transitions BEGIN SELECT RAISE(ABORT, ‘App Release transitions are write-once’); END;\nCREATE TRIGGER app_release_transition_obligation_enumeration_after_insert AFTER INSERT ON app_release_transition_obligations BEGIN INSERT OR IGNORE INTO app_release_transition_obligation_enumeration(sequence) VALUES (NEW.sequence); END;\nCREATE TRIGGER app_release_transition_obligation_after_insert AFTER INSERT ON app_release_transitions WHEN NEW.operation_kind = ‘revocation’ BEGIN INSERT INTO app_release_transition_obligations (sequence, transition_id, operation_kind, idempotency_key, release_id, public_surface_id, state) VALUES (NEW.sequence, NEW.transition_id, NEW.operation_kind, NEW.idempotency_key, NEW.release_id, NEW.public_surface_id, ‘pending’); END;\nCREATE TRIGGER app_release_team_publishers_write_once BEFORE UPDATE ON app_release_team_publishers BEGIN SELECT RAISE(ABORT, ‘App publisher registrations are write-once’); END;\nCREATE TRIGGER app_release_verification_metadata_write_once BEFORE UPDATE ON app_release_release_verification_metadata BEGIN SELECT RAISE(ABORT, ‘App Release verification metadata is write-once’); END;\nCREATE TRIGGER app_release_team_publishers_template_seed_pair BEFORE INSERT ON app_release_team_publishers WHEN (NEW.template_app_id IS NULL) != (NEW.template_seed_revision IS NULL) BEGIN SELECT RAISE(ABORT, ‘App publisher template seed pointer is incomplete’); END;\nCREATE TRIGGER app_release_team_publishers_artifacts_seed_required BEFORE INSERT ON app_release_team_publishers WHEN NEW.source_provider = ‘artifacts’ AND NEW.template_app_id IS NULL BEGIN SELECT RAISE(ABORT, ‘Artifacts App publisher requires verified template seed provenance’); END;\nCREATE TRIGGER app_release_team_publishers_artifacts_seed_verified BEFORE INSERT ON app_release_team_publishers WHEN NEW.source_provider = ‘artifacts’ AND NOT EXISTS (SELECT 1 FROM publisher_template_seed_receipts WHERE platform_app_id = NEW.template_app_id AND seed_revision = NEW.template_seed_revision AND recipe_json IS NOT NULL AND build_recipe_digest IS NOT NULL) BEGIN SELECT RAISE(ABORT, ‘Artifacts App publisher template seed is not verified’); END;\nCREATE TRIGGER publisher_template_seed_receipts_write_once BEFORE UPDATE ON publisher_template_seed_receipts BEGIN SELECT RAISE(ABORT, ‘Publisher template seed receipts are write-once’); END;\nCREATE TRIGGER publisher_template_seed_receipts_append_only BEFORE DELETE ON publisher_template_seed_receipts BEGIN SELECT RAISE(ABORT, ‘Publisher template seed receipts are append-only’); END;\nCREATE TRIGGER publisher_template_seed_recipe_required BEFORE INSERT ON publisher_template_seed_receipts WHEN NEW.recipe_json IS NULL OR json_valid(NEW.recipe_json) = 0 OR NEW.build_recipe_digest IS NULL BEGIN SELECT RAISE(ABORT, ‘Publisher template seed recipe proof is incomplete’); END;\nCREATE TRIGGER publisher_artifacts_repositories_write_once BEFORE UPDATE ON publisher_artifacts_repositories BEGIN SELECT RAISE(ABORT, ‘Publisher Artifacts repository metadata is write-once’); END;\nCREATE TABLE publisher_artifacts_repositories_pending (repository_name TEXT PRIMARY KEY CHECK(length(repository_name) BETWEEN 1 AND 128), provider_id TEXT NOT NULL CHECK(length(provider_id) > 0), default_branch TEXT NOT NULL CHECK(default_branch = ‘main’), remote TEXT NOT NULL CHECK(length(remote) > 0), parent_repository TEXT REFERENCES publisher_artifacts_repositories(repository_name), initial_token TEXT NOT NULL CHECK(length(initial_token) > 0), CHECK(parent_repository IS NULL OR parent_repository <> repository_name)) STRICT;\nCREATE TRIGGER publisher_artifacts_repositories_pending_write_once BEFORE UPDATE ON publisher_artifacts_repositories_pending BEGIN SELECT RAISE(ABORT, ‘Publisher Artifacts recovery state is write-once’); END;\nCREATE TABLE app_release_erasure_scope (singleton INTEGER PRIMARY KEY CHECK(singleton=1), app_id TEXT NOT NULL) STRICT;\nCREATE TABLE app_release_erasure_jobs (app_id TEXT PRIMARY KEY, team_id TEXT NOT NULL, object_keys_json TEXT NOT NULL CHECK(json_valid(object_keys_json)), repository_name TEXT) STRICT;\nCREATE TRIGGER app_release_apps_append_only BEFORE DELETE ON app_release_apps WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=OLD.app_id) BEGIN SELECT RAISE(ABORT, ‘App Release apps are append-only’); END;\nCREATE TRIGGER app_release_releases_append_only BEFORE DELETE ON app_release_releases WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=OLD.app_id) BEGIN SELECT RAISE(ABORT, ‘App Release releases are append-only’); END;\nCREATE TRIGGER app_release_verifications_append_only BEFORE DELETE ON app_release_release_verifications WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=(SELECT app_id FROM app_release_releases WHERE release_id=OLD.release_id)) BEGIN SELECT RAISE(ABORT, ‘App Release verifications are append-only’); END;\nCREATE TRIGGER app_release_verification_formats_append_only BEFORE DELETE ON app_release_release_verification_formats WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=(SELECT app_id FROM app_release_releases WHERE release_id=OLD.release_id)) BEGIN SELECT RAISE(ABORT, ‘App Release verification formats are append-only’); END;\nCREATE TRIGGER app_release_public_surfaces_append_only BEFORE DELETE ON app_release_public_surfaces WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=OLD.app_id) BEGIN SELECT RAISE(ABORT, ‘App Release public Surfaces are append-only’); END;\nCREATE TRIGGER app_release_transitions_append_only BEFORE DELETE ON app_release_transitions WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=(SELECT app_id FROM app_release_releases WHERE release_id=OLD.release_id)) BEGIN SELECT RAISE(ABORT, ‘App Release transitions are append-only’); END;\nCREATE TRIGGER app_release_team_publishers_append_only BEFORE DELETE ON app_release_team_publishers WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=OLD.app_id) BEGIN SELECT RAISE(ABORT, ‘App publisher registrations are append-only’); END;\nCREATE TRIGGER app_release_verification_metadata_append_only BEFORE DELETE ON app_release_release_verification_metadata WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=(SELECT app_id FROM app_release_releases WHERE release_id=OLD.release_id)) BEGIN SELECT RAISE(ABORT, ‘App Release verification metadata is append-only’); END;\nCREATE TRIGGER publisher_artifacts_repositories_append_only BEFORE DELETE ON publisher_artifacts_repositories WHEN NOT EXISTS (SELECT 1 FROM app_release_erasure_scope WHERE app_id=(SELECT app_id FROM app_release_team_publishers WHERE source_provider=‘artifacts’ AND source_repository=OLD.repository_name)) BEGIN SELECT RAISE(ABORT, ‘Publisher Artifacts repository metadata is append-only’); END;\n”

The one current App Release D1 schema for an empty catalog.

createTeamAppReleaseErasure(database, bucket, assetPolicy?): object

Read every catalog reference before deleting content-addressed R2 objects.

AppReleaseD1Database

ErasureBucket

number = positiveInteger

number = positiveInteger

number = positiveInteger

number = positiveInteger

verifyManifest(teamId, appIds, keys): Promise<{ teamId: string; apps: object[]; repositories: string[]; }>

Reject any live App or R2 key outside this Team’s current or retry scope.

string

readonly string[]

readonly string[]

Promise<{ teamId: string; apps: object[]; repositories: string[]; }>

preflight(teamId): Promise<{ teamId: string; apps: object[]; repositories: string[]; }>

Inventory Team catalog rows, exclusive objects, and source repositories.

string

Promise<{ teamId: string; apps: object[]; repositories: string[]; }>

erase(teamId): Promise<{ apps: number; }>

Remove one Team’s catalog and exclusive objects, resuming pending jobs.

string

Promise<{ apps: number; }>

readback(teamId, appIds, keys): Promise<{ clear: boolean; remaining: string[]; pending: string[]; obligationTeams: string[]; obligationPages: string[]; objects: string[]; }>

Verify the named Apps, pending jobs, obligations and exclusive objects.

string

readonly string[]

readonly string[]

Promise<{ clear: boolean; remaining: string[]; pending: string[]; obligationTeams: string[]; obligationPages: string[]; objects: string[]; }>


createD1TeamAppPublisherRegistry(database): TeamAppPublisherRegistry

Create the native registry that joins a Team publisher to one App/source.

AppReleaseD1Database

TeamAppPublisherRegistry


createD1AppReleaseStore(database): PromiseAppReleaseStore & object

Create the D1-backed App Release store with private public-website authority.

AppReleaseD1Database

PromiseAppReleaseStore & object


createR2ArtifactReader(bucket, policy?, assets?): ArtifactReader

Create the R2-backed artifact reader for opaque artifact references.

Asset manifests are verified cheaply for delivery: the root bytes are digest-checked here, while the asset handler checks the requested object. Publication callers pass verification: "publication" to retain the complete manifest object sweep.

AppReleaseR2Bucket

ArtifactSnapshotPolicy = DEFAULT_ARTIFACT_SNAPSHOT_POLICY

Pick<AssetR2Bucket, "head">

{ maxManifestBytes: number; maxObjects: number; maxObjectBytes: number; maxTotalBytes: number; }

number = positiveInteger

number = positiveInteger

number = positiveInteger

number = positiveInteger

ArtifactReader


createD1TransitionObligationStore(database): AppReleaseTransitionObligationStore

Open the D1-only obligation adjunct for a future owner-driven dispatcher. The ordinary App Release store contract intentionally does not expose it.

AppReleaseD1Database

AppReleaseTransitionObligationStore


readD1SurfaceTransitionBasis(database, stableRoute, releaseId, now?): Promise<AppReleaseStoreResult<AppReleaseSurfaceTransitionBasis>>>>

Resolve one previously selected Release on a Surface and retain the exact transition sequence. The Release need not remain the Surface’s current default, but it must still be verified, active, and owned by that Surface.

AppReleaseD1Database

StableRoute

ReleaseId

() => number

Promise<AppReleaseStoreResult<AppReleaseSurfaceTransitionBasis>>


matchEligibleSurfaceTransitionBasis(result, expected): { kind: "selected"; appId: AppId; publicSurfaceId: PublicSurfaceId; releaseId: ReleaseId; sequence: number; eligibility: "eligible" | "ineligible"; checkedAt: number; } | null

Match one eligible selected Release without leaking store-result branching to consumers.

AppReleaseStoreResult<AppReleaseSurfaceTransitionBasis>

Readonly<{ appId: AppId; releaseId: ReleaseId; sequence?: number; }>

{ kind: "selected"; appId: AppId; publicSurfaceId: PublicSurfaceId; releaseId: ReleaseId; sequence: number; eligibility: "eligible" | "ineligible"; checkedAt: number; }

readonly kind: "selected"

readonly appId: AppId

readonly publicSurfaceId: PublicSurfaceId

readonly releaseId: ReleaseId

readonly sequence: number

readonly eligibility: "eligible" | "ineligible"

readonly checkedAt: number

Authority-read start time; consumers may only shorten its horizon.


null