Catalog fields
This page lists the fields of the catalog’s files, the values each one accepts, and what the platform does with it. Use it when you write or review a catalog entry: a field that drives something changes real resources once its merge request merges, and a field marked designed is accepted, or planned, but nothing acts on it yet.
The catalog page explains the files themselves and why intent lives there. The examples come from a demo organization, a fictional online retailer.
How to read a row
Section titled “How to read a row”Each row is one field, with four facts:
- Required: whether a file must have it, and its default when it may be left out.
- Values: what the catalog’s checks accept. The catalog’s JSON Schemas and its lint refuse anything else, including any field the schema does not define (enforced: the catalog’s pipeline runs the lint on every merge request).
- What it drives: what the platform builds or decides from it, and which part of the platform does so.
- Source: the files that define the field and the code that reads it.
The tables describe the platform at release 2026.10.01-1, as the catalog’s schemas, its lint and the code that reads each field stand on 2026-10-01. A row marked designed is a field the platform’s contracts specify that nothing reads yet, or, for the last four product fields, one the schema does not accept yet.
Product
Section titled “Product”A product’s file is products/<journey>.<domain>.<context>.<product>.yaml.
product
- Required
- Yes.
- Values
- A slug of 2 to 10 characters: lowercase letters and digits, words joined by single hyphens, starting with a letter. It is the last part of the file name, unique within its domain, and never a name the domain has retired.
- What it drives
- The product's identity everywhere: its repository path, its two project ids, its users group, its state prefixes and its hostname.
- Source
- catalog
schema/common.schema.json,scripts/lint.mjs,docs/derivations.md
journey
- Required
- Yes.
- Values
- A journey slug, 3 to 10 lowercase letters, listed in
catalog.yaml. It is the first part of the file name. - What it drives
- The first level of the product's path, and the DNS zone its hostnames sit in,
<journey>.projectairframe.dev. - Source
- catalog
scripts/lint.mjs; landing-zoneroots/network/edge.tf
domain
- Required
- Yes.
- Values
- A domain slug, 3 to 8 lowercase letters. It is the second part of the file name, and the pair
<journey>/<domain>is listed incatalog.yaml. - What it drives
- The project ids,
lk-<domain>-<product>, and which domain's project factory root creates the projects and which domain's GitLab root creates the repository. - Source
- catalog
scripts/lint.mjs; landing-zoneroots/project-factory/
context
- Required
- Yes.
- Values
- A slug of 3 to 12 characters. It is the third part of the file name, and its context file must exist.
- What it drives
- The context's GitLab group, which holds the repository, and the context's folder, which holds the projects.
- Source
- catalog
scripts/lint.mjs; landing-zoneroots/project-factory/
team
- Required
- Yes.
- Values
- A team slug. The team must exist and live in the product's context, and at least one person who may merge, among the team's developers and lead and the leads above the product, must have a GitLab account.
- What it drives
- Who approves and who may merge, with the leads of the context, domain and journey; the members of the product's users group; the team group's read access to the projects; the
teamlabel; the Grafana team. - Source
- catalog
scripts/lint.mjs; landing-zoneroots/groups/main.tf,roots/project-factory/; control-planegate/src/core/ownership.ts
lifecycle
- Required
- No. Default
{ status: active }. - Values
statusisactive,retiringorremoved.retire_after, a date, is required for the last two.removedcomes only afterretiring, and only once that date has passed.- What it drives
- Retiring takes the product's services off the shared edge and keeps every resource. Removed deletes its projects, users group and repository, and needs a tombstone so the name is never reused. A change of status needs the
lifecyclelabel and two approvals: one from the team, one from a domain lead or the platform team. - Source
- catalog
scripts/lint.mjs,scripts/lifecycle-check.mjs; control-planegate/src/core/ownership.ts; golden-pathmodules/cloud-run-service/main.tf
criticality
- Required
- Yes.
- Values
1,2or3; 1 is the most critical.- What it drives
- The
criticalitylabel; the production database's tier and, at 1, its regional availability; the cap on each service's instances; whether production waits for the sandbox's apply (1 and 2). At 1 or 2 the team needs two on-call members, and at 1 on-call hoursalways. - Source
- golden-path
modules/cloud-sql/main.tf,modules/cloud-run-service/main.tf,template/.gitlab-ci.yml.jinja; catalogscripts/lint.mjs
data_classification
- Required
- Yes.
- Values
public,internal,confidentialorrestricted.restrictedrequiresinner_source: false.- What it drives
- The
data_classificationlabel on the product's resources. - Source
- golden-path
modules/airframe-context/main.tf; catalogscripts/lint.mjs
rto, rpo
- Required
- Yes.
- Values
- A positive whole number followed by
m,hord, such as1hor15m; the lint checks this forrpo. Anrpobelow5mneeds criticality 1. - What it drives
- The production database's recovery: an
rpounder a day turns on point-in-time recovery, and the golden path's Cloud SQL module refuses an objective it cannot meet. - Source
- catalog
scripts/lint.mjs; golden-pathmodules/cloud-sql/main.tf
monthly_budget
- Required
- Yes.
- Values
- Whole US dollars, at least 1. All product and playground budgets together must not exceed the folder's budget in
catalog.yaml. - What it drives
- A Google Cloud budget on each billed project, 70 percent production and 30 percent non-production, alerting at 80 and 100 percent. The Airframe cost check refuses a change whose priced plans go over it. Raising it needs a domain lead.
- Source
- landing-zone
roots/project-factory/; control-planepolicy/airframe/cost.rego,gate/src/core/ownership.ts; catalogscripts/lint.mjs
template
- Required
- Yes.
- Values
fullstackornone.nonerequiressource_repoorrepos.- What it drives
- Whether the render job writes the repository's first commit from the golden path's template. With
nonethe repository the platform creates stays empty. - Source
- control-plane
lifecycle/render.sh; catalogscripts/lint.mjs
stack
- Required
- No. Default
node. - Values
node,python-fastapiorjava-spring.- What it drives
- The application the template renders. The injected build and test job is then chosen by the files that stack leaves in the repository.
- Source
- catalog
schema/product.schema.json; control-planetemplates/build-test/template.yml
slo
- Required
- Yes.
- Values
availability, a percentage from 90 to 99.99, andlatency_p95_ms, a whole number of milliseconds.- What it drives
- The targets on the product's SLO dashboard and its error budget alert rule in Grafana.
- Source
- operations
roots/grafana/pack.tf
quality
- Required
- No. Default: coverage 80, no ratchet, findings never fail.
- Values
minimum_coverage, 0 to 100;coverage_ratchet, true or false;block_on_quality, one ofoff,info,minor,major,criticalorblocker.- What it drives
- The injected
build:qualityjob reads it from the catalog at run time and fails below the coverage, below main's coverage when the ratchet is on, or on findings at or above the severity. A change needs a team lead or a domain lead. - Source
- control-plane
templates/build-test/template.yml,gate/src/core/ownership.ts
external_ingressdesigned
- Required
- No. Default
false. - Values
trueorfalse.- What it drives
- Meant to let a route the product declares public skip single sign-on. The golden path passes it to the product's modules, but every product backend still has single sign-on, and the policy pack denies one without it: the building block for a public route is not built.
- Source
- golden-path
modules/service-project/main.tf,modules/cloud-run-service/main.tf; control-planepolicy/airframe/cloud_run.rego
inner_source
- Required
- No. Default
true. - Values
trueorfalse.- What it drives
- With
false, in a domain that has a restricted group, the repository goes there and is private. Elsewhere the repository is public. - Source
- control-plane
modules/product-repositories/main.tf; landing-zoneroots/project-factory/
agentic_opsdesigned
- Required
- No. Default
diagnose. - Values
diagnose,act,autoorpropose.- What it drives
- How far the operations agent may act on the product. Nothing reads it: that agent is not built.
- Source
- catalog
schema/product.schema.json; landing-zonedocs/contracts.md1.4
preview_concurrency
- Required
- No. Default
2. - Values
- 1 to 16.
- What it drives
- The size of the shared preview database instance, when
preview_dbisshared. - Source
- golden-path
modules/preview-substrate/variables.tf,template/infra/np/main.tf.jinja
preview_db
- Required
- No. Default
sidecar. - Values
sidecarorshared.- What it drives
- How a preview gets its database: a PostgreSQL container beside the preview's service, or a database of its own in one shared Cloud SQL instance per product.
- Source
- golden-path
modules/preview-substrate/variables.tf,template/infra/eph/main.tf.jinja
preview_ttl_hours
- Required
- No. Default
72. - Values
- 1 to 168.
- What it drives
- How long a preview lives after its latest apply, carried as the
expireslabel on its services; after that it is destroyed. - Source
- golden-path
modules/preview-substrate/variables.tf,modules/cloud-run-service/main.tf
previewdesigned
- Required
- No. Default
standard. - Values
standardorcustom.- What it drives
- Whether the product brings its own preview component. Nothing reads it; every preview uses the standard router.
- Source
- catalog
schema/product.schema.json; landing-zonedocs/contracts.md1.4
conformance_leveldesigned
- Required
- No.
- Values
1,2or3.- What it drives
- How far along the adoption ladder the product is. Nothing reads it yet.
- Source
- catalog
schema/product.schema.json; landing-zonedocs/contracts.md1.4
residency_profiledesigned
- Required
- No. Default
default. - Values
- Only
default. - What it drives
- Where the product's data may live. Only one profile exists, and nothing reads the field.
- Source
- catalog
schema/product.schema.json; landing-zonedocs/contracts.md1.4
componentsdesigned
- Required
- No.
- Values
- A list of
name, with an optionalcriticalityanddata_classification. The product's name, a hyphen and the component's name are at most 10 characters together. - What it drives
- Separate projects for a part of the product with a different profile. No project factory creates them yet.
- Source
- catalog
schema/product.schema.json,scripts/lint.mjs; landing-zoneroots/project-factory/
database
- Required
- No.
- Values
tier, a Cloud SQL tier name starting withdb-.- What it drives
- The tier of the product's Cloud SQL instances, in place of the module's default: the smallest outside production, the criticality's tier in production.
- Source
- catalog
schema/product.schema.json; golden-pathtemplate/infra/prod/main.tf.jinja,template/infra/np/main.tf.jinja
services
- Required
- No.
- Values
- Names of files in the catalog's
services/, each a Google Cloud service the platform has approved. - What it drives
- Each service's API is enabled on the product's billed projects and its roles are granted to the product's apply identities. Adding one needs a domain lead.
- Source
- catalog
scripts/lint.mjs; landing-zoneroots/project-factory/; control-planegate/src/core/ownership.ts
sandbox
- Required
- No. Default
false. - Values
true, ortierwith a Cloud SQL tier name. Required when another product consumes this product's events or calls it.- What it drives
- A permanent environment at main's version in the non-production project, with its own database at the smallest tier or the one named, for other products to test against.
- Source
- catalog
scripts/lint.mjs; golden-pathtemplate/infra/sandbox/main.tf.jinja
egress
- Required
- No.
- Values
- Hostnames, with no wildcards and no addresses.
- What it drives
- The egress proxy's allow rules for the product's services. The proxy is off by default because it costs money while idle, and while it is off a product that declares
egresscannot deploy. - Source
- landing-zone
roots/network/egress.tf
egress_tcpdesigned
- Required
- No.
- Values
- A list of
name,cidrsandport. - What it drives
- Outbound connections other than web requests, to named address ranges. Nothing reads it yet.
- Source
- catalog
schema/product.schema.json; landing-zoneroots/network/variables.tf
consumes
- Required
- No.
- Values
- A list of
topic, the publisher's path and event as<journey>/<domain>/<context>/<product>/<event>, andsubscription, unique in the product. The publisher must declare the event. - What it drives
- Adding one needs the approval of the publisher's owners, unless the event is marked
inner_source. The event appears as received on the product's page in the architecture catalog. No module creates the subscription yet, so that part is designed. - Source
- catalog
scripts/lint.mjs; control-planegate/src/core/ownership.ts,cli/fragment.py
topics
- Required
- No.
- Values
- A list of
event, two lowercase words joined by a dot such asorder.placed;schema, a path in the product's repository; andinner_source, defaultfalse. - What it drives
- The events other products may consume, and their pages in the architecture catalog. No module creates the Pub/Sub topic yet, so that part is designed.
- Source
- catalog
scripts/lint.mjs; control-planecli/fragment.py
calls
- Required
- No.
- Values
- Product paths,
<journey>/<domain>/<context>/<product>, never the product itself. - What it drives
- Adding one needs the approval of the called product's owners, and the called product must run a sandbox. The call appears in the architecture catalog.
- Source
- catalog
scripts/lint.mjs; control-planegate/src/core/ownership.ts,cli/fragment.py
iap_accessdesigned
- Required
- No.
- Values
- A list of
teamorgroup. - What it drives
- Who else may reach the product behind single sign-on. Nothing reads it yet: the product's users group holds its own team's members.
- Source
- catalog
schema/product.schema.json; landing-zoneroots/groups/main.tf
source_repodesigned
- Required
- No.
- Values
- The address of the one repository an existing system lives in. Only with
template: none. - What it drives
- Nothing reads it yet: the repository the platform creates stays empty.
- Source
- catalog
scripts/lint.mjs; control-planelifecycle/render.sh
reposdesigned
- Required
- No.
- Values
- A list of
nameandrole, the role beinginfra,service,worker,migrationorfrontend. Only withtemplate: none. - What it drives
- A product spread over several repositories. Nothing reads it yet.
- Source
- catalog
schema/product.schema.json; landing-zonedocs/adr/0017-multi-repository-products-and-adoption-by-moving-the-group.md
runtimedesigned
- Required
- Not accepted yet.
- Values
cloud-runorgke, in the contracts.- What it drives
- Where the product runs: Cloud Run, or namespaces on a shared GKE cluster. The schema does not accept the field yet, so the lint refuses an entry that uses it.
- Source
- landing-zone
docs/contracts.md1.4; catalogschema/product.schema.json
source_groupdesigned
- Required
- Not accepted yet.
- Values
- A GitLab group path, in the contracts.
- What it drives
- The group an adopted product's repositories live in before they move under the platform's path. The lint refuses it today.
- Source
- landing-zone
docs/contracts.md1.4; catalogschema/product.schema.json
hostnamesdesigned
- Required
- Not accepted yet.
- Values
- Hostnames under a zone the organization holds, in the contracts.
- What it drives
- The hostnames an adopted product arrives with, which the shared edge would serve as aliases of its own. The lint refuses it today.
- Source
- landing-zone
docs/contracts.md1.4 and 8; catalogschema/product.schema.json
dependenciesdesigned
- Required
- Not accepted yet.
- Values
- A list of
name,kind,hostandport, in the contracts. - What it drives
- A data store or service the product keeps running outside the platform; the network would open the way to it. The lint refuses it today.
- Source
- landing-zone
docs/contracts.md1.4; catalogschema/product.schema.json
Secrets are never in the catalog. A product’s repository lists them by name in its own secrets file, without values.
A team’s file is teams/<team>.yaml.
team
- Required
- Yes.
- Values
- A slug, equal to the file name.
- What it drives
- The team group,
lk-team-<team>@, which holds viewer access to the team's product projects, and the team, its contact point and its alert routing in Grafana. - Source
- catalog
scripts/lint.mjs; landing-zoneroots/groups/main.tf,roots/project-factory/; operationsroots/grafana/
context
- Required
- Yes.
- Values
- The path of the context the team lives in,
<journey>/<domain>/<context>, orplatform. - What it drives
- Which products the team may manage: a product's team must live in the product's context.
- Source
- catalog
scripts/lint.mjs
lead
- Required
- Yes.
- Values
- A person who is a member with the role
team_lead. - What it drives
- The team's primary contact, on its page in the architecture catalog. The platform team's lead administers the Grafana organization.
- Source
- catalog
scripts/lint.mjs; control-planecli/fragment.py; operationsroots/grafana/members.tf
timezone
- Required
- No. Default
Etc/UTC. - Values
- A time zone name, such as
Europe/Lisbon. - What it drives
- Shown on the team's page in the architecture catalog. Nothing else reads it yet.
- Source
- catalog
schema/team.schema.json; control-planecli/fragment.py
members
- Required
- Yes, at least one.
- Values
- A list of
personandroles; the roles aredeveloper,team_lead,oncallandoncall-secondary. A member is active or pending, never departed. - What it drives
- Every member may approve changes to the team's products; developers and team leads may also merge them. Active members join the team group, the users groups of the team's products and the team in Grafana.
- Source
- catalog
scripts/lint.mjs,ownership/protected-paths.yaml; landing-zoneroots/groups/main.tf
oncalldesigned
- Required
- No. A criticality 1 product's team needs it.
- Values
rotation,weeklyordaily;layers, the on-call roles;hours,businessoralways. A criticality 1 product needsalways.- What it drives
- The team's on-call schedule, which is not built. Today the values only appear on the team's page in the architecture catalog.
- Source
- catalog
scripts/lint.mjs; control-planecli/fragment.py
Person
Section titled “Person”A person’s file is people/<person>.yaml.
person
- Required
- Yes.
- Values
- The local part of the email address, such as
sam.okafor, equal to the file name. - What it drives
- The person's identity in every team, lead list and approval.
- Source
- catalog
schema/common.schema.json,scripts/lint.mjs
email
- Required
- Yes.
- Values
- An address in the organization's domain,
projectairframe.dev. - What it drives
- Group memberships: the groups root adds each active person to their groups by this address.
- Source
- catalog
schema/common.schema.json; landing-zoneroots/groups/main.tf
name
- Required
- Yes.
- Values
- Any text.
- What it drives
- The person's page in the architecture catalog.
- Source
- control-plane
cli/fragment.py
status
- Required
- Yes.
- Values
active,pendingordeparted.- What it drives
- Only active people join groups. A pending person, with no account yet, keeps their roles and lead positions. The lint refuses a departed person in a team or a lead list.
- Source
- catalog
scripts/lint.mjs; landing-zoneroots/groups/main.tf
gitlab_username
- Required
- No.
- Values
- A GitLab username.
- What it drives
- GitLab memberships and merge rights, and the approval policy's named approvers: only active people with a username count.
- Source
- catalog
scripts/lint.mjs; security-policiesscripts/approvers.py; control-planeroots/gitlab/
grafana_username
- Required
- No.
- Values
- The person's Grafana Cloud login, once single sign-on has created the account.
- What it drives
- Membership of the Grafana organization and of the person's teams there.
- Source
- operations
roots/grafana/members.tf
profile
- Required
- No.
- Values
about,expertise,linksandhours. A change to it needs the person: their approval, or a merge request they opened with only their own commits.- What it drives
- The person's page in the architecture catalog.
- Source
- catalog
ownership/protected-paths.yaml; control-planegate/src/core/ownership.ts,cli/fragment.py
Journey
Section titled “Journey”A journey’s file is journeys/<journey>.yaml.
journey
- Required
- Yes.
- Values
- 3 to 10 lowercase letters, equal to the file name and listed in
catalog.yaml. - What it drives
- The journey's folder, its GitLab group and its DNS zone,
<journey>.projectairframe.dev. - Source
- catalog
scripts/lint.mjs,docs/derivations.md
leads
- Required
- Yes, at least one.
- Values
- People, the first being the primary contact. None may be departed.
- What it drives
- The group
lk-journey-<journey>-leads@. Journey leads may merge on every product below. - Source
- catalog
schema/journey.schema.json,scripts/lint.mjs; landing-zoneroots/groups/main.tf
description
- Required
- Yes.
- Values
- Text.
- What it drives
- The journey's page in the architecture catalog.
- Source
- control-plane
cli/fragment.py
Domain
Section titled “Domain”A domain’s file is domains/<journey>.<domain>.yaml.
domain
- Required
- Yes.
- Values
- 3 to 8 lowercase letters, equal to the second part of the file name and listed as
<journey>/<domain>incatalog.yaml. - What it drives
- The domain's folder, its leads group and its two subnets in each network come from the catalog. Its GitLab groups, its project factory root and its GitLab domain root are changes to the platform itself.
- Source
- landing-zone
roots/folders/,roots/groups/,roots/network/; control-planeroots/gitlab/
journey
- Required
- Yes.
- Values
- The journey it belongs to, equal to the first part of the file name. The journey's file must exist.
- What it drives
- Where the domain sits, under the journey's folder and group.
- Source
- catalog
scripts/lint.mjs
leads
- Required
- Yes, at least one.
- Values
- People, as for a journey.
- What it drives
- The group
lk-<journey>-<domain>-leads@. Domain leads may merge on every product below and approve its entries; one must approve a raised budget or a new service, and a domain lead or the platform team gives one of the two approvals a lifecycle change needs. - Source
- landing-zone
roots/groups/main.tf; control-planegate/src/core/ownership.ts
description
- Required
- Yes.
- Values
- Text, at most 200 characters.
- What it drives
- The domain's page in the architecture catalog.
- Source
- catalog
schema/domain.schema.json; control-planecli/fragment.py
restricted_subtree
- Required
- No. Default
false. - Values
trueorfalse.- What it drives
- A restricted group inside the domain's GitLab group, where products with
inner_source: falseget private repositories. - Source
- control-plane
roots/gitlab/groups.tf,modules/product-repositories/main.tf
Context
Section titled “Context”A context’s file is contexts/<journey>.<domain>.<context>.yaml. A small domain still declares one context, named after the domain.
context
- Required
- Yes.
- Values
- A slug of 3 to 12 characters, equal to the third part of the file name.
- What it drives
- The context's folder, and its GitLab group, which holds the repositories of its products.
- Source
- catalog
scripts/lint.mjs; landing-zoneroots/folders/; control-planeroots/gitlab/
domain
- Required
- Yes.
- Values
- Its domain, equal to the second part of the file name. The domain's file must exist.
- What it drives
- Where the context sits, under the domain's folder and group.
- Source
- catalog
scripts/lint.mjs
journey
- Required
- Yes.
- Values
- Its journey, equal to the first part of the file name.
- What it drives
- Where the context sits.
- Source
- catalog
scripts/lint.mjs
leads
- Required
- Yes, at least one.
- Values
- People, as for a journey.
- What it drives
- The group
lk-<journey>-<domain>-<context>-leads@. Context leads may merge on every product of the context and approve its entries. - Source
- landing-zone
roots/groups/main.tf; catalogownership/protected-paths.yaml
description
- Required
- Yes.
- Values
- Text.
- What it drives
- Shown with the context on its domain's page in the architecture catalog.
- Source
- control-plane
cli/fragment.py
Where it lives
In the catalog repository:
- schema/: the JSON Schemas every file is checked against
- scripts/lint.mjs: the catalog's consistency checks
- docs/derivations.md: what each field drives
In the landing-zone repository:
