Promotion is the transition from “merged and tested” to “approved for production”. It binds an immutable prompt artifact — identified by content digest — to a delivery channel. Downstream apps pin the promoted digest so they always run exactly what was tested.Documentation Index
Fetch the complete documentation index at: https://bintzgavin-apastra-14.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
The full promotion flow
From author to downstream pin, the complete lifecycle looks like this:Author a prompt change
Edit the prompt spec in
promptops/prompts/. Run a local smoke eval using the apastra-eval skill.Open a pull request
Push the change and open a PR. CI triggers the regression gate on the
promptops/** changes.CI runs suites and regression gate
The
regression-gate.yml workflow fetches the regression report from the promptops-artifacts branch, evaluates it against the policy, and posts a step summary. If any blocker rule fails, the required status check fails and merge is blocked.Human review
CODEOWNERS review approves the PR. An approval state record is written to the
promptops-artifacts branch, recording the revision ref, decision, and whether all checks passed.Merge
The PR merges to
main. The promptops-artifacts branch now holds the approval record for this revision.Tag and release
When you’re ready to release, push a tag (e.g.,
v1.2.0). The prompt-release.yml workflow triggers immutable-release.yml, which packages promptops/ as promptops.tar.gz, computes a SHA-256 digest, attests build provenance, and creates an immutable GitHub Release.Promotion record appended
The
promote.yml workflow (triggered manually or by the release publish event) verifies the approval record, then writes an append-only promotion record to the promotions/ directory on the promptops-artifacts branch. The record binds the digest to a channel (e.g., prod).Delivery syncs to targets
The
deliver.yml workflow reads the promotion record, resolves the channel and digest, iterates over promptops/delivery/*.yaml delivery targets, and executes the sync for each target matching the channel.Downstream apps pin the digest
Consuming apps update their
consumption.yaml to pin the new digest or tag. The resolver uses this pin to fetch the exact artifact that was promoted.The consumption manifest
Apps declare their prompt dependencies inpromptops/manifests/consumption.yaml. This file maps local prompt names to resolution configurations:
Fields
| Field | Required | Purpose |
|---|---|---|
version | Yes | Manifest schema version |
prompts | Yes | Map of local names to resolution config |
prompts.<name>.id | Yes | Stable prompt ID to resolve |
prompts.<name>.pin | No | Commit SHA, tag, or semver to pin to |
prompts.<name>.override | No | Path to a local file overriding the resolved prompt |
prompts.<name>.model | No | Model override for this specific prompt |
defaults.model | No | Default model for all prompts in this manifest |
defaults.provider | No | Default provider |
Resolution order
The resolver applies this precedence when resolving a prompt ID:Local override
If
override is set on the prompt entry, the resolver uses the local file path. This is for fast local iteration — a developer can point to a local copy without changing the pin.Workspace path
If the prompt exists in the same repo under
promptops/prompts/<id>.yaml, the resolver uses it. This is the default for same-repo topologies.Git ref
If
pin is set to a commit SHA or tag, the resolver fetches the prompt spec from that ref. This is the default for separate-repo topologies and governed production pins.The local override path is designed for local development only. Never commit an
override that points to a local absolute path — it will break for other developers and in CI.Promotion records
A promotion record is an append-only JSON file that binds an approved digest to a channel at a point in time. Records are committed to thepromotions/ directory on the promptops-artifacts branch and are never modified.
Fields from the promotion record schema
| Field | Required | Purpose |
|---|---|---|
version | Yes | The approved version (semver or tag) |
channel | Yes | Target channel (e.g., prod, staging) |
digest | Yes | Content digest of the promoted artifact |
evidence | No | Links to regression reports or run artifacts |
timestamp | No | ISO 8601 timestamp of the promotion |
promote.yml workflow enforces that a promotion can only proceed if an approval state record exists for the target digest with decision: "approved" and checks_passed: true. This prevents promoting unapproved revisions.
Packaging options
Git ref (tag/SHA)
Pinning surface:
git+...#<sha> or tag in manifestBest for: Dev, early adoption, internal useZero publishing overhead. Requires Git access. npm and pip both support Git/VCS dependency forms natively, so language-specific wrappers are optional.GitHub Release asset
Pinning surface: Release tag + asset digestBest for: Governed releases with low infrastructureTag lineage with easy download. Can be made immutable. Not natively digest-addressed unless you add digests to release notes (which
immutable-release.yml does automatically).OCI artifact
Pinning surface:
name@sha256:...Best for: Org-wide artifact distributionDigest-addressed by design. Supports tag + digest references. Supports associated artifacts and referrers. Requires a container registry.npm/PyPI wrapper
Pinning surface: Semver in ecosystemBest for: Mature orgs with a broad consumer baseBest app ergonomics — standard package manager tooling. Requires a publishing pipeline. Overhead is higher than Git refs.
Packaging table
| Mode | Pinning surface | Strengths | When to use |
|---|---|---|---|
| Git ref (tag/SHA) | git+...#<sha> or tag in manifest | Zero publishing; simplest | Default — dev and internal use |
| GitHub Release asset | Release tag + asset digest | Tag lineage; easy download; can be immutable | Governed releases, low infra |
| OCI artifact | name@sha256:... | Digest-addressed; org-wide distribution | Org-wide artifact distribution |
| npm/PyPI wrapper | Semver in ecosystem | Best app ergonomics | Mature orgs, broad consumer base |
Delivery targets
A delivery target is a declarative YAML file inpromptops/delivery/ that describes how to sync an approved version to a downstream system. The deliver.yml workflow iterates over these files and executes the sync for each target matching the promoted channel.
type and repo. Supported types include:
github_pr— open a PR to a downstream app repo updating itsconsumption.yamloci_registry— push the OCI artifact to an internal registry namespaceconfig_store— sync to a config store used by edge or runtime systems
Delivery is adapters, not a hosted platform. The system does not assume any particular delivery target — it defines the contract (promotion record in, sync executed out) and lets you implement the adapter for your infrastructure.
Rollback
Rollback is a promotion to a prior digest — not an edit to existing records. To roll back:- Find the previous promotion record for the
prodchannel inpromotions/on thepromotions-artifactsbranch. - Run the
promote.ymlworkflow with the prior digest and channelprod. - The workflow writes a new promotion record binding the prior digest to
prod. - The
deliver.ymlworkflow syncs the prior digest to allproddelivery targets. - Downstream apps update their
consumption.yamlpin to the prior digest.
Immutable releases
Theimmutable-release.yml workflow creates GitHub Releases that cannot be modified after publication. The key steps:
actions/attest-build-provenance) records the builder identity, workflow run, and input materials. This enables supply-chain verification for downstream consumers.