Skip to Content

Manifest model

Propagate splits deployment configuration into layered manifests. Secrets never live in committed files.

Overview

FileLocationPurpose
stack.yaml.propagate/stack.yamlInfrastructure intent for one deployment
values.yaml.propagate/values.yamlUser-provided capability secrets (gitignored)
app.manifest.yamlEach app repo rootPer-app contract: routes, env, dependencies
federation.yaml.propagate/federation.yamlNetworking/DID (planned, not implemented)
resolved.json.propagate/resolved.jsonValidation output with derived env and deploy order

stack.yaml

Describes what to deploy, not how values are obtained.

apiVersion: propagate/v1 kind: Stack metadata: clientName: Acme Corp eventName: Argentina ALJ eventDateStart: "2026-02-11" eventDateEnd: "2026-02-13" deployment: slug: acme-corp # repo/stack naming; not used in DNS dns: eventCode: argentina-alj # user input; DNS segment for all apps provider: github: targetOrg: client-org vercel: teamId: team_xxx apps: - slug: docs - slug: timelining

DNS derivation

From dns.eventCode and PROPAGATE_HOST_NAME, propagate computes per-app URLs:

https://{appSlug}.{eventCode}.{hostName}

Example: https://docs.argentina-alj.prisma.events

app.manifest.yaml

Lives at the root of each app repository. Declares what the app provides and requires as stable capability IDs.

apiVersion: propagate/v1 kind: App app: slug: timelining name: Timelining sourceUrl: https://github.com/prisma-collective/timelining provides: capabilities: - id: timelining.web type: route pattern: "{appSlug}.{eventCode}.{hostName}" - id: timelining.visualise.all type: route path: /api/visualise/all requires: capabilities: - id: telegram.bot_token type: env key: TELEGRAM_BOT_TOKEN source: user - id: upstash.kv type: env keys: [KV_REST_API_URL, KV_REST_API_TOKEN] source: provisioned provisioner: vercel.upstash-kv - id: neo4j.connection type: env keys: [NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD] source: provisioned provisioner: railway.neo4j dockerPath: .docker - id: docs.web type: env key: DOCS_APP_URL source: capability - id: docs.infra_token type: env key: PRIVATE_API_TOKEN source: generated dependsOn: - docs

Author manifests via the agent task in propagate AGENT_PREPARE_APPS.md — scan API routes and service modules to derive capabilities.

Capability value sources

SourceWho sets itExample
userPrompted in propagate create; stored in values.yamlTELEGRAM_BOT_TOKEN
provisionedAuto-provisioned on propagate apply unless overridden in values.yamlKV_REST_*, NEO4J_*
derivableComputed from stack.yaml + deployment outputsDOCS_APP_URL
generatedCreated at apply time by propagatePRIVATE_API_TOKEN (shared between apps)
capabilityResolved from another app’s providesdocs.webDOCS_APP_URL

Capability IDs are stable contracts. Env var names are implementations that may change per environment.

values.yaml

User-provided secrets keyed by capability ID:

capabilities: telegram.bot_token: "..." upstash.kv: # optional override — skips Redis provisioning KV_REST_API_URL: "..." KV_REST_API_TOKEN: "..." neo4j.connection: # optional override — skips Neo4j provisioning NEO4J_URI: bolt://... NEO4J_USERNAME: neo4j NEO4J_PASSWORD: "..."

App catalog

catalog/apps.yaml in the propagate repo maps slugs to sibling repos:

SlugLocal pathDeployable
docs../docs-secretyes
timelining../timeliningyes
enacting../enactno
registering../enrolno
evaluating../evaluateno

Cross-app wiring (docs + timelining)

CallerEnvCallee endpointCapability
timeliningDOCS_APP_URLdocs GET /api/pages/snapshotdocs.pages.snapshot
timeliningDOCS_APP_URLdocs GET /api/serve/{slug}docs.pages.serve
timeliningDOCS_APP_URLdocs GET /api/protocol/{channel}docs.protocol.schema

Deploy order: docs before timelining (dependsOn). docs has no reverse dependency on timelining.

Federation (deferred)

federation.yaml will hold DID identity, parent-child relationships, and network policies. No CLI commands or Pulumi resources exist for it yet.

Last updated on