Skip to content
Open
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
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Each project is fully isolated — own queue, workers, sessions, and state. Work

- **[Scheduling engine](#automatic-scheduling)** — `work_heartbeat` continuously scans queues, dispatches workers, and drives DEV → review → DEV [feedback loops](#how-tasks-flow-between-roles)
- **[Project isolation](#execution-modes)** — parallel workers per project, parallel projects across the system
- **[Role instructions](#custom-instructions-per-project)** — per-project, per-role prompts injected at dispatch time
- **[Role instructions](#custom-instructions-per-project)** — per-project, per-role prompts injected via the bootstrap hook

### Process enforcement

Expand Down Expand Up @@ -364,28 +364,40 @@ Workers can also comment during work — QA leaves review feedback, DEV posts im

### Custom instructions per project

Each project gets instruction files that workers receive with every task they pick up:
Each project gets instruction files that worker sessions load via the `agent:bootstrap` hook:

```
devclaw/
├── workflow.yaml (workspace-level workflow overrides)
├── prompts/ (workspace defaults — fallback)
│ ├── developer.md
│ ├── reviewer.md
│ ├── tester.md
│ ├── deployer.md
│ └── architect.md
└── projects/
├── my-webapp/
│ ├── workflow.yaml (project-specific workflow overrides)
│ └── prompts/
│ ├── developer.md "Run npm test before committing. Deploy URL: staging.example.com"
│ └── tester.md "Check OAuth flow. Verify mobile responsiveness."
│ ├── reviewer.md "Code review rules and PR acceptance policy."
│ ├── tester.md "Check OAuth flow. Verify mobile responsiveness."
│ ├── deployer.md "Promotion steps, lane checks, proof-of-release requirements."
│ └── architect.md "Research alternatives and create implementation-ready tasks."
└── my-api/
└── prompts/
├── developer.md "Run cargo test. Follow REST conventions in CONTRIBUTING.md"
└── tester.md "Verify all endpoints return correct status codes."
├── reviewer.md "Review API changes and PR quality."
├── tester.md "Verify all endpoints return correct status codes."
├── deployer.md "Promote approved builds between lanes and record evidence."
└── architect.md "Research architecture tradeoffs before implementation."
```

Deployment steps, test commands, coding standards, acceptance criteria — all injected at dispatch time, per project, per role.
Deployment steps, test commands, coding standards, acceptance criteria, promotion steps, and proof requirements are injected into worker sessions from these role prompt files.

The Deployer uses `deployer.md` as its dedicated prompt surface.

Release policy, lane semantics, and proof requirements still belong in workflow/config and runbooks, not only in prompts.

---

Expand Down
2 changes: 1 addition & 1 deletion defaults/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ If the test phase is enabled in workflow.yaml:

### Prompt Instructions

Workers receive role-specific instructions appended to their task message. These are loaded from `devclaw/projects/<project-name>/prompts/<role>.md` in the workspace, falling back to `devclaw/prompts/<role>.md` if no project-specific file exists. `project_register` scaffolds these files automatically — edit them to customize worker behavior per project.
Workers receive role-specific instructions via the bootstrap hook, not by appending them to the task message. These are loaded from `devclaw/projects/<project-name>/prompts/<role>.md` in the workspace, falling back to `devclaw/prompts/<role>.md` if no project-specific file exists. `project_register` scaffolds these files automatically — edit them to customize worker behavior per project.

### Heartbeats

Expand Down
86 changes: 86 additions & 0 deletions defaults/devclaw/prompts/deployer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# DEPLOYER Worker Instructions

You are the Deployer. Your job is to move an exact approved candidate from one release lane to another, verify the result, and record proof of release.

## Context You Receive

When you start work, you're given:

- **Issue:** number, title, body, URL, labels, state
- **Comments:** full discussion thread on the issue
- **Project:** repo path, base branch, project name, projectSlug
- **Release context:** source lane, target lane, candidate identity, required evidence, and any project-specific runbook steps

Read the issue body and comments carefully. Release work is evidence-sensitive. Do not guess at lane meaning, candidate identity, or acceptance rules.

## Your Job

1. **Understand the requested release step**
- Identify whether you are promoting, validating, accepting, or rolling back a candidate
- Confirm the source lane and target lane
- Confirm the exact candidate identity

2. **Verify preconditions**
- Make sure the requested lane transition is allowed
- Make sure the candidate is the intended one
- Make sure any required approvals, checks, or prerequisites are satisfied before proceeding

3. **Execute the release step**
- Follow the project runbook exactly
- Perform the required promotion, validation, acceptance, or rollback action
- Do not improvise a different release path because it seems close enough

4. **Verify the result**
- Confirm the destination lane now contains the intended candidate
- Confirm the destination identity matches the requested promotion
- Confirm any required checks or validation evidence are collected

5. **Record proof**
- Call `task_comment` with a release receipt that includes:
- source lane
- target lane
- candidate identity
- resulting destination identity or state
- verification evidence
- any relevant runbook notes

6. **Escalate cleanly if blocked**
- If required evidence is missing, lane rules are unclear, or the release cannot be proven, stop and report the exact blocker
- Do not mark a release complete when proof is incomplete

## Conventions

- Treat workflow/config and project runbooks as the source of truth for lane definitions, allowed paths, and release policy
- Treat prompt instructions as execution guidance, not as a replacement for structural release rules
- Never guess at candidate identity
- Never claim success without proof
- Be explicit about what changed, where it changed, and how you verified it
- If a candidate must be demoted or rolled back, record that explicitly
- **Do NOT use closing keywords in PR/MR descriptions** (no "Closes #X", "Fixes #X", "Resolves #X"). Use "As described in issue #X" or "Addresses issue #X" instead

## Filing Follow-Up Issues

If you discover unrelated release-process gaps, environment drift, or missing tooling, call `task_create`:

`task_create({ projectSlug: "<from task message>", title: "Release: ...", description: "..." })`

## Completing Your Task

When you are done, **call `work_finish` yourself** — do not just announce in text.

Use the completion result required by the active delivery state and workflow step you are executing.

Your summary should include:
- the lane transition attempted
- the candidate identity
- the resulting destination state
- whether proof was successfully recorded

If blocked, say exactly what proof, approval, environment access, or lane rule is missing.

The `projectSlug` is included in your task message.

## Tools You Should NOT Use

These are orchestrator-only tools. Do not call them:
- `task_start`, `tasks_status`, `health`, `project_register`
61 changes: 60 additions & 1 deletion defaults/devclaw/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ roles:
models:
junior: anthropic/claude-haiku-4-5
senior: anthropic/claude-sonnet-4-5
deployer:
models:
junior: anthropic/claude-haiku-4-5
senior: anthropic/claude-sonnet-4-5

workflow:
initial: planning
Expand Down Expand Up @@ -154,16 +158,71 @@ workflow:
label: Testing
color: "#9b59b6"
on:
PASS:
PASS: toPromote
FAIL:
target: toImprove
actions:
- reopenIssue
REFINE: refining
BLOCKED: refining
toPromote:
type: queue
role: deployer
label: To Promote
color: "#1d76db"
priority: 2
on:
PICKUP: promoting
SKIP: toAccept
PROMOTED: toAccept
FAIL: toImprove
DEMOTED: toImprove
BLOCKED: refining
promoting:
type: active
role: deployer
label: Promoting
color: "#6ea8fe"
on:
COMPLETE: toAccept
BLOCKED: refining
toAccept:
type: queue
role: deployer
label: To Accept
color: "#20c997"
priority: 2
on:
PICKUP: accepting
SKIP:
target: done
actions:
- closeIssue
ACCEPTED:
target: done
actions:
- closeIssue
FAIL:
target: toImprove
actions:
- reopenIssue
DEMOTED:
target: toImprove
actions:
- reopenIssue
REFINE: refining
BLOCKED: refining
accepting:
type: active
role: deployer
label: Accepting
color: "#8ce0c4"
on:
COMPLETE:
target: done
actions:
- closeIssue
BLOCKED: refining
done:
type: terminal
label: Done
Expand Down
156 changes: 156 additions & 0 deletions dev/design/deployer-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Deployer contract

This document describes the operator-facing contract for the DevClaw Deployer.

Use it as the manual for how release promotion and acceptance are meant to work.

## Core idea

Release is a distinct process from implementation, review, and testing.

- Development answers: was the change built correctly?
- Review answers: is the code acceptable?
- Testing answers: does it behave technically as expected?
- Release answers: should this exact candidate move from one lane to another, and can we prove that it did?

Release initiation should be **policy-controlled**, not automatic. Like PR handling, it may be human-initiated or agent-initiated depending on project policy.

## Flow

```mermaid
flowchart TD
A[Candidate ready in source lane] --> B{Promotion initiated by policy?}
B -- no --> A
B -- human --> C[Promote candidate from source lane to target lane]
B -- agent --> C
C --> D[Record candidate identity and promotion receipt]
D --> E[Run lane-specific verification]
E --> F{Acceptance decision}
F -- accept --> G[Record acceptance receipt]
G --> H[Candidate accepted in target lane]
F -- reject --> I[Invalidate candidate]
I --> J[Demotion or rollback path]
F -- refine --> K[Return to refinement or improvement]
F -- blocked --> L[Pause for human decision]
```

## Required concepts

### 1. Lanes are project-defined

Projects define release lanes or environments structurally in config.

Examples might be `dev`, `staging`, `production`, `local-current`, or something project-specific, but DevClaw core does not hardcode those names.

### 2. Promotion is source to target

Promotion means moving an exact candidate from one named lane to another named lane.

A promotion request identifies at minimum:
- the candidate
- the source lane
- the target lane
- the promotion policy or type

### Prompt surface

The Deployer uses a dedicated `deployer.md` prompt surface.

That prompt is where release-execution behavior belongs. It is not the source of truth for lanes, routing policy, allowed promotion paths, or proof requirements. Those remain structural workflow/config and runbook concerns.

### 3. Candidate identity is mandatory

A promoted candidate is tied to an exact identity, such as:
- commit SHA
- PR URL
- branch
- tag, version, build id, or artifact id when relevant

### 4. Proof of release is mandatory

The Deployer proves that it released the intended version.

Minimum proof includes:
- source candidate identity
- source lane
- target lane
- resulting target identity or target state
- verification evidence that the destination matches the intended candidate

Core rule:

> Prove source identity, prove destination identity, prove they match the intended promotion.

### 5. Acceptance is candidate-specific

Acceptance applies to a specific promoted candidate, not the issue in general.

Acceptance records:
- who accepted it
- where it was accepted
- what evidence was used
- what exact candidate was accepted

### 6. Acceptance defaults should be strong but configurable

Default acceptance criteria:
- candidate identity present
- source lane and target lane recorded
- proof of target state present
- required checks or evidence attached
- accepter identity recorded
- explicit outcome recorded

Projects can override:
- who can accept
- required evidence
- required checks
- allowed outcomes
- per-lane rules

### 7. Acceptance outcomes should be explicit

Standard outcomes:
- `accept`
- `reject`
- `refine`
- `blocked`

Rejecting acceptance invalidates the candidate, not just vaguely reopens the issue.

### 8. Rollback and demotion must be explicit

If a promoted candidate fails acceptance or later validation, the system explicitly marks it invalid and records the demotion or rollback path.

### 9. Preconditions and repeat behavior must be defined

The contract defines:
- what must already be true before promotion is allowed
- what should happen on repeated promotion attempts
- no-op
- retry
- replace candidate
- require explicit override

## Config versus prompts

This contract lives primarily in project config and workflow semantics, not only in prompts.

Prompts can explain how a project uses the Deployer, but they are not the sole source of truth for:
- lane names
- allowed promotion paths
- acceptance authority
- required evidence
- lane-specific rules

## Operator checklist

A usable Deployer project setup defines at least:
- release lanes or environments
- allowed promotion paths between lanes
- candidate identity requirements
- proof-of-release requirements
- acceptance authority and outcomes
- rollback or demotion behavior
- preconditions for promotion
- retry and override behavior for repeated promotions
Loading