CascadeGuard — Sortie Operations

How Sortie integrates with the CascadeGuard org for autonomous SDLC execution.

Constraint: One Repo Per Workflow

Sortie creates an isolated workspace per issue and checks out a single repository. It cannot work across multiple repos in one session. This shapes how we structure issues and workflows.

Repo Partitioning

RepoScopeSortie-managed
cascadeguard/cascadeguardOSS core — event-driven image lifecycle, Kargo integrationYes
cascadeguard/cascadeguard-appSaaS platform — landing page, dashboard, API, scan workerYes
cascadeguard/cascadeguard-docsDocumentation siteYes (triage, implement)
cascadeguard/cascadeguard-actionsReusable GitHub ActionsYes (implement, bugfix)
cascadeguard/cascadeguard-open-secure-imagesHardened base imagesYes (implement, bugfix)
cascadeguard/cascadeguard-orgOrg config as codeNo (manual / board only)

Issue Structure: Org Board → Repo Sub-Issues

GitHub org-level project boards (ProjectV2) provide cross-repo visibility, but every item on the board must belong to a repo. Sortie only sees repo-level issues.

Single-repo work

Most tickets touch one repo. Create the issue directly in that repo with the appropriate labels. Sortie picks it up.

[cascadeguard-app#42] Add billing endpoint
  labels: backlog, backend, api
  → Sortie TRIAGE → PLAN → IMPLEMENT → REVIEW

Cross-repo work

When a feature spans multiple repos, use a parent issue with sub-issues:

[cascadeguard-app#50] Add image attestation verification (parent)
  labels: backlog, backend, api, infra
  ├── [cascadeguard#30] Add attestation verification to core scanner
  │     labels: backlog, backend
  ├── [cascadeguard-app#51] Expose attestation results in dashboard API
  │     labels: backlog, backend, api, frontend
  └── [cascadeguard-docs#12] Document attestation verification feature
        labels: backlog, docs

Each sub-issue lives in its target repo. Sortie runs independently on each one. The parent issue on the org project board tracks overall progress.

Rules for cross-repo decomposition

  1. Parent issue lives in the primary repo (usually cascadeguard-app for business features, cascadeguard for OSS features)
  2. Sub-issues are created in each affected repo with their own labels
  3. Each sub-issue must be self-contained — it should be implementable by checking out only that repo
  4. Dependencies between sub-issues should be noted in the description (e.g., “depends on cascadeguard#30 being merged first”)
  5. The parent issue moves to done only when all sub-issues are done
  6. Delivery layers on the parent should list all layers across all sub-issues; each sub-issue lists only its own layers

Who decomposes

  • CTO decomposes technical features into repo-level sub-issues
  • CEO decomposes strategic initiatives into feature-level issues (which the CTO then decomposes further if cross-repo)
  • Product Owner verifies each sub-issue has clear acceptance criteria before it moves to todo

Parent ↔ child interactions at runtime

Sortie provides .issue.parent and .issue.blocked_by in the prompt template, so agents working on a sub-issue can see the parent context and any blockers.

What Sortie handles automatically:

  • Sub-issue agents see the parent identifier and can read the parent issue for context
  • Blocked-by relationships are rendered in the prompt so agents know about dependencies

What requires manual or external coordination:

  • Decomposition: The CTO’s PLAN workflow creates the plan. Decomposition into sub-issues across repos is done by the CTO via gh issue create in the appropriate repos (the agent has access to gh CLI in the Sortie workspace)
  • Parent completion: The parent issue should only move to done when all sub-issues are done. The org project board shows sub-issue progress. The CTO’s REVIEW workflow can check for this before closing the parent
  • Dependency ordering: If sub-issue B depends on sub-issue A being merged first, note this in B’s description and add a blocked label. Sortie won’t pick up blocked issues (they’re not in active_states). Remove the blocked label once the dependency is merged

Label-Based State Machine

Sortie uses GitHub issue labels as states. These labels must exist in every Sortie-managed repo.

Required labels

LabelSDLC PhaseDescription
triageIntakeNew issue, needs assessment
backlogPrioritisedAssessed, waiting for board approval
todoReadyBoard-approved, ready for pickup
in-progressBuildingAgent is working on it
reviewPR openImplementation complete, awaiting review
doneCompleteMerged and verified
wontfixTerminalClosed without action
blockedStalledWaiting on dependency or decision
needs-humanEscalationSortie exhausted retries, human needed
bugTypeBug report (used by BUGFIX workflow query_filter)
plannedEnrichmentCTO has created an implementation plan for this issue
skill:platformSkillWork suited for Lead Platform Engineer (infra, CI/CD, containers)
skill:fullstackSkillWork suited for Full-Stack Engineer (app frontend, API)
skill:devsecopsSkillWork suited for DevSecOps Engineer (security, scanning)

State flow

triage → backlog → todo → in-progress → review → done
 CTO      CTO     board    engineer      CTO
triages   plans   approves  pulls &      reviews
                            implements
                     ↓
                  blocked
                     ↓
                needs-human (escalation)

Label setup

Run once per repo to create the required labels:

REPO=cascadeguard/cascadeguard-app
for label in triage backlog todo in-progress review done wontfix blocked needs-human bug; do
  gh label create "$label" --repo "$REPO" --force 2>/dev/null || true
done

Workflow ↔ Repo Matrix

Each Sortie workflow instance targets one repo. The workflow files live at .ai/agents/cascadeguard/<agent>/sortie/ and default to cascadeguard-app. Override with SORTIE_TRACKER_PROJECT.

Workflowcascadeguardcascadeguard-appcascadeguard-docscascadeguard-actionscascadeguard-open-secure-images
TRIAGE✓ (default)
PLAN✓ (default)
IMPLEMENT✓ (default)
BUGFIX✓ (default)
REVIEW✓ (default)

To run a workflow against a non-default repo, use the repo-specific env file:

# cascadeguard-app (SaaS platform)
sortie --env-file hosts/mac-cascadeguard-app.env .ai/agents/cascadeguard/cto/sortie/IMPLEMENT.workflow.md
 
# cascadeguard (OSS core)
sortie --env-file hosts/mac-cascadeguard.env .ai/agents/cascadeguard/cto/sortie/IMPLEMENT.workflow.md

Toolchain differences

The IMPLEMENT and BUGFIX workflows include self_review.verification_commands that are toolchain-specific. The defaults target cascadeguard-app (turbo monorepo: npm run lint, npm run typecheck, npm run test).

For repos with different toolchains, create a variant workflow or override verification commands. Current toolchains:

RepoBuild systemLintTypecheckTest
cascadeguard-appturbo + npm workspacesnpm run lintnpm run typechecknpm run test
cascadeguardnpm (minimal)npm run test
cascadeguard-docsTBDTBDTBDTBD
cascadeguard-actionsGitHub Actions (YAML)
cascadeguard-open-secure-imagesDockerfiles + Taskfile

Running Sortie

Per-repo environment files

Each repo gets its own .env file per host. This sets the target repo, workspace root, and a separate SQLite DB path (Sortie instances sharing a DB will collide).

hosts/
├── mac-cascadeguard-app.env        # Mac + cascadeguard-app
├── mac-cascadeguard.env            # Mac + cascadeguard (OSS)
├── k8s-lab-cascadeguard-app.env    # k8s-lab + cascadeguard-app
├── k8s-lab-cascadeguard.env        # k8s-lab + cascadeguard (OSS)
├── mac.env                         # Mac base (shared config only)
└── k8s-lab.env                     # k8s-lab base (shared config only)

Running a single workflow

sortie --env-file hosts/mac-cascadeguard-app.env \
  .ai/agents/cascadeguard/cto/sortie/IMPLEMENT.workflow.md

Running all workflows (multi-process)

Each workflow × repo combination is a separate Sortie process. Use a Procfile runner to manage them.

Recommended: overmind (tmux-based, brew install overmind):

# From workspace root
overmind start -f .ai/agents/cascadeguard/cto/sortie/Procfile

Each process gets its own tmux pane. Attach to a specific one with overmind connect cto-plan-app. Restart with overmind restart cto-plan-app.

Alternative: goreman (simpler, no tmux):

goreman -f .ai/agents/cascadeguard/cto/sortie/Procfile start

On k8s-lab: Each workflow × repo is a separate Deployment. Mount the .env file as a ConfigMap/Secret and the workflow files from a volume.

Required environment variables

VariableSourceDescription
SORTIE_GITHUB_TOKENAgent PATGitHub PAT with repo scope for the target repo
ANTHROPIC_API_KEYAPI keyAnthropic API key for Claude Code
SORTIE_WORKSPACE_ROOThosts/*.envWorkspace root path (host-specific)
SORTIE_TRACKER_PROJECThosts/*.envTarget repo in owner/repo format
SORTIE_DB_PATHhosts/*.envPer-instance SQLite DB path (avoids collisions)

Agent ↔ Workflow Assignment

Different agents run different subsets of workflows based on their role.

AgentTRIAGEPLANIMPLEMENTBUGFIXREVIEW
CTO (Priya)
Full-Stack Engineer (Tomás)
Lead Platform Engineer (Kai)
DevSecOps Engineer (Jordan)
Product Owner (Sana)

The CTO focuses on triage, planning, and review. Engineers focus on implementation. This mirrors the SDLC where the CTO does not write production code.

File Layout

.ai/agents/cascadeguard/
├── ORG.md                              # Org context (all agents, all tools)
├── SORTIE.md                           # This file — Sortie operations
├── workflows/                          # Generic SDLC workflows (tool-agnostic)
│   ├── triage.md
│   ├── plan.md
│   ├── implement.md
│   ├── bugfix.md
│   └── review.md
├── cto/sortie/                         # CTO's Sortie workflow files
│   ├── Procfile                        # Multi-process runner config
│   ├── TRIAGE.workflow.md
│   ├── PLAN.workflow.md
│   ├── IMPLEMENT.workflow.md
│   ├── BUGFIX.workflow.md
│   └── REVIEW.workflow.md
├── full-stack-engineer/sortie/         # (future) Engineer workflows
├── lead-platform-engineer/sortie/      # (future) Platform eng workflows
└── devsecops-engineer/sortie/          # (future) DevSecOps workflows

hosts/
├── mac-cascadeguard-app.env            # Mac + cascadeguard-app
├── mac-cascadeguard.env                # Mac + cascadeguard (OSS)
├── k8s-lab-cascadeguard-app.env        # k8s-lab + cascadeguard-app
├── k8s-lab-cascadeguard.env            # k8s-lab + cascadeguard (OSS)
├── mac.env                             # Mac base config
└── k8s-lab.env                         # k8s-lab base config