> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trytrellis.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic Workflow Switching

> Select workflow variants per task, developer, or team without replacing the global workflow.

Trellis 0.7 separates the global workflow from a library of workflow variants.
Different tasks can use different variants while the project keeps one safe
fallback.

## Global switching and task selection are different

`trellis workflow --template <workflow-id>` replaces the global
`.trellis/workflow.md`. Use it when the project as a whole should move to a
different workflow.

Dynamic selection keeps variants under `.trellis/workflows/` and resolves one
at runtime for the active task. It does not overwrite the global workflow.

## Create a local workflow

Create a complete, editable workflow from the bundled native workflow:

```bash theme={null}
trellis workflow create review-first
```

Trellis writes `.trellis/workflows/review-first.md`, then asks two questions
in order:

1. Set `default_workflow: review-first` in `.trellis/config.yaml`?
2. Set `workflow=review-first` in `.trellis/.developer`?

Both default to no. The workflow file is created regardless of the answers.
Use `--skip-defaults` to create the file without prompts. Non-interactive
execution also skips the prompts.

The command copies the full native workflow so the new file already contains
the required phase headings, workflow-state blocks, and platform markers. It
never changes or removes the global `.trellis/workflow.md`.

## Save workflow variants to the project library

List bundled, marketplace, and already-saved workflows:

```bash theme={null}
trellis workflow --list
```

Save a variant:

```bash theme={null}
trellis workflow --save tdd
trellis workflow --save channel-driven-subagent-dispatch
```

Use another marketplace source when needed:

```bash theme={null}
trellis workflow \
  --marketplace owner/repository \
  --save my-workflow
```

The result is a user-managed file:

```text theme={null}
.trellis/workflows/
├── tdd.md
├── channel-driven-subagent-dispatch.md
└── my-workflow.md
```

`trellis update` does not overwrite files in this library. Re-run
`trellis workflow --save <workflow-id> --force` when you intentionally want to refresh
a saved template.

## Pin a workflow to a task

Choose the workflow when creating a task:

```bash theme={null}
python3 ./.trellis/scripts/task.py create \
  "Add checkout validation" \
  --workflow tdd
```

Change the active task's selection:

```bash theme={null}
python3 ./.trellis/scripts/task.py workflow tdd
```

Clear the task pin and return to the default chain:

```bash theme={null}
python3 ./.trellis/scripts/task.py workflow --clear
```

The selected id is stored in `task.json`:

```json theme={null}
{
  "workflow": "tdd"
}
```

The task pin only works when `.trellis/workflows/tdd.md` exists. A missing or
invalid variant prints a warning and falls through to the next default.

## Configure personal and team defaults

Runtime resolution uses one precedence chain:

| Priority | Source                                         | Scope                          | Committed |
| -------: | ---------------------------------------------- | ------------------------------ | :-------: |
|        1 | `task.json` `workflow`                         | Current task                   |    Yes    |
|        2 | `.trellis/.developer` `workflow=<workflow-id>` | Current developer and checkout |     No    |
|        3 | `.trellis/config.yaml` `default_workflow`      | Team                           |    Yes    |
|        4 | `.trellis/workflow.md`                         | Project fallback               |    Yes    |

Set a team default:

```yaml theme={null}
# .trellis/config.yaml
default_workflow: tdd
```

Set a personal override:

```ini theme={null}
# .trellis/.developer
name=alice
workflow=native
```

The personal file is gitignored, so one developer can prefer `native` while
the team default remains `tdd`. An explicit task pin still wins over both.

When a layer is unset, invalid, or points to a missing file, resolution
continues downward. If none of the optional layers apply, behavior is
identical to reading `.trellis/workflow.md` directly.

## What changes at runtime

The resolved workflow supplies all runtime workflow content:

* the Phase Index shown at session start
* the per-turn `[workflow-state:*]` breadcrumb
* phase and step details returned by `get_context.py --mode phase`
* Codex inline versus sub-agent dispatch guidance

Consumers share the same resolver, so changing a task pin takes effect on the
next workflow lookup. No new hook is installed for the switch.

## Keep variant files compatible

A workflow variant is executable input, not only prose. Keep these parser
markers:

* a `## Phase Index` section
* `#### X.Y` step headings
* `[workflow-state:STATUS]...[/workflow-state:STATUS]` blocks
* any platform routing markers used by your workflow

`trellis workflow --save` warns when a saved template is missing the standard
markers. The warning does not block custom workflows, but missing markers can
degrade session-start context, breadcrumbs, or phase lookup.

Workflow ids must match `[A-Za-z0-9_-]+`. This keeps every id inside
`.trellis/workflows/` and prevents path traversal.

## Current limits

* Selection is explicit. Trellis does not infer a workflow from task type.
* Pi Agent and Oh My Pi extensions still read the global
  `.trellis/workflow.md`; task, personal, and team selection does not apply to
  those two extensions yet.
* OpenCode per-turn breadcrumbs honor dynamic selection, but its SessionStart
  summary still reads the global workflow.
* Snow SessionStart and per-message context still read the global workflow.
* A saved marketplace workflow is a local copy. It does not update until you
  save it again with `--force`.

## Related pages

* [Custom Workflow](/beta/advanced/custom-workflow)
* [Dynamic Spec Loading](/beta/advanced/dynamic-spec-loading)
* [Everyday Use](/beta/start/everyday-use)
