Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,41 @@ error_handling:
channel: "#eng-reviews"
```


### Multi-Agent Coordination via GNAP

When multiple gitagent-defined agents need to work together on shared tasks, use [GNAP (Git-Native Agent Protocol)](https://github.com/farol-team/gnap) as the coordination layer. A shared git repo acts as a persistent, auditable task board — no orchestrator process required.

```
coordination-board/ # shared GNAP repo (separate from agent repos)
├── board/
│ ├── todo/
│ │ └── analyze-report.md # task waiting to be claimed
│ ├── doing/
│ │ └── write-summary.md # claimed by agent-b (owner set in front-matter)
│ └── done/
│ └── fetch-data.md # completed with output appended
```

Agents coordinate by committing file moves: `todo/ → doing/ → done/`. Every transition is a git commit — full audit trail, no extra infrastructure.

**Task file format:**

```markdown
---
id: analyze-report-001
priority: high
owner: null
required_role: analyst
---
# Analyze Q1 Report
...
```

**SOD integration:** combine `required_role` in task files with `conflicts` in `agent.yaml` to prevent the same agent from both creating and completing high-stakes tasks.

See [`examples/gnap-coordination/`](examples/gnap-coordination/) for a full working example with a SkillsFlow workflow that polls the board, claims tasks, and writes results.

### Porting Framework Agents to GitAgent

Agents built in frameworks like NVIDIA AIQ, LangGraph, or CrewAI have their identity split across config files, Jinja2 templates, and Python code. gitagent extracts the **identity layer** — prompts, rules, roles, tool schemas — into a portable, versionable format.
Expand Down
56 changes: 56 additions & 0 deletions examples/gnap-coordination/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# GNAP Coordination Example

This example shows how to use GNAP (Git-Native Agent Protocol) as the coordination layer for multiple gitagent-defined agents.

## What is GNAP?

[GNAP](https://github.com/farol-team/gnap) is a git-native coordination protocol where a shared repo acts as a persistent, auditable task board. Agents communicate by reading and writing files — no orchestrator process required.

## Board Structure

```
board/
├── todo/ # tasks waiting to be claimed
├── doing/ # tasks currently in progress (claimed by an agent)
└── done/ # completed tasks with outputs
```

Each task is a markdown file with a YAML front-matter header:
```markdown
---
id: task-001
priority: high
owner: null # set to AGENT_ID when claimed
required_role: analyst
---

# Task description...
```

## How it works with gitagent

1. **Definition layer (gitagent):** Each agent is defined by `agent.yaml` + `SOUL.md` with clear roles via `DUTIES.md`
2. **Coordination layer (GNAP):** Agents share a git repo as a task board, coordinating via commits
3. **SOD enforcement:** `required_role` in task files + `conflicts` in `agent.yaml` prevents the same agent from creating and completing high-stakes tasks

## Running the example

```bash
# Set up the coordination board
git init gnap-board && cd gnap-board
mkdir -p board/{todo,doing,done}
git add . && git commit -m "init: gnap board"

# Configure the worker agent
export GNAP_BOARD_URL="file:///path/to/gnap-board"
export AGENT_ID="worker-1"

# Run the workflow
gitagent run . --adapter git
```

## Further reading

- [GNAP specification](https://github.com/farol-team/gnap)
- [gitagent SkillsFlow docs](../../spec/SPECIFICATION.md)
- [Segregation of Duties pattern](../../README.md#segregation-of-duties-sod)
32 changes: 32 additions & 0 deletions examples/gnap-coordination/agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
spec_version: "0.1.0"
name: gnap-worker
version: 0.1.0
description: >
Example agent that coordinates with peers via a shared GNAP board.
Claims tasks from board/todo/, processes them, moves to board/done/.

model:
preferred: claude-sonnet-4-6

compliance:
segregation_of_duties:
roles:
- id: analyst
description: Processes analysis tasks
permissions: [claim, process, complete]
- id: reviewer
description: Reviews completed work
permissions: [review, approve, reject]
conflicts:
- [analyst, reviewer]
assignments:
gnap-worker: [analyst]
enforcement: strict

environment:
- name: GNAP_BOARD_URL
description: URL of the shared GNAP coordination git repo
required: true
- name: AGENT_ID
description: Unique identifier for this agent instance
required: true
18 changes: 18 additions & 0 deletions examples/gnap-coordination/board/todo/analyze-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
id: analyze-report-001
priority: high
owner: null
created_by: orchestrator
created_at: 2026-03-15T10:00:00Z
required_role: analyst
---

# Analyze Q1 Report

Analyze the Q1 financial report and extract key metrics.

## Input
- file: knowledge/q1-report.pdf

## Expected Output
- metrics: revenue, growth_rate, top_risks
50 changes: 50 additions & 0 deletions examples/gnap-coordination/workflows/gnap-worker-flow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: gnap-worker-flow
description: Claim and process tasks from a shared GNAP coordination board

triggers:
- schedule: "*/5 * * * *" # poll board every 5 minutes

steps:
claim:
tool: bash
inputs:
command: |
git clone $GNAP_BOARD_URL /tmp/board
cd /tmp/board
TASK=$(ls board/todo/ | head -1)
if [ -z "$TASK" ]; then echo "no_task"; exit 0; fi
git mv board/todo/$TASK board/doing/$TASK
sed -i "s/owner: null/owner: $AGENT_ID/" board/doing/$TASK
git commit -m "claim: $TASK by $AGENT_ID"
git push
echo $TASK

process:
agent: analyst
depends_on: [claim]
conditions:
- ${{ steps.claim.outputs.stdout != 'no_task' }}
inputs:
task_file: board/doing/${{ steps.claim.outputs.stdout }}

complete:
tool: bash
depends_on: [process]
inputs:
command: |
cd /tmp/board
TASK="${{ steps.claim.outputs.stdout }}"
git mv board/doing/$TASK board/done/$TASK
echo "\n\n## Output\n${{ steps.process.outputs }}" >> board/done/$TASK
git commit -m "done: $TASK"
git push

error_handling:
on_failure:
tool: bash
inputs:
command: |
cd /tmp/board
git mv board/doing/$TASK board/todo/$TASK
git commit -m "requeue: $TASK (failed)"
git push