Projects

The WORKFLOW.md guide

How a project is configured, how to edit it in the app, and what happens when you save.

Each project is configured by one file, WORKFLOW.md, in the root of its repository (or another path you choose). It has two parts: YAML front matter between --- lines, which configures the project, and a Markdown body, which is the prompt the agent gets on its first turn.

WORKFLOW.md
---
tracker:
  kind: local
  active_states: [Todo, In Progress]
  terminal_states: [Done, Canceled]
workspace:
  root: ~/HarnessWorkspaces/my-app
docker:
  enabled: true
git:
  pull_request: draft
---
You are an autonomous senior engineer working on **{{ issue.identifier }}: {{ issue.title }}**.

{{ issue.description | default: "_No description provided._" }}

When the work is complete and verified, move the issue to **Human Review** and comment with a summary.

Because the file lives in the repository, it's versioned with your code, reviewed like code, and the same file works in Local and Remote mode.

Create one#

The Add Project wizard writes a complete, commented WORKFLOW.md for you, with your tracker, runner, model, Docker and pull-request choices filled in and the optional sections commented out. You rarely write one from scratch. See Example workflows for complete files.

Edit it in the app#

Open the project's Workflow tab. It has three views of the same draft:

  • Settings: a form for tracker states, agents and models, branch and PR options, limits, sandbox, browser and preview, links, gateway and hooks.
  • Prompt: the Liquid template, with a live preview rendered against a sample task (HAR-42: Add dark mode toggle to settings). Toggle Retry to preview what a retry attempt sees. Copy a variable inserts {{ issue.identifier }}, {{ attempt }} and the others.
  • Source: the raw file.

Next to the editor, the Effective configuration inspector shows what SI Fabrik will actually use, after defaults and $VAR resolution:

GroupShows
VariablesEvery $NAME the workflow references, and docker.env names, with where each value comes from: project, global, the SI Fabrik process, or not set
TrackerKind, active and terminal states, required labels, poll interval
AgentsRunner, concurrency (and per-state caps), max turns, max backoff, stall and silence timeouts
Claude Code / CodexCommand, model, permission mode or approval policy, budget per session
Model gatewayWhether it's on, the base URL, where the key comes from, model slots
Branch & PRManaged clone or after_create hook, base branch, save, hand-off action, PR provider, where git runs
LimitsDaily budget and tokens, cost cap per task, parking and pausing thresholds
LinksPackages, services, who it's shared with, who may file tasks here, and any link problems
IsolationWhere agents run, the image, the workspace root, where hooks run, and security warnings

How form edits are written#

Form edits change only the lines for that key. Comments, ordering and your own formatting are kept, and commented-out template keys such as # daily_budget_usd: 50 are filled in place. Every edit is checked by re-parsing the file; an edit that wouldn't read back exactly is rejected. If the YAML doesn't parse, the form is replaced by a message and you fix it in Source.

Save and hot reload#

  1. Review the diff

    Press Save… (⌘S). SI Fabrik shows a diff of your changes. If the file changed on disk since you opened it, the sheet warns you that saving replaces those changes.

  2. Save

    Confirm. The running orchestrator reloads the workflow right away; no restart needed. Edits you make in your own editor are picked up the same way.

Server projects

For a project on a harnessd server, the Workflow tab reads the file from the server (operator role) and Save… writes it there (admin role). The server refuses a save if the file changed since you opened it (409 changed) or if it doesn't validate (422 invalid_workflow).

Validation#

SI Fabrik validates the workflow when it loads and before every dispatch. A project with errors shows them in its header and doesn't dispatch.

CodeMeaning
missing_workflow_fileThe file can't be read
workflow_parse_errorInvalid YAML, or front matter opened with --- but never closed
workflow_front_matter_not_a_mapThe front matter isn't a YAML map
missing_tracker_kindtracker.kind is required
unsupported_tracker_kindNot one of local, clickup, github
invalid_tracker_configFor example, tracker.active_states is empty
invalid_hooks_timeouthooks.timeout_ms must be positive
invalid_max_turnsagent.max_turns must be positive
invalid_max_concurrent_agentsagent.max_concurrent_agents must be 0 or more
missing_claude_command / missing_codex_commandThe runner's command is empty
template_parse_error / template_render_errorThe prompt template is invalid, or uses an unknown variable or filter

Problems in links: (an invalid URL, a reserved token name, a project that doesn't share back) also block dispatch and show under Links in the inspector.

Secrets in WORKFLOW.md#

Never put a secret value in the file: it's committed, and agents can read it in their workspace. Reference variables instead:

YAML
tracker:
  kind: clickup
  provider:
    api_token: $CLICKUP_API_TOKEN
gateway:
  api_key: $LITELLM_API_KEY

$NAME and ${NAME} are resolved on the host, from the project environment, then the global environment. See Environment and variables.

See also#