Skip to content

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.

app_id: app_k9x2m3p
slug: expense-tracker
owner: 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.

app_id: app_k9x2m3p
slug: expense-tracker
owner: 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 }
FieldRequiredDescription
app_idyesGreenlight app identifier; written at registration.
slugnoURL-safe identifier; informational after registration.
ownernoOwning user.
docsyesDeploy-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: a web workload with kind, dockerfile, port, and routes. Omit compute: 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 by kind (postgres, blob) and name. Provisioning these is what injects their managed env vars (e.g. DATABASE_URL).
  • grants — the app’s integration access. Each entry names the integration, the credential (the IT-registered slug), and an optional reason. 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 via requestCredentialAccess, never declared here (see Local development).
  • env — the names (and sensitive flags) of user-controlled env vars. Values are written via envSet; 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, and docs.architecture are projected into apps.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.

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.