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

# Agents and connectors

> Define SAF files, prompt responsibilities, connector configs, and authoring rules for a Fabriqa workflow.

# Agents and connectors

After you define `workflow.yaml` and your artifact schemas, you still need to define:

* which agents exist
* what they are allowed to do
* which prompt owns sequencing
* how artifacts project into connector targets

## Agent SAF files

Each workflow agent is defined in a `.saf` file.

SAF files are JSON documents. They describe:

* who the agent is
* which generic kind of work it owns
* which prompt file it uses
* which workflow and coding tools it may call

SAF files do not describe ACP behavior, LLM behavior, or provider capability policy. Fabriqa runtime owns that adaptation.

### SAF format

Fabriqa reads these top-level SAF keys:

| Key             | Required | Purpose                                   |
| --------------- | -------- | ----------------------------------------- |
| `saf_version`   | Yes      | SAF document version                      |
| `agent`         | Yes      | Agent identity                            |
| `system_prompt` | Yes      | Relative path to the prompt markdown file |
| `tools`         | Yes      | Workflow and coding tool access           |

The `agent` object includes:

| Key    | Required | Purpose                                               |
| ------ | -------- | ----------------------------------------------------- |
| `id`   | Yes      | Stable workflow agent ID                              |
| `name` | Yes      | Human-facing label                                    |
| `kind` | Yes      | Generic Fabriqa agent kind: `planning` or `execution` |

### Example

```json theme={null}
{
  "saf_version": "1.0.0",
  "agent": {
    "id": "planner",
    "name": "Planner",
    "kind": "planning"
  },
  "system_prompt": "prompts/planner.md",
  "tools": {
    "workflow": [
      "capabilities",
      "workflow_get",
      "artifact_type_get",
      "artifact_list",
      "artifact_get",
      "artifact_validate",
      "artifact_create",
      "artifact_update",
      "relation_add",
      "relation_list"
    ],
    "coding": [
      "read_file",
      "web_search",
      "fetch"
    ]
  }
}
```

### Field-by-field guidance

* `saf_version`
  * Keep this at the SAF version Fabriqa supports.
* `agent.id`
  * Must stay stable because workflows reference agents by ID in `workflow.yaml`.
* `agent.kind`
  * Declares the generic Fabriqa behavior this agent participates in.
  * Use `planning` for agents that coordinate, inspect, and shape work.
  * Use `execution` for agents that perform execution work.
  * Keep it consistent with `tools.coding`. Planning agents should not declare `execute` or `"full"`. Execution agents should declare `execute` or `"full"`.
* `system_prompt`
  * Should point to a markdown file in `prompts/`.
  * Put long behavior instructions there instead of embedding them in JSON.
* `tools.workflow`
  * Declare the workflow tools the agent is allowed to use.
  * This is always a subset selected from Fabriqa's predefined workflow-tool list.
* `tools.coding`
  * Declare coding and external-read tools.
  * This is always a subset selected from Fabriqa's predefined coding-tool list, or the special `"full"` mode.

### Runtime ownership

Fabriqa intentionally keeps SAF runtime-agnostic.

That means workflow authors do not define:

* ACP decorator policy
* LLM provider capability requirements
* runtime-specific builtin tool allowlists
* per-agent budget or max-turn transport policy

Fabriqa runtime owns those translations. The SAF only declares the portable agent contract.

### `tools.workflow`

`tools.workflow` is a workflow-author-selected subset of Fabriqa's built-in workflow-tool vocabulary.

Workflow authors do not invent names here. Fabriqa defines the vocabulary, and each SAF file chooses only the tools that agent actually needs.

If a SAF file declares an unknown workflow tool, Fabriqa should reject the workflow definition during validation and loading.

Current built-in workflow tools:

| Tool                     | Purpose                                                                 |
| ------------------------ | ----------------------------------------------------------------------- |
| `capabilities`           | Inspect the runtime workflow capability block for the active workspace. |
| `workspace_project_list` | List attached workspace projects for scope decisions.                   |
| `workflow_get`           | Inspect the active workflow definition.                                 |
| `workflow_ready`         | List ready and currently unblocked artifacts.                           |
| `workflow_claim`         | Claim one ready artifact for execution.                                 |
| `artifact_type_list`     | List workflow-defined artifact schemas.                                 |
| `artifact_type_get`      | Inspect one artifact schema.                                            |
| `artifact_list`          | List artifacts in the current workflow instance.                        |
| `artifact_get`           | Fetch one artifact by ID.                                               |
| `artifact_validate`      | Validate a create or update payload without mutating state.             |
| `artifact_create`        | Create one artifact.                                                    |
| `artifact_update`        | Update one artifact.                                                    |
| `artifact_complete`      | Complete one artifact.                                                  |
| `relation_add`           | Add one relation between artifacts.                                     |
| `relation_list`          | Inspect relations for one artifact.                                     |

Typical patterns:

* routing or coordinator agents usually need a read-oriented subset such as `capabilities`, `workflow_get`, `artifact_list`, `artifact_get`, and `relation_list`
* planning agents usually add `artifact_validate`, `artifact_create`, `artifact_update`, and sometimes `workspace_project_list`
* execution agents usually add `workflow_ready`, `workflow_claim`, and `artifact_complete`

### `tools.coding`

`tools.coding` is also selected from a predefined Fabriqa vocabulary.

Keep the public authoring surface simple. In v1, use one of these three forms:

```json theme={null}
"coding": []
```

```json theme={null}
"coding": ["read_file", "fetch"]
```

```json theme={null}
"coding": "full"
```

Rules:

* omit `coding` or use `[]` for no coding-tool access
* use a string list when the agent needs only a narrow subset
* use `"full"` when the agent needs unrestricted coding-tool access
* `"full"` is a mode, not a tool name
* there is no authored `"read_only"` literal in the SAF format

Current built-in coding tools:

| Tool         | Purpose                                    |
| ------------ | ------------------------------------------ |
| `read_file`  | Read workspace files directly.             |
| `web_search` | Search the web for external context.       |
| `fetch`      | Fetch a specific URL or remote document.   |
| `execute`    | Run commands in the workspace environment. |

Typical patterns:

* planning agents usually use `read_file`, `web_search`, and `fetch`
* operations-style agents may add `execute`
* implementation agents typically use `"full"`

Validation rule:

* workflow authors cannot invent custom coding tool names
* if a SAF file declares an unknown coding tool, Fabriqa should reject the workflow definition during validation and loading

### Example: AI-DLC `inception`

This is the built-in AI-DLC planning agent. It captures intents, decomposes them into units and stories, and plans bolts for construction.

```json theme={null}
{
  "saf_version": "1.0.0",
  "agent": {
    "id": "inception",
    "name": "Inception",
    "kind": "planning"
  },
  "system_prompt": "prompts/inception.md",
  "tools": {
    "workflow": [
      "capabilities",
      "workflow_get",
      "artifact_type_get",
      "artifact_list",
      "artifact_get",
      "artifact_validate",
      "artifact_create",
      "artifact_update",
      "relation_add",
      "relation_list"
    ],
    "coding": [
      "read_file",
      "web_search",
      "fetch"
    ]
  }
}
```

Read this example like this:

* `system_prompt` points to `prompts/inception.md`, which contains the actual planning ritual and sequencing rules
* `agent.kind` marks Inception as a planning agent, so Fabriqa treats it as planning behavior instead of execution behavior
* `tools.workflow` gives Inception the planning subset it needs to inspect, validate, create, update, and relate workflow artifacts
* `tools.coding` is intentionally narrow because Inception is a planning agent, not a coding agent

The important split is:

* SAF defines the portable agent contract
* prompt defines the behavior

## SAF guidance

* Put long behavior instructions in the prompt file, not in the SAF JSON itself.
* Keep the `agent` object minimal: `id`, `name`, and `kind`.
* Use `agent.kind` to declare generic planning versus execution behavior.
* Keep workflow tool access explicit and minimal.
* Treat coding tool access as part of the workflow contract.
* Select both `tools.workflow` and `tools.coding` from Fabriqa's predefined vocabularies.
* Expect workflow validation to fail if a SAF file uses an unknown tool name.
* Do not encode ACP or provider-specific behavior in the SAF file.

## Prompt responsibilities

Prompts remain the main control surface for:

* when to create a `run`
* when to create a `bolt`
* when to create design docs
* when to create execution outputs
* when to replan
* when to complete work

The DSL exists so prompts can inspect a stable, structured workflow model instead of guessing from naming conventions.

### Good prompt boundary

Prompt decides:

* sequencing
* prioritization
* whether to replan
* whether a new output artifact is needed

DSL decides:

* what artifacts exist
* what each artifact means
* which parent association is required
* which fields are required
* how the artifact renders

## Connector configs

Connector kinds are product-defined by Fabriqa.

The workflow definition only does two things:

* subscribes to built-in connector kinds in `workflow.yaml`
* provides connector-specific mapping files in `connectors/*.yaml`

### File connector

The file connector usually relies on templates.

```yaml theme={null}
# workflow.yaml
connectors:
  file: connectors/file.yaml
```

```yaml theme={null}
# connectors/file.yaml
kind: file

artifacts:
  walkthrough:
    template: templates/walkthrough.md.tmpl
    filename: walkthroughs/{{ artifact.display_id }}.md
```

Use file templates for:

* markdown snapshots of artifacts
* handoff docs in the repo
* workflow-friendly exports for code review and history

### Future platform connectors

Issue trackers and docs platforms will usually need structured field mappings instead of markdown templates.

```yaml theme={null}
# connectors/linear.yaml
kind: linear

objects:
  work_item:
    target: issue
    fields:
      title: title
      description: description
      tags: labels
```

Do not use connector config as the source of truth. The source of truth is still the artifact record plus its schema.

### Runtime settings live in Fabriqa

After a workflow is activated on a workspace, Fabriqa owns:

* connector enable or disable state
* connection or account selection
* target workspace project selection
* sync state and execution behavior

Those settings are runtime configuration, not workflow definition.

## Authoring checklist

Before publishing a workflow:

1. Keep `workflow.yaml` orchestration-focused.
2. Keep artifact-local meaning in the artifact schema file.
3. Prefer markdown sections for the main body of documents.
4. Keep primitive status and scope fields in `schema.properties` and let Fabriqa surface them as metadata automatically when they are not used by a document section.
5. Write `description` on every field that an agent could misread.
6. Keep artifact behavior in prompts and keep artifact schemas structural.
7. Keep the prompt responsible for sequencing.
8. Add connector config files only when the workflow needs projection or sync.
9. Keep runtime connector settings out of the DSL.

## Related pages

<CardGroup cols={2}>
  <Card title="Workflow DSL overview" icon="compass" href="/workflows/workflow-dsl">
    Go back to the Workflow DSL overview.
  </Card>

  <Card title="Artifact schemas" icon="scroll-text" href="/workflows/workflow-dsl-artifact-schemas">
    Review artifact sections and lifecycles again.
  </Card>

  <Card title="AI-DLC workflow" icon="zap" href="/workflows/ai-dlc">
    See a built-in workflow that uses these prompt and connector patterns.
  </Card>

  <Card title="Workflow glossary" icon="book-open" href="/workflows/workflow-glossary">
    Keep the workflow vocabulary close while authoring.
  </Card>
</CardGroup>
