Skip to content
Talk to our solutions team

Product Repository Layout

A product is one repository. Each top-level folder belongs to a block; a block only ever reads its own folder.

myproduct/
.kisai/ # product metadata
config.yaml # product-level config (name, …)
data/
datastores/
datastores.yaml # entity definitions → data.svc
plugins/ # data plugins (code/js, code/go)
access.yaml
iam/
realms.yaml # who authenticates, with which providers
providers.yaml # auth method declarations
token.yaml # token expiry + claims
federation.yaml
access.yaml # authorization predicates
config.yaml
extend/ # entity overlays
plugins/
content/ # content.svc
types/ # content types, one file each
apps/<app>/app.yaml # content apps
stores/stores.yaml # content stores
extend/ # extensions to content.svc's own entities
workflow/
workflows/ # workflow definitions
automate/ # distributed automation flows
notification/ # notify.svc templates + channels
pages/ # UI pages
forms/ # UI forms
i18n/ # translations
themes/ # UI themes
dependencies/
bffs/ # backend-for-frontend definitions
jobs/ # job definitions
search/ # search configuration
integrations/ # third-party integrations
rules/ # rules.svc: one folder per rule set
<set>/*.grl # the set's rules, and vocab.yaml beside them
ai/
bots/ # bot definitions
tests/
functional/
load/

Only include the folders your product uses. A minimal product is just:

myapp/
config.yaml # name: myapp
pages/home.yaml
data/customer.yaml
FolderConsuming block
data/datastores/Data (data.svc): see Entities
iam/IAM (iam.svc): see IAM Configuration
pages/, forms/, i18n/, themes/UI runtime
workflow/workflows/workflow.svc
content/content.svc
bffs/bff.svc
jobs/jobs.svc
notification/notify.svc
rules/rules.svc: see How rule definitions reach the service
ai/bots/ai-bot.svc

Blocks additionally ship embedded base definitions inside their own binaries (base entities, pointcuts, APIs). The product folder layers on top of that base; tenant-level extensions layer on top of the product (delivered as data, not files, see the consuming block’s docs).

Meta serves any branch or tag of the repository:

  • Every read accepts ?version=<name>&versionType=branch|tag.
  • Per-repo allowedversions allow-lists what may be requested: exact names or regex patterns.
  • pinversion pins a repo to a fixed ref regardless of what callers ask for.
  • Version-pinned reads are read out of the commit itself, never a checkout: they never disturb the live worktree.

Meta has no notion of a component. A folder of component.yaml files is served like any other files; the marketplace and the forge authoring UI read and interpret them (marketplace search belongs to the marketplace, not to meta).