Refine session management terminology and clarify plugin-controlled lifecycle in documentation

This commit is contained in:
Lauren ten Hoor
2026-02-08 20:49:44 +08:00
parent fd6c5142b9
commit d921b5c7bb
3 changed files with 147 additions and 122 deletions

View File

@@ -2,21 +2,21 @@
**Every group chat becomes an autonomous development team.**
Add the agent to a Telegram group, point it at a GitLab repo — that group now has an **orchestrator** managing the backlog, a **DEV** sub-agent session writing code, and a **QA** sub-agent session reviewing it. All autonomous. Add another group, get another team. Each project runs in complete isolation with its own task queue, workers, and session state.
Add the agent to a Telegram group, point it at a GitLab repo — that group now has an **orchestrator** managing the backlog, a **DEV** worker session writing code, and a **QA** worker session reviewing it. All autonomous. Add another group, get another team. Each project runs in complete isolation with its own task queue, workers, and session state.
DevClaw is the [OpenClaw](https://openclaw.ai) plugin that makes this work.
## Why
[OpenClaw](https://openclaw.ai) is great at giving AI agents the ability to develop software — spawn sub-agent sessions, manage sessions, work with code. But running a real multi-project development pipeline exposes a gap: the orchestration layer between "agent can write code" and "agent reliably manages multiple projects" is brittle. Every task involves 10+ coordinated steps across GitLab labels, session state, model selection, and audit logging. Agents forget steps, corrupt state, null out session IDs they should preserve, or pick the wrong model for the job.
[OpenClaw](https://openclaw.ai) is great at giving AI agents the ability to develop software — spawn worker sessions, manage sessions, work with code. But running a real multi-project development pipeline exposes a gap: the orchestration layer between "agent can write code" and "agent reliably manages multiple projects" is brittle. Every task involves 10+ coordinated steps across GitLab labels, session state, model selection, and audit logging. Agents forget steps, corrupt state, null out session IDs they should preserve, or pick the wrong model for the job.
DevClaw fills that gap with guardrails. It gives the orchestrator atomic tools that make it impossible to forget a label transition, lose a session reference, or skip an audit log entry. The complexity of multi-project orchestration moves from agent instructions (that LLMs follow imperfectly) into deterministic code (that runs the same way every time).
## The idea
One orchestrator agent manages all your projects. It reads task backlogs, creates issues, decides priorities, and delegates work. For each task, it spawns (or reuses) a **DEV** sub-agent session to write code or a **QA** sub-agent session to review it. Every Telegram group is a separate project — the orchestrator keeps them completely isolated while managing them all from a single process.
One orchestrator agent manages all your projects. It reads task backlogs, creates issues, decides priorities, and delegates work. For each task, DevClaw creates (or reuses) a **DEV** worker session to write code or a **QA** worker session to review it. Every Telegram group is a separate project — the orchestrator keeps them completely isolated while managing them all from a single process.
DevClaw gives the orchestrator four tools that replace hundreds of lines of manual orchestration logic. Instead of following a 10-step checklist per task (fetch issue, check labels, pick model, check for existing session, transition label, update state, log audit event...), it calls `task_pickup` and the plugin handles everything atomically.
DevClaw gives the orchestrator four tools that replace hundreds of lines of manual orchestration logic. Instead of following a 10-step checklist per task (fetch issue, check labels, pick model, check for existing session, transition label, dispatch task, update state, log audit event...), it calls `task_pickup` and the plugin handles everything atomically — including session dispatch.
## How it works
@@ -26,33 +26,33 @@ graph TB
direction TB
A_O["🎯 Orchestrator"]
A_GL[GitLab Issues]
A_DEV["🔧 DEV (sub-agent session)"]
A_QA["🔍 QA (sub-agent session)"]
A_DEV["🔧 DEV (worker session)"]
A_QA["🔍 QA (worker session)"]
A_O -->|task_pickup| A_GL
A_O -->|spawns / sends| A_DEV
A_O -->|spawns / sends| A_QA
A_O -->|task_pickup dispatches| A_DEV
A_O -->|task_pickup dispatches| A_QA
end
subgraph "Group Chat B"
direction TB
B_O["🎯 Orchestrator"]
B_GL[GitLab Issues]
B_DEV["🔧 DEV (sub-agent session)"]
B_QA["🔍 QA (sub-agent session)"]
B_DEV["🔧 DEV (worker session)"]
B_QA["🔍 QA (worker session)"]
B_O -->|task_pickup| B_GL
B_O -->|spawns / sends| B_DEV
B_O -->|spawns / sends| B_QA
B_O -->|task_pickup dispatches| B_DEV
B_O -->|task_pickup dispatches| B_QA
end
subgraph "Group Chat C"
direction TB
C_O["🎯 Orchestrator"]
C_GL[GitLab Issues]
C_DEV["🔧 DEV (sub-agent session)"]
C_QA["🔍 QA (sub-agent session)"]
C_DEV["🔧 DEV (worker session)"]
C_QA["🔍 QA (worker session)"]
C_O -->|task_pickup| C_GL
C_O -->|spawns / sends| C_DEV
C_O -->|spawns / sends| C_QA
C_O -->|task_pickup dispatches| C_DEV
C_O -->|task_pickup dispatches| C_QA
end
AGENT["Single OpenClaw Agent"]
@@ -65,7 +65,7 @@ It's the same agent process — but each group chat gives it a different project
## Task lifecycle
Every task (GitLab issue) moves through a fixed pipeline of label states. Issues are created by the orchestrator agent or by sub-agent sessions — not manually. DevClaw tools handle every transition atomically — label change, state update, audit log, and session management in a single call.
Every task (GitLab issue) moves through a fixed pipeline of label states. Issues are created by the orchestrator agent or by worker sessions — not manually. DevClaw tools handle every transition atomically — label change, state update, audit log, and session management in a single call.
```mermaid
stateDiagram-v2
@@ -88,23 +88,25 @@ stateDiagram-v2
## Session reuse
Sub-agent sessions are expensive to start — each new spawn requires the agent to read the full codebase (~50K tokens). DevClaw preserves session IDs across task completions. When a DEV finishes task A and picks up task B on the same project, the plugin detects the existing session and returns `"sessionAction": "send"` instead of `"spawn"` — the orchestrator sends the new task to the running session instead of creating a new one.
Worker sessions are expensive to start — each new spawn requires the session to read the full codebase (~50K tokens). DevClaw maintains **separate sessions per model per role** (session-per-model design). When a DEV finishes task A and picks up task B on the same project with the same model, the plugin detects the existing session and sends the task directly — no new session needed.
The plugin handles session dispatch internally via OpenClaw CLI. The orchestrator agent never calls `sessions_spawn` or `sessions_send` — it just calls `task_pickup` and the plugin does the rest.
```mermaid
sequenceDiagram
participant O as Orchestrator
participant DC as DevClaw Plugin
participant GL as GitLab
participant S as Sub-agent Session
participant S as Worker Session
O->>DC: task_pickup({ issueId: 42, role: "dev" })
DC->>GL: Fetch issue, verify label
DC->>DC: Select model (haiku/sonnet/opus)
DC->>DC: Check existing session
DC->>DC: Check existing session for selected model
DC->>GL: Transition label (To Do → Doing)
DC->>S: Dispatch task via CLI (create or reuse session)
DC->>DC: Update projects.json, write audit log
DC-->>O: { sessionAction: "send", sessionId: "...", model: "sonnet" }
O->>S: sessions_send (task description)
DC-->>O: { success: true, announcement: "🔧 DEV (sonnet) picking up #42" }
```
## Model selection
@@ -134,22 +136,32 @@ All project state lives in a single `memory/projects.json` file in the orchestra
"baseBranch": "development",
"dev": {
"active": false,
"sessionId": "agent:orchestrator:subagent:a9e4d078-...",
"issueId": null,
"model": "haiku"
"model": "haiku",
"sessions": {
"haiku": "agent:orchestrator:subagent:a9e4d078-...",
"sonnet": "agent:orchestrator:subagent:b3f5c912-...",
"opus": null
}
},
"qa": {
"active": false,
"sessionId": "agent:orchestrator:subagent:18707821-...",
"issueId": null,
"model": "grok"
"model": "grok",
"sessions": {
"grok": "agent:orchestrator:subagent:18707821-..."
}
}
}
}
}
```
Key design decision: when a worker completes a task, `sessionId` and `model` are **preserved** (only `active` and `issueId` are cleared). This enables session reuse on the next pickup.
Key design decisions:
- **Session-per-model** — each model gets its own worker session, accumulating context independently. Model selection maps directly to a session key.
- **Sessions preserved on completion** — when a worker completes a task, `sessions` map is **preserved** (only `active` and `issueId` are cleared). This enables session reuse on the next pickup.
- **Plugin-controlled dispatch** — the plugin creates and dispatches to sessions via OpenClaw CLI (`sessions.patch` + `openclaw agent`). The orchestrator agent never calls `sessions_spawn` or `sessions_send`.
- **Sessions persist indefinitely** — no auto-cleanup. `session_health` handles manual cleanup when needed.
All writes go through atomic temp-file-then-rename to prevent corruption.
@@ -170,11 +182,13 @@ Pick up a task from the GitLab queue for a DEV or QA worker.
2. Validates no active worker for this role
3. Fetches issue from GitLab, verifies correct label state
4. Selects model based on task complexity
5. Detects session reuse opportunity
6. Transitions GitLab label (e.g. `To Do``Doing`)
7. Updates `projects.json` state
8. Writes audit log entry
9. Returns structured instructions for the orchestrator
5. Looks up existing session for selected model (session-per-model)
6. Creates session via Gateway RPC if new (`sessions.patch`)
7. Dispatches task to worker session via CLI (`openclaw agent`)
8. Transitions GitLab label (e.g. `To Do``Doing`)
9. Updates `projects.json` state (active, issueId, model, session key)
10. Writes audit log entry
11. Returns announcement text for the orchestrator to post
### `task_complete`
@@ -205,10 +219,13 @@ Detects and optionally fixes state inconsistencies.
**Parameters:**
- `autoFix` (boolean, optional) — Auto-fix zombies and stale state
- `activeSessions` (string[], optional) — Live session IDs from `sessions_list`
**What it does:**
- Queries live sessions via Gateway RPC (`sessions.list`)
- Cross-references with `projects.json` worker state
**Checks:**
- Active worker with no session ID (critical)
- Active worker with no session key (critical)
- Active worker whose session is dead — zombie (critical)
- Worker active for >2 hours (warning)
- Inactive worker with lingering issue ID (warning)