forked from farhoodlabs/paperclip
Add blocker/dependency documentation to Paperclip skill
Document blockedByIssueIds field, issue_blockers_resolved and issue_children_completed wake reasons, and blockedBy/blocks response arrays in both SKILL.md and api-reference.md so agents know how to set and use first-class issue dependencies. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -88,10 +88,48 @@ Headers: X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
|
||||
{ "status": "blocked", "comment": "What is blocked, why, and who needs to unblock it." }
|
||||
```
|
||||
|
||||
Status values: `backlog`, `todo`, `in_progress`, `in_review`, `done`, `blocked`, `cancelled`. Priority values: `critical`, `high`, `medium`, `low`. Other updatable fields: `title`, `description`, `priority`, `assigneeAgentId`, `projectId`, `goalId`, `parentId`, `billingCode`.
|
||||
Status values: `backlog`, `todo`, `in_progress`, `in_review`, `done`, `blocked`, `cancelled`. Priority values: `critical`, `high`, `medium`, `low`. Other updatable fields: `title`, `description`, `priority`, `assigneeAgentId`, `projectId`, `goalId`, `parentId`, `billingCode`, `blockedByIssueIds`.
|
||||
|
||||
**Step 9 — Delegate if needed.** Create subtasks with `POST /api/companies/{companyId}/issues`. Always set `parentId` and `goalId`. When a follow-up issue needs to stay on the same code change but is not a true child task, set `inheritExecutionWorkspaceFromIssueId` to the source issue. Set `billingCode` for cross-team work.
|
||||
|
||||
## Issue Dependencies (Blockers)
|
||||
|
||||
Paperclip supports first-class blocker relationships between issues. Use these to express "issue A is blocked by issue B" so that dependent work automatically resumes when blockers are resolved.
|
||||
|
||||
### Setting blockers
|
||||
|
||||
Pass `blockedByIssueIds` (an array of issue IDs) when creating or updating an issue:
|
||||
|
||||
```json
|
||||
// At creation time
|
||||
POST /api/companies/{companyId}/issues
|
||||
{ "title": "Deploy to prod", "blockedByIssueIds": ["issue-id-1", "issue-id-2"], "status": "blocked", ... }
|
||||
|
||||
// After the fact
|
||||
PATCH /api/issues/{issueId}
|
||||
{ "blockedByIssueIds": ["issue-id-1", "issue-id-2"] }
|
||||
```
|
||||
|
||||
The `blockedByIssueIds` array **replaces** the existing blocker set on each update. To add a blocker, include the full list. To remove all blockers, send `[]`.
|
||||
|
||||
Constraints: issues cannot block themselves, and circular blocker chains are rejected.
|
||||
|
||||
### Reading blockers
|
||||
|
||||
`GET /api/issues/{issueId}` returns two relation arrays:
|
||||
|
||||
- `blockedBy` — issues that block this one (with `id`, `identifier`, `title`, `status`, `priority`, assignee info)
|
||||
- `blocks` — issues that this one blocks
|
||||
|
||||
### Automatic wake-on-dependency-resolved
|
||||
|
||||
Paperclip fires automatic wakes in two scenarios:
|
||||
|
||||
1. **All blockers done** (`PAPERCLIP_WAKE_REASON=issue_blockers_resolved`): When every issue in the `blockedBy` set reaches `done`, the dependent issue's assignee is woken to resume work.
|
||||
2. **All children done** (`PAPERCLIP_WAKE_REASON=issue_children_completed`): When every direct child issue of a parent reaches a terminal state (`done` or `cancelled`), the parent issue's assignee is woken to finalize or close out.
|
||||
|
||||
When you receive one of these wake reasons, check the issue state and continue the work or mark it done.
|
||||
|
||||
## Project Setup Workflow (CEO/Manager Common Path)
|
||||
|
||||
When asked to set up a new project with workspace config (local folder and/or GitHub repo), use:
|
||||
@@ -166,6 +204,7 @@ If you are asked to create or manage routines you MUST read:
|
||||
- **Preserve workspace continuity for follow-ups.** Child issues inherit execution workspace linkage server-side from `parentId`. For non-child follow-ups tied to the same checkout/worktree, send `inheritExecutionWorkspaceFromIssueId` explicitly instead of relying on free-text references or memory.
|
||||
- **Never cancel cross-team tasks.** Reassign to your manager with a comment.
|
||||
- **Always update blocked issues explicitly.** If blocked, PATCH status to `blocked` with a blocker comment before exiting, then escalate. On subsequent heartbeats, do NOT repeat the same blocked comment — see blocked-task dedup in Step 4.
|
||||
- **Use first-class blockers** when a task depends on other tasks. Set `blockedByIssueIds` on the dependent issue so Paperclip automatically wakes the assignee when all blockers are done. Prefer this over ad-hoc "blocked by X" comments.
|
||||
- **@-mentions** (`@AgentName` in comments) trigger heartbeats — use sparingly, they cost budget.
|
||||
- **Budget**: auto-paused at 100%. Above 80%, focus on critical tasks only.
|
||||
- **Escalate** via `chainOfCommand` when stuck. Reassign to manager or create a task for them.
|
||||
|
||||
@@ -109,6 +109,8 @@ POST /api/companies/company-1/exports
|
||||
|
||||
Includes the issue's `project` and `goal` (with descriptions), plus each ancestor's resolved `project` and `goal`. This gives agents full context about where the task sits in the project/goal hierarchy.
|
||||
|
||||
The response also includes `blockedBy` and `blocks` arrays showing first-class dependency relationships:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "issue-99",
|
||||
@@ -116,6 +118,10 @@ Includes the issue's `project` and `goal` (with descriptions), plus each ancesto
|
||||
"parentId": "issue-50",
|
||||
"projectId": "proj-1",
|
||||
"goalId": null,
|
||||
"blockedBy": [
|
||||
{ "id": "issue-80", "identifier": "PAP-80", "title": "Design auth schema", "status": "in_progress", "priority": "high", "assigneeAgentId": "agent-55", "assigneeUserId": null }
|
||||
],
|
||||
"blocks": [],
|
||||
"project": {
|
||||
"id": "proj-1",
|
||||
"name": "Auth System",
|
||||
@@ -290,7 +296,8 @@ POST /api/companies/company-1/issues
|
||||
{ "title": "Implement caching layer", "assigneeAgentId": "agent-42", "parentId": "issue-30", "status": "todo", "priority": "high", "goalId": "goal-1" }
|
||||
|
||||
POST /api/companies/company-1/issues
|
||||
{ "title": "Write load test suite", "assigneeAgentId": "agent-55", "parentId": "issue-30", "status": "todo", "priority": "medium", "goalId": "goal-1" }
|
||||
{ "title": "Write load test suite", "assigneeAgentId": "agent-55", "parentId": "issue-30", "status": "blocked", "priority": "medium", "goalId": "goal-1", "blockedByIssueIds": ["<caching-layer-issue-id>"] }
|
||||
# ^ Load tests depend on caching layer being done first. Paperclip will auto-wake agent-55 when the blocker resolves.
|
||||
|
||||
PATCH /api/issues/issue-30
|
||||
{ "status": "done", "comment": "Broke down into subtasks for caching layer and load testing." }
|
||||
@@ -617,8 +624,8 @@ Terminal states: `done`, `cancelled`
|
||||
| GET | `/api/companies/:companyId/issues` | List issues, sorted by priority. Filters: `?status=`, `?assigneeAgentId=`, `?assigneeUserId=`, `?projectId=`, `?labelId=`, `?q=` (full-text search across title, identifier, description, comments) |
|
||||
| GET | `/api/issues/:issueId` | Issue details + ancestors |
|
||||
| GET | `/api/issues/:issueId/heartbeat-context` | Compact context for heartbeat: issue state, ancestor summaries, comment cursor |
|
||||
| POST | `/api/companies/:companyId/issues` | Create issue |
|
||||
| PATCH | `/api/issues/:issueId` | Update issue (optional `comment` field adds a comment in same call) |
|
||||
| POST | `/api/companies/:companyId/issues` | Create issue (supports `blockedByIssueIds: string[]` for dependencies) |
|
||||
| PATCH | `/api/issues/:issueId` | Update issue (optional `comment` field; `blockedByIssueIds` replaces blocker set) |
|
||||
| POST | `/api/issues/:issueId/checkout` | Atomic checkout (claim + start). Idempotent if you already own it. |
|
||||
| POST | `/api/issues/:issueId/release` | Release task ownership |
|
||||
| GET | `/api/issues/:issueId/comments` | List comments |
|
||||
@@ -719,3 +726,4 @@ Terminal states: `done`, `cancelled`
|
||||
| @-mention agents for no reason | Each mention triggers a budget-consuming heartbeat | Only mention agents who need to act |
|
||||
| Sit silently on blocked work | Nobody knows you're stuck; the task rots | Comment the blocker and escalate immediately |
|
||||
| Leave tasks in ambiguous states | Others can't tell if work is progressing | Always update status: `blocked`, `in_review`, or `done` |
|
||||
| Block on another task without `blockedByIssueIds` | No automatic wake when blocker resolves; manual follow-up needed | Set `blockedByIssueIds` so Paperclip auto-wakes the assignee when all blockers are done |
|
||||
|
||||
Reference in New Issue
Block a user