Meta Overview
meta.svc distributes product definitions, a product on kis.ai is a git monorepo with one folder per service block (data/, iam/, pages/, …); each generic block fetches its folder through meta and morphs itself into the specific application. Git is the source of truth, meta is the gateway and distributor in front of it.
Meta is deliberately generic and content-agnostic: it serves files by path, as raw bytes, with ETags. Interpreting a file (parsing an entity YAML, a realm definition, a page) is the consuming block’s job, never meta’s: meta has no typed, service-config or component endpoints, and knows no block’s folder layout.
Meta is not the configuration plane: config.svc configures how a block runs (ports, pools, credentials); meta distributes what the product is (entities, realms, pages, workflows).
Default port: 8080.
Sources
Section titled “Sources”A product repository can be backed by:
| Type | Behavior |
|---|---|
local | A git working tree on disk: filesystem-watched, full branch/tag support, writable |
remote | A remote git URL: mirrored (in memory or to a filesystem cache) and fetched on a poll interval; served from its commits, never checked out |
| plain folder | A directory without git: served as-is |
| embedded | Products compiled into the binary with meta embed: for appliance-style distribution |
Local-dir and remote-git sit behind the same read contract, so blocks behave identically in development and production.
One binary, three roles via -m/--mode:
meta(default): the customers’ products the repository config lists, and each tenant’s own products, checked out per user on first use.product: forge-authored product repositories, resolved through forge on first use.marketplace: the marketplace repositories.
Multi-tenancy
Section titled “Multi-tenancy”Repositories are registered per customer, each customer holding a set of products. The X-Customer header (or JWT claims) selects the customer; the product name is in the URL path. Per-repo access rules (JS expressions over the caller’s identity) and license entitlements gate access.
Change propagation
Section titled “Change propagation”- Server side: remote repos are fetched on a per-repo ticker (jittered); local repos and folders are filesystem-watched. When a product’s content moves, meta publishes
repo-updatedon the product’s change stream (GET /product/stream). - Client side: a block names the folders it reads (its watch paths). The chassis meta client wakes on the change stream (the directory watcher in local mode, a poll as the floor), compares the manifests of those folders, and runs the block’s load again only when one of them moved.
- Reads are version-addressable: any read can pin
?version=<name>&versionType=branch|tag, validated against the repo’s allow-list.
How a block consumes meta
Section titled “How a block consumes meta”Every service block ships with the meta client built into the chassis. Per served tenant, the chassis reads meta.url (or meta.localdir for local development) from tenant config, then:
- Runs the block’s load: the block reads its own folders of the tenant’s product, as files (one file by path, a folder’s files in one batched read), and interprets them itself.
- Watches those folders; when a file under them changes, runs the load again.
- Reads go through a per-tenant content cache, ETag-revalidated, that serves last-known-good content through a transient outage.
For local development without a running meta.svc, meta.localdir points the client at the product’s checkout (or a folder of products, products/<product>). It reads exactly as meta serves it: a conformance test pins the two.
Continue with:
- Product repository layout: what goes in the monorepo
- HTTP API: the file, git, and stream surface
- Operations: running,
meta serve, caching, failure modes, and deployment - End-to-End Testing: verify a deployment across run modes and the full surface