greenlight.yml
Reference
Every Greenlight-managed repository has a greenlight.yml at the root. It is the contract for what the deployed pod sees: identity, documentation, and declared infrastructure (workloads, resources, grants, and env-var names). The agent edits it with ordinary file tools and opens a PR; on merge, the reconciler applies it. Env-var values are written separately through envSet and never live in this file.
The agent reads app_id from this file on a fresh clone, then calls getApp for everything else.
A minimal example
Section titled “A minimal example”app_id: app_k9x2m3pslug: expense-trackerowner: jane@contoso.com
docs: summary: Reimbursement tracker for finance ops. purpose: Replace the shared spreadsheet finance currently uses. architecture: | Single Node.js web service. Postgres for records. SSO-gated; UI is shadcn + Tailwind.registerApp seeds this file with app_id, the docs block, the Greenlight pipeline workflow, and a .gitignore — plus commented-out scaffold for the workloads, resources, grants, and env blocks below. No Dockerfile is seeded; the agent authors it for the app’s stack in the first code PR. The app stays in registered state, with no infrastructure, until that first PR declares its workload and merges.
A full example
Section titled “A full example”app_id: app_k9x2m3pslug: expense-trackerowner: jane@contoso.com
docs: summary: Reimbursement tracker for finance ops. purpose: Replace the shared spreadsheet finance currently uses. architecture: Single Node.js web service backed by Postgres.
workloads: web: kind: web dockerfile: Dockerfile port: 8080 routes: ['/*']
resources: - kind: postgres name: db - kind: blob name: receipts
grants: - integration: snowflake-prod credential: analytics-read reason: Read the sales mart for the dashboard.
env: - { name: APPROVAL_SECRET, sensitive: true } - { name: FEATURE_FLAGS, sensitive: false }Schema
Section titled “Schema”Identity & docs
Section titled “Identity & docs”| Field | Required | Description |
|---|---|---|
app_id | yes | Greenlight app identifier; written at registration. |
slug | no | URL-safe identifier; informational after registration. |
owner | no | Owning user. |
docs | yes | Deploy-time app documentation projected into the dashboard (see below). |
Declared infrastructure (applied on merge)
Section titled “Declared infrastructure (applied on merge)”These blocks are the desired state the merge-time reconciler converges to:
workloads— the app’s runnable shape: awebworkload withkind,dockerfile,port, androutes. Omitcompute:unless you have evidence you need more than the baseline; declaring it sets request = limit and reserves that capacity even when idle.resources— managed resources bykind(postgres,blob) andname. Provisioning these is what injects their managed env vars (e.g.DATABASE_URL).grants— the app’s integration access. Each entry names theintegration, thecredential(the IT-registered slug), and an optionalreason. Auto-approved grants work immediately on merge; the rest land in IT’s review queue while the app deploys. Manifest grants bind the app only — a person’s own access to an integration is requested imperatively viarequestCredentialAccess, never declared here (see Local development).env— the names (andsensitiveflags) of user-controlled env vars. Values are written viaenvSet; every declared name must have a value at merge time or the deploy fails.
runtime and build details live in the repo’s Dockerfile and source code, not here.
The docs block is required deploy-time documentation:
docs.summary,docs.purpose, anddocs.architectureare projected intoapps.doc_*after a successful deployment.- The app detail page renders that projection in its read-only “About this app” section.
- App Knowledge is separate and starts empty; owners create entries and agents propose them only when useful context emerges.
Changes to greenlight.yml docs.* update the deployment projection on a successful merge. They do not create or overwrite Knowledge entries.
Policy check
Section titled “Policy check”On every pipeline run, the policy gate validates greenlight.yml: required identity and docs fields, and the manifest blocks above — for example, it rejects an env: entry that collides with a platform-reserved name, and the deploy fails if a declared env: name has no value in the vault. Approved changes are applied by the reconciler on merge.