> ## Documentation Index
> Fetch the complete documentation index at: https://oxy.tech/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Oxy Functions, Resumable Airway Backfills, a Custom-Apps Deployment Console, and World Model Graph Drill-Down

> Server-side TypeScript handlers inside customer apps, chunked crash-resumable ELT backfills, a redesigned admin console for managing custom-app deployments, and an explorable World Model graph.

<Icon icon="calendar" iconType="regular" size={16} /> **July 3, 2026** · v0.5.95, v0.5.96, v0.5.97, v0.5.98, v0.5.99, v0.5.100, v0.5.101, v0.5.102

### New Features

#### Oxy Functions

Custom apps can now ship their own server-side logic. **Oxy Functions** are TypeScript handlers that live inside a custom-app bundle and run on Oxy's managed runtime with direct, first-class access to your project's data plane — query the warehouse, run a semantic query, trigger an Airway pipeline, or call an external API, all without standing up any separate backend.

* **Data-plane native** - Each function receives a `ctx` with direct access to the tools you already use: `ctx.query` for SQL, `ctx.semantic.query` for the semantic layer, `ctx.airway.run` for ELT pipelines, `ctx.warehouse.*` for warehouse writes, and `ctx.fetch` for outbound HTTP — no extra infrastructure to wire up.
* **Three ways to run** - Invoke a function as an HTTP route called from your React app, run it on a cron **schedule** for periodic ETL, or drop it into an Airway pipeline as a custom transform step.
* **Call it from React** - A `useFunction(name)` hook in the SDK invokes a function from your app's frontend and streams the result back, so an app can trigger real server-side work in response to a user action.
* **Versioned with your app** - Functions are declared in `oxy-app.json`, bundled at publish time, and ship inside the same build artifact as the frontend — so promoting or rolling back an app moves its frontend and backend together, never out of sync.
* **Safe by default** - Functions run in an isolated sandbox with per-user rate limiting, request timeouts, an outbound-fetch allowlist, and a full audit trail of every invocation.

Declare functions in `oxy-app.json`, then call one from your app with the SDK hook:

```typescript theme={null}
const runReport = useFunction("daily_report");
await runReport({ month: "2026-07" });
```

#### Scheduled Oxy Functions

Oxy Functions can now run on their own cron schedule as durable background jobs — and write secrets back to your project — turning a function into a self-contained scheduled task with no external orchestrator to stand up.

* **Cron-scheduled functions** - Declare a `schedule` on a function in `oxy-app.json` and `oxy publish` registers it to fire on that cron cadence. Each run executes on Oxy's durable task queue with exactly-once firing across a multi-instance fleet, so a scheduled function never double-fires and a missed tick collapses to a single run.
* **Write secrets from a function** - A new `ctx.secrets.set(key, value)` lets a scheduled function persist a value — such as a freshly refreshed API token — back into Oxy Secrets, where every request-time function then reads it via `ctx.env`. One refresher writes, many readers consume, so a rotating credential stays consistent across the whole app.
* **Visible run history** - Scheduled function runs surface in the Schedules "recent runs" view with their status and history, alongside your other scheduled automations, pipelines, and agents.
* **Capability-gated writes** - Secret writes are opt-in and fail closed: a function must declare the `secrets.write` capability in its manifest before it can call `ctx.secrets.set`.

A common use is a token refresher that keeps an external credential current for all of an app's other functions:

```typescript theme={null}
// functions/refresh-token.ts — { "schedule": "*/50 * * * *", "secrets": { "write": true } }
export default async function (ctx) {
  const token = await refreshUpstreamToken();
  await ctx.secrets.set("QB_TOKEN", token);
}
```

#### Resumable Chunked Airway Backfills

Backfilling a long history through an Airway ELT pipeline no longer has to be an all-or-nothing job. A new backfill primitive splits a long date range into calendar-aligned period chunks, runs each one as its own bounded backfill, and records progress as it goes — so a crash or cancellation resumes where it left off instead of restarting years of loading from scratch.

* **Chunked, resumable backfills** - `oxy airway backfill --pipeline <pipeline> --from <start> --to <end> --granularity month|week|day` enumerates the range into gapless period chunks and runs each in turn. Re-running skips chunks already loaded and retries only the ones that failed, so an interrupted backfill picks back up cleanly.
* **Coverage reporting** - `oxy airway coverage --pipeline <pipeline>` shows which periods are done, failed, or still pending, along with the loaded range — an at-a-glance answer to "what data is actually loaded, and what's still missing?"
* **Works with any pipeline** - Because a chunk is just one bounded Airway run, chunked backfill and coverage apply to any pipeline (Toast, QuickBooks, and others) with no per-pipeline changes.

```bash theme={null}
oxy airway backfill restaurant_analytics.airway.yml \
  --from 2020-01-01T00:00:00Z --to 2026-07-01T00:00:00Z --granularity month

oxy airway coverage restaurant_analytics.airway.yml
```

#### Custom-Apps Deployment Console

The admin **Apps** surface has been reworked from a dense list into a full deployment-platform console for Global Owner and Global Admin operators who manage custom-app deployments across every workspace.

* **Gallery and list views** - Toggle between a responsive card gallery (default) and a dense, sortable table with a sticky header. The active view, along with your search, filters, grouping, and sort, is persisted in the URL so any state is shareable with a link.
* **Filter, group, and search** - Filter by status and source, group by org, status, or source, and search across apps — everything narrows the same view so you can find a specific deployment fast.
* **Bulk actions** - Select multiple apps (with shift-range and select-all) and act on them from a sticky bar: **Promote latest** points each app's published channel at its newest build, alongside Publish, Unpublish, and Delete. Each run folds into a single summary so partial failures surface clearly.
* **Full-page app detail** - Selecting an app opens a full-width dossier with a live preview, build history, activity, and settings, plus an **Access** tab with a one-tap link into the Oxygen Factory (IDE) for that workspace.
* **Richer at-a-glance detail** - Every card, row, and detail header shows the app's own favicon, a "Promoted by \<email> · \<when>" attribution line, clickable URL and subdomain links that open in a new tab, and a one-tap copy button for the app URL.

#### World Model Graph Drill-Down and Breakdowns

The **World Model Graph** — the interactive map of your semantic layer — is now something you can explore end-to-end, drilling from the entity hierarchy down into real instances and tracing what drives a measure.

* **Instance drill-down** - Expand an entity into its actual instances and follow cross-link edges outward in both directions across entity clusters, so you can walk from one entity to the related rows it connects to rather than just reading the static schema.
* **Sample Browser** - Entity cards carry descendant sample chips, and a Sample Browser popover lets you page through the filtered instances behind an entity — a quick way to see the concrete rows a node represents.
* **Measure breakdowns** - A measure's contributors now appear on their own entity cards, with breakdown edges anchored to the contributing metric rows so you can see exactly which underlying measures roll up into a top-line number; unrelated nodes and edges recede to keep the path in focus.
* **Live filter counts** - As you filter, each entity shows how many instances match, computed directly so counts stay accurate as you narrow the graph.
* **Connected demo data** - The example project now ships store, city, and region geography with orders linked to stores, so the World Model renders as a connected, breakdown-able hierarchy out of the box.

***

### Platform Improvements

#### Airway ELT

* **Secrets resolve for customer-app automations on the fleet** - Automations triggered from a customer app now resolve their project's UI-managed secrets from the database instead of falling back to environment-only lookups. Previously, a customer-app-triggered automation running on the stateless serve fleet could fail to reach its warehouse — for example ClickHouse would fall back to a `localhost:8123` default and the run would error with `automation_warehouse_unreachable` — because config secret references and declared `http_request` secrets were never read from the project's secret store. Those secrets now resolve correctly, unblocking customer-app automations that talk to a warehouse or an external API.
* **Retries resume where a run left off** - Retrying a failed Airway run now reuses the same run in place instead of spinning up a fresh copy, and preserves that run's progress cursor. A mid-window backfill that crashes partway through picks back up from where it stopped on retry — clearing only the failed attempt's error and events — so it never re-pulls history it already loaded or leaves a gap in the range.
* **Reset a pipeline's schema** - A new **Reset schema** action drops an Airway pipeline's destination tables and clears its stored schema and incremental cursor, so the next run re-infers a fresh schema from scratch. Because Airway schema migration is purely additive, a pipeline stuck on a wrong schema previously couldn't self-heal; reset — available from the pipeline overview, behind a confirmation — gives it a clean slate, after which a backfill repopulates the data. Applies to Airhouse destinations.

#### Airhouse

* **Catalog index toggle for faster dashboards** - Workspace owners and admins can now enable catalog **metadata** indexes for their Airhouse tenant from the workspace Airhouse settings. Indexing the catalog removes a per-scan sequential scan that serialized concurrent dashboard tiles, sharply cutting contention when many tiles load at once. The switch shows a "Building indexes…" state while the index builds in the background and settles on its own.
* **Fewer round-trips per dashboard tile** - World Model dashboard queries now skip a redundant per-tile schema lookup against Airhouse on the route they actually use, halving the number of calls each tile makes and speeding up dashboards with many tiles.

#### Customer Apps Performance

Every customer app now loads faster, with no changes required on your part:

* **Cached, compressed assets** - Content-hashed app assets are served with long-lived immutable caching, and app HTML supports conditional requests (ETag / 304 Not Modified), so returning visitors skip re-downloading files that haven't changed. Responses are also served with Brotli/gzip compression to cut transfer size for the app shell and static files.
* **Cached query results** - Repeated warehouse and semantic-layer queries from a customer app are served from a short-lived, project-scoped result cache, and the SDK's `useQuery` hook now dedupes in-flight requests so simultaneous identical queries share a single round trip. Append `?refresh` to bypass the cache and force a fresh run.

#### Developer Portal

* **Database sidebar grouped by schema** - The IDE's Database sidebar now organizes tables under collapsible schema nodes instead of one flat list, making a multi-schema connection (such as an Airhouse connection) far easier to navigate. Connections that report bare table names, like DuckDB and Postgres, keep rendering flat exactly as before.
* **Drop tables and schemas from the sidebar** - Right-click a table or schema in the Database sidebar to drop it, behind the same confirmation dialog used elsewhere in the IDE — a quick way to tear down test data without hand-writing `DROP` statements. Available to workspace editors.

#### Admin & Customer Apps

* **Unified app icons and screenshots** - An app's icon and screenshot are now sourced from a single manifest-driven model shared by both the homepage launcher and the admin console — a real icon with a monogram fallback, and art with a letter-tile fallback — so a custom app shows a consistent picture everywhere. This replaces the old admin-only `favicon.ico` probe.
* **Tenant logos in admin** - Tenant logos are now rendered and managed directly in the admin custom-apps surface.
* **Simpler publishing** - `oxy publish` now infers the org from the workspace, so passing `--project` alone is enough, and the git source of each deployment is captured at publish time and linked from admin.

#### Workspace Health & Reconciliation

* **Flexible actual-vs-expected checks** - Reconciliation checks now compare a symmetric **actual / expected** pair, and the Oxy side of a check can resolve either through the semantic layer or a raw scalar SQL query — so any measure can be validated against a live external source, rather than being locked to a single fixed shape.
* **More external metrics and grains** - Reconciliation against a live source (for example Toast Analytics) now covers guest, discount, void, and refund metrics, and can compare on **weekly** and **monthly** grains alongside the existing daily comparison.
* **Human-readable health panel** - The admin **Workspace Health → Reconciliation** panel now renders labeled, human-readable actual and expected sections for each check, making drift easier to read at a glance.
* **App-admin access to Workspace Health** - Global App-Admins (not just Global Owners) can now reach the Workspace Health route.
* **Raw-SQL checks work on every warehouse** - A reconciliation check whose Oxy side uses a raw `sql:` block now resolves against any configured warehouse — ClickHouse, Snowflake, BigQuery, or Postgres — not just Airhouse-backed databases. Previously such a check failed with a "database not configured" error even when the database was defined in `config.yml` and semantic-layer checks against that same database worked fine.

#### Observability

* **Reliable observability panels** - The traces, metrics, and execution-analytics panels in the Observability surface now load reliably. A heavy traces query previously ran an unbounded scan that could take tens of seconds, time out at the request limit, and even take the observability backend offline for days; the query is now bounded to the panel's time window so it returns quickly and stays healthy under load.
* **No telemetry lost during backend hiccups** - When the observability backend is briefly unavailable, captured spans are now retried with backoff and queued instead of being dropped, and the collector automatically recovers a stalled backend connection on its own — so a transient outage no longer leaves a gap in your traces.
* **Faster reads as data grows** - Observability event tables are now day-partitioned and old storage snapshots are expired on a regular retention cadence, keeping time-windowed queries fast as trace and metric history accumulates. Newly captured spans now appear in the panel within about 30 seconds, a small delay traded for a much faster and more stable Observability surface.

#### Documentation

* **CLI installation guide** - A new guide walks through installing and using the `oxy` CLI as optional companion tooling — installing via the install script (with version pinning), verifying and updating, an overview of the core commands (`init`, `run`, `login`, `mcp`, `publish`, `api`, `update`), and common workflows like authenticating, running automations locally, exposing Oxy to editors over MCP, and publishing custom apps.
