Skip to content
Talk to our solutions team

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. Type-aware endpoints still exist but are being retired in favor of the raw file surface.

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.

A product repository can be backed by:

TypeBehavior
localA git working tree on disk — filesystem-watched, full branch/tag support, writable
remoteA remote git URL — cloned (in memory or to a filesystem cache), re-pulled on a poll interval
plain folderA directory without git — served as-is
embeddedProducts compiled into the binary with meta embed — for appliance-style distribution
federationAnother meta instance, reverse-proxied

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 — platform bring-up repositories.
  • product — forge-authored product repositories (the common case).
  • marketplace — marketplace components plus a search index.

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.

  • Server side — remote repos are re-pulled on a per-repo ticker (jittered); local repos are filesystem-watched. A HEAD change publishes a repo event to all SSE subscribers.
  • Client side — every chassis service polls its service/{service}/config endpoint every 15 seconds using lastupdated bookmarks; the response says load: true only when something actually changed. Services that need file-level reactions subscribe to the SSE watch stream instead.
  • Reads are version-addressable: any read can pin ?version=<name>&versionType=branch|tag, validated against the repo’s allow-list.

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:

  1. Calls GET /product/{id}/service/{service}/config until it succeeds — this returns the merged envelope: service config, product config, datastore definitions, versions, and timestamps.
  2. Polls it every 15s; on load: true the block rebuilds the affected tenant.
  3. Reads individual files through the generic byte surface (/product/{id}/file/{path}), with a 5-minute ETag-revalidated content cache and stale-serve on transient outage.

For local development without a running meta.svc, meta.localdir points the client at a folder mirroring the same URL structure on disk.

Continue with: