Scenario: CLI to Production
Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.
In this scenario, you use orqestractl to author, validate, and deploy a workflow entirely from the terminal — then set up GitOps sync for ongoing deployments.
What you’ll do
- Author assets and a flow as local YAML files
- Validate the flow structure
- Deploy to Orqestra via the CLI
- Promote through the release lifecycle
- Set up GitOps sync for continuous deployment
Prerequisites
orqestractlinstalled (pip install orqestra-cli)- Orqestra running locally (
make dev) - API credentials configured:
export ORQESTRA_API_URL=http://localhost:8000 export ORQESTRA_API_KEY=your-key
Step 1: Author Resources Locally
Create a project directory with your Orqestra resources:
mkdir -p orqestra-project/{assets,flows}assets/classifier-prompt.yaml:
kind: asset
slug: classifier-prompt
asset_kind: prompt_template
owner_ref: team:support
version:
label: v1
content:
system_message: "You are a ticket classification system. Classify each ticket as low, medium, or high urgency."
user_template: "Classify this ticket: {{ query }}"assets/model-policy.yaml:
kind: asset
slug: ticket-model-policy
asset_kind: model_policy
owner_ref: team:support
version:
label: v1
content:
provider_route:
route_id: your-provider-classifier-us
provider: your-provider
model: your-provider/your-model
account_slot: your-provider-prod
region: us-east-1
residency: us
state: approved
sensitivity_tiers: [public, internal]
capability_tags: [chat, classification]
cost_class: standard
prompt_caching: allowed
logging: redacted
fallback_routes: []
temperature: 0.1
max_tokens: 100assets/workload-profile.yaml:
kind: asset
slug: ticket-workload-profile
asset_kind: workload_profile
owner_ref: team:support
version:
label: v1
content:
category: chat
audience: internal
autonomy_level: assistive
data_sensitivity: internal
retrieval_needs: { required: false }
memory_needs: { required: true }
tool_needs: { required: false }
egress_needs: { posture: none }
evidence_expectations: { trace_level: detailed }assets/sandbox-profile.yaml:
kind: asset
slug: ticket-sandbox-profile
asset_kind: sandbox_profile
owner_ref: team:support
version:
label: v1
content:
isolation_class: process
capabilities: { code_execution: true, tool_use: true, retrieval: true, memory: true }
resource_limits: { timeout_seconds: 60 }
network_posture: { egress: none }
data_access: { max_sensitivity: internal }
secret_posture: none
tool_posture: { allowed: true, families: [http_request], max_side_effect_class: read_write }
evidence_requirements: { trace_level: detailed }
lifecycle_posture: workspace_scopedassets/harness.yaml:
kind: asset
slug: ticket-harness
asset_kind: workload_harness
owner_ref: team:support
version:
label: v1
content:
# Scenario assertions are empty for the quickstart; the harness
# still pins the release to a governed harness asset version.
scenarios: []
negative_scenarios: []
retrieval_assertions: []
memory_assertions: []
tool_assertions: []
egress_assertions: []
evidence_checks: []
evaluation_refs: []flows/classify-ticket.yaml:
kind: flow
slug: classify-ticket
owner_ref: team:support
version:
label: v1
content:
name: Ticket Classifier
description: Classifies support tickets by urgency
trigger:
type: api_request
inputs_schema:
type: object
required: [query]
properties:
query:
type: string
entry_step: classify
steps:
- id: classify
type: llm_call
config:
prompt_template_ref: classifier-promptStep 2: Validate the Flow
Check for structural errors before deploying:
orqestractl flow validate --file flows/classify-ticket.yamlExpected output:
Flow validation: PASSED
Steps: 1
Entry step: classify (valid)
Trigger: api_request (valid)
References: prompt_template_ref=classifier-promptStep 3: Deploy with Sync
Use orqestractl sync to create all resources in one command:
# Preview what will be created
orqestractl sync preview --dir ./orqestra-project
# Apply
orqestractl sync apply --dir ./orqestra-projectOutput:
Sync complete:
Created: 2 assets, 1 flow
Updated: 0
Unchanged: 0Declarative asset versions are idempotent by label and content. Re-running
orqestractl sync preview --dir ./orqestra-project skips an existing matching version.
If you change the content of an immutable version label such as v1, sync stops
and asks you to create a new label such as v2.
Step 4: Create the Workload and Release
# Declare the workload's PII classification up front (the interface config
# file is the full interface_config document).
echo 'pii_classification: internal' > interface.yaml
# Create the application, declaring every runtime-readiness input up front:
# an invocation mode, a PII classification (via --interface-config), the
# release environment intent, and the three authoring-default asset versions
# (workload profile / sandbox profile / harness — captured like the other
# version IDs below, from the portal or the JSON APIs).
WORKLOAD_ID=$(orqestractl --format json workload create --slug ticket-classifier --owner team:support \
--invocation-mode api --release-environment-intent production \
--interface-config interface.yaml \
--default-workload-profile-id $WL_PROFILE_V1 \
--default-sandbox-profile-id $SBX_PROFILE_V1 \
--default-workload-harness-id $HARNESS_V1 | jq -r '.workload_id')
# Bind a service lane — an effective lane binding is required before the
# workload can dispatch real runs.
orqestractl workload lane-binding add $WORKLOAD_ID --lane standard
# Create a release
RELEASE_ID=$(orqestractl --format json release create --workload $WORKLOAD_ID --environment production | jq -r '.release_id')Runtime-readiness activation gate. Activating a release on an operator-managed workload requires the workload to be runtime-ready (invocation mode, PII classification, workload profile / sandbox profile / harness defaults, a service-lane binding, a release environment intent, human oversight when required, and every declared connection requirement). If anything is missing, the
--to activetransition is refused with a typed409 workload_not_readywhoseblockerslist names every missing item — fix the named items and retry. The workload page’s readiness banner shows the same projection, andorqestractl release transitionprints the refusal with the missing-readiness list.
# Bind assets (release bind expects asset_version_id values)
# Capture these IDs from the portal or the JSON APIs if you do not already
# have them from earlier create/version calls.
orqestractl release bind $RELEASE_ID --asset-version $PROMPT_V1 --role main_prompt
orqestractl release bind-model-policy $RELEASE_ID --asset-version $MODEL_POLICY_V1
orqestractl release bind $RELEASE_ID --asset-version $FLOW_V1 --role orchestration_flow
orqestractl release bind $RELEASE_ID --asset-version $POLICY_V1 --role policy_bundle
# Promote through the release lifecycle
orqestractl release transition $RELEASE_ID --to review_ready
# Record at least one approval via the portal or API before approving
curl -X POST http://localhost:8000/v1/releases/$RELEASE_ID/approvals \
-H "Content-Type: application/json" \
-d '{
"outcome": "approved",
"subject_kind": "release",
"subject_ref": "'"$RELEASE_ID"'"
}'
orqestractl release transition $RELEASE_ID --to approved
orqestractl release transition $RELEASE_ID --to activeStep 5: Test the Deployment
orqestractl release get $RELEASE_IDAt this point the release is live. For a bounded knowledge-query workload you can also use:
orqestractl run <workload-slug> --query "What is Orqestra?"For non-chat workloads, use the portal or the workload-specific interface you attached to that release.
Step 6: Set Up GitOps for Continuous Deployment
Push your project to Git and add a CI pipeline:
cd orqestra-project
git init
git add .
git commit -m "Initial Orqestra resources"
git remote add origin git@github.com:<your-org>/orqestra-resources.git
git push -u origin main.github/workflows/deploy.yml:
name: Deploy to Orqestra
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- run: pip install orqestra-cli
- run: orqestractl sync reconcile --dir .
env:
ORQESTRA_API_URL: ${{ secrets.ORQESTRA_API_URL }}
ORQESTRA_API_KEY: ${{ secrets.ORQESTRA_API_KEY }}Now every push to main automatically syncs your resource definitions to Orqestra.
For separate Orqestra instances, export the governed release shape from the source instance and import it into the target after the referenced asset versions and target connection instances exist:
orqestractl release export-manifest $RELEASE_ID \
--workspace $SOURCE_WORKSPACE_ID \
--file release-manifest.yaml
orqestractl release import-manifest \
--workspace $TARGET_WORKSPACE_ID \
--file release-manifest.yamlThe manifest contains the release policy bundle slug, pinned asset versions, and logical connection bindings. It does not contain secrets; connection parameters must be non-secret configuration, and each target instance keeps its own Vault secrets.
Step 7: Make a Change
Update the prompt and push:
# Edit the prompt
vim assets/classifier-prompt.yaml
# Change version label to v2, update the system_message
git add -A
git commit -m "Improve classifier prompt"
git pushThe CI pipeline runs orqestractl sync reconcile --dir ., creating or updating
the declared resources. Create a new release to activate new versions.
What you’ve learned
- How to author Orqestra resources as local YAML files
- How to validate flows before deployment
- How to deploy with
orqestractl sync - How to promote releases through the actual release lifecycle (
review_ready -> approved -> active) - How to set up GitOps for continuous deployment from Git