Add adapter config docs, approval context env vars, and paperclip-create-agent skill

Export agentConfigurationDoc from all adapters for LLM reflection. Inject
PAPERCLIP_APPROVAL_ID, PAPERCLIP_APPROVAL_STATUS, and PAPERCLIP_LINKED_ISSUE_IDS
into local adapter environments. Update SKILL.md with approval handling procedure,
issue-approval linking, and config revision documentation. Add new
paperclip-create-agent skill for CEO-driven agent hiring workflows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-19 13:02:53 -06:00
parent c09037ffad
commit 0d73e1b407
9 changed files with 387 additions and 19 deletions

View File

@@ -65,6 +65,7 @@ export interface ServerAdapterModule {
execute(ctx: AdapterExecutionContext): Promise<AdapterExecutionResult>; execute(ctx: AdapterExecutionContext): Promise<AdapterExecutionResult>;
supportsLocalAgentJwt?: boolean; supportsLocalAgentJwt?: boolean;
models?: { id: string; label: string }[]; models?: { id: string; label: string }[];
agentConfigurationDoc?: string;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -6,3 +6,23 @@ export const models = [
{ id: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" }, { id: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
{ id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" }, { id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
]; ];
export const agentConfigurationDoc = `# claude_local agent configuration
Adapter: claude_local
Core fields:
- cwd (string, required): absolute working directory for the agent process
- model (string, optional): Claude model id
- promptTemplate (string, optional): run prompt template
- bootstrapPromptTemplate (string, optional): first-run prompt template
- maxTurnsPerRun (number, optional): max turns for one run
- dangerouslySkipPermissions (boolean, optional): pass --dangerously-skip-permissions to claude
- command (string, optional): defaults to "claude"
- extraArgs (string[], optional): additional CLI args
- env (object, optional): KEY=VALUE environment variables
Operational fields:
- timeoutSec (number, optional): run timeout in seconds
- graceSec (number, optional): SIGTERM grace period in seconds
`;

View File

@@ -75,12 +75,32 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
typeof context.wakeReason === "string" && context.wakeReason.trim().length > 0 typeof context.wakeReason === "string" && context.wakeReason.trim().length > 0
? context.wakeReason.trim() ? context.wakeReason.trim()
: null; : null;
const approvalId =
typeof context.approvalId === "string" && context.approvalId.trim().length > 0
? context.approvalId.trim()
: null;
const approvalStatus =
typeof context.approvalStatus === "string" && context.approvalStatus.trim().length > 0
? context.approvalStatus.trim()
: null;
const linkedIssueIds = Array.isArray(context.issueIds)
? context.issueIds.filter((value): value is string => typeof value === "string" && value.trim().length > 0)
: [];
if (wakeTaskId) { if (wakeTaskId) {
env.PAPERCLIP_TASK_ID = wakeTaskId; env.PAPERCLIP_TASK_ID = wakeTaskId;
} }
if (wakeReason) { if (wakeReason) {
env.PAPERCLIP_WAKE_REASON = wakeReason; env.PAPERCLIP_WAKE_REASON = wakeReason;
} }
if (approvalId) {
env.PAPERCLIP_APPROVAL_ID = approvalId;
}
if (approvalStatus) {
env.PAPERCLIP_APPROVAL_STATUS = approvalStatus;
}
if (linkedIssueIds.length > 0) {
env.PAPERCLIP_LINKED_ISSUE_IDS = linkedIssueIds.join(",");
}
for (const [k, v] of Object.entries(envConfig)) { for (const [k, v] of Object.entries(envConfig)) {
if (typeof v === "string") env[k] = v; if (typeof v === "string") env[k] = v;
} }

View File

@@ -6,3 +6,23 @@ export const models = [
{ id: "o3", label: "o3" }, { id: "o3", label: "o3" },
{ id: "codex-mini-latest", label: "Codex Mini" }, { id: "codex-mini-latest", label: "Codex Mini" },
]; ];
export const agentConfigurationDoc = `# codex_local agent configuration
Adapter: codex_local
Core fields:
- cwd (string, required): absolute working directory for the agent process
- model (string, optional): Codex model id
- promptTemplate (string, optional): run prompt template
- bootstrapPromptTemplate (string, optional): first-run prompt template
- search (boolean, optional): run codex with --search
- dangerouslyBypassApprovalsAndSandbox (boolean, optional): run with bypass flag
- command (string, optional): defaults to "codex"
- extraArgs (string[], optional): additional CLI args
- env (object, optional): KEY=VALUE environment variables
Operational fields:
- timeoutSec (number, optional): run timeout in seconds
- graceSec (number, optional): SIGTERM grace period in seconds
`;

View File

@@ -43,12 +43,32 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
typeof context.wakeReason === "string" && context.wakeReason.trim().length > 0 typeof context.wakeReason === "string" && context.wakeReason.trim().length > 0
? context.wakeReason.trim() ? context.wakeReason.trim()
: null; : null;
const approvalId =
typeof context.approvalId === "string" && context.approvalId.trim().length > 0
? context.approvalId.trim()
: null;
const approvalStatus =
typeof context.approvalStatus === "string" && context.approvalStatus.trim().length > 0
? context.approvalStatus.trim()
: null;
const linkedIssueIds = Array.isArray(context.issueIds)
? context.issueIds.filter((value): value is string => typeof value === "string" && value.trim().length > 0)
: [];
if (wakeTaskId) { if (wakeTaskId) {
env.PAPERCLIP_TASK_ID = wakeTaskId; env.PAPERCLIP_TASK_ID = wakeTaskId;
} }
if (wakeReason) { if (wakeReason) {
env.PAPERCLIP_WAKE_REASON = wakeReason; env.PAPERCLIP_WAKE_REASON = wakeReason;
} }
if (approvalId) {
env.PAPERCLIP_APPROVAL_ID = approvalId;
}
if (approvalStatus) {
env.PAPERCLIP_APPROVAL_STATUS = approvalStatus;
}
if (linkedIssueIds.length > 0) {
env.PAPERCLIP_LINKED_ISSUE_IDS = linkedIssueIds.join(",");
}
for (const [k, v] of Object.entries(envConfig)) { for (const [k, v] of Object.entries(envConfig)) {
if (typeof v === "string") env[k] = v; if (typeof v === "string") env[k] = v;
} }

View File

@@ -0,0 +1,129 @@
---
name: paperclip-create-agent
description: >
Create new agents in Paperclip with governance-aware hiring. Use when you need
to inspect adapter configuration options, compare existing agent configs,
draft a new agent prompt/config, and submit a hire request.
---
# Paperclip Create Agent Skill
Use this skill when you are asked to hire/create an agent.
## Preconditions
You need either:
- board access, or
- agent permission `can_create_agents=true` in your company
If you do not have this permission, escalate to your CEO or board.
## Workflow
1. Confirm identity and company context.
```sh
curl -sS "$PAPERCLIP_API_URL/api/agents/me" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
```
2. Discover available adapter configuration docs for this Paperclip instance.
```sh
curl -sS "$PAPERCLIP_API_URL/llms/agent-configuration.txt" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
```
3. Read adapter-specific docs (example: `claude_local`).
```sh
curl -sS "$PAPERCLIP_API_URL/llms/agent-configuration/claude_local.txt" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
```
4. Compare existing agent configurations in your company.
```sh
curl -sS "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/agent-configurations" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
```
5. Draft the new hire config:
- role/title/name
- reporting line (`reportsTo`)
- adapter type
- adapter and runtime config aligned to this environment
- capabilities
- initial prompt in adapter config (`bootstrapPromptTemplate`/`promptTemplate` where applicable)
- source issue linkage (`sourceIssueId` or `sourceIssueIds`) when this hire came from an issue
6. Submit hire request.
```sh
curl -sS -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/agent-hires" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CTO",
"role": "cto",
"title": "Chief Technology Officer",
"reportsTo": "<ceo-agent-id>",
"capabilities": "Owns technical roadmap, architecture, staffing, execution",
"adapterType": "codex_local",
"adapterConfig": {"cwd": "/abs/path/to/repo", "model": "o4-mini"},
"runtimeConfig": {"heartbeat": {"enabled": true, "intervalSec": 300, "wakeOnDemand": true}},
"sourceIssueId": "<issue-id>"
}'
```
7. Handle governance state:
- if response has `approval`, hire is `pending_approval`
- monitor and discuss on approval thread
- when the board approves, you will be woken with `PAPERCLIP_APPROVAL_ID`; read linked issues and close/comment follow-up
```sh
curl -sS "$PAPERCLIP_API_URL/api/approvals/<approval-id>" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
curl -sS -X POST "$PAPERCLIP_API_URL/api/approvals/<approval-id>/comments" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"## CTO hire request submitted\n\n- Approval: [<approval-id>](/approvals/<approval-id>)\n- Pending agent: [<agent-id>](/agents/<agent-id>)\n- Source issue: [<issue-id>](/issues/<issue-id>)\n\nUpdated prompt and adapter config per board feedback."}'
```
If the approval already exists and needs manual linking to the issue:
```sh
curl -sS -X POST "$PAPERCLIP_API_URL/api/issues/<issue-id>/approvals" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"approvalId":"<approval-id>"}'
```
After approval is granted, run this follow-up loop:
```sh
curl -sS "$PAPERCLIP_API_URL/api/approvals/$PAPERCLIP_APPROVAL_ID" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
curl -sS "$PAPERCLIP_API_URL/api/approvals/$PAPERCLIP_APPROVAL_ID/issues" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
```
For each linked issue, either:
- close it if approval resolved the request, or
- comment in markdown with links to the approval and next actions.
## Quality Bar
Before sending a hire request:
- Reuse proven config patterns from related agents where possible.
- Avoid secrets in plain text unless required by adapter behavior.
- Ensure reporting line is correct and in-company.
- Ensure prompt is role-specific and operationally scoped.
- If board requests revision, update payload and resubmit through approval flow.
For endpoint payload shapes and full examples, read:
`skills/paperclip-create-agent/references/api-reference.md`

View File

@@ -0,0 +1,93 @@
# Paperclip Create Agent API Reference
## Core Endpoints
- `GET /llms/agent-configuration.txt`
- `GET /llms/agent-configuration/:adapterType.txt`
- `GET /api/companies/:companyId/agent-configurations`
- `GET /api/agents/:agentId/configuration`
- `POST /api/companies/:companyId/agent-hires`
- `GET /api/agents/:agentId/config-revisions`
- `POST /api/agents/:agentId/config-revisions/:revisionId/rollback`
- `POST /api/issues/:issueId/approvals`
- `GET /api/approvals/:approvalId/issues`
Approval collaboration:
- `GET /api/approvals/:approvalId`
- `POST /api/approvals/:approvalId/request-revision` (board)
- `POST /api/approvals/:approvalId/resubmit`
- `GET /api/approvals/:approvalId/comments`
- `POST /api/approvals/:approvalId/comments`
- `GET /api/approvals/:approvalId/issues`
## `POST /api/companies/:companyId/agent-hires`
Request body matches agent create shape:
```json
{
"name": "CTO",
"role": "cto",
"title": "Chief Technology Officer",
"reportsTo": "uuid-or-null",
"capabilities": "Owns architecture and engineering execution",
"adapterType": "claude_local",
"adapterConfig": {
"cwd": "/absolute/path",
"model": "claude-sonnet-4-5-20250929",
"promptTemplate": "You are CTO..."
},
"runtimeConfig": {
"heartbeat": {
"enabled": true,
"intervalSec": 300,
"wakeOnDemand": true
}
},
"budgetMonthlyCents": 0,
"sourceIssueId": "uuid-or-null",
"sourceIssueIds": ["uuid-1", "uuid-2"]
}
```
Response:
```json
{
"agent": {
"id": "uuid",
"status": "pending_approval"
},
"approval": {
"id": "uuid",
"type": "hire_agent",
"status": "pending"
}
}
```
If company setting disables required approval, `approval` is `null` and the agent is created as `idle`.
## Approval Lifecycle
Statuses:
- `pending`
- `revision_requested`
- `approved`
- `rejected`
- `cancelled`
For hire approvals:
- approved: linked agent transitions `pending_approval -> idle`
- rejected: linked agent is terminated
## Safety Notes
- Config read APIs redact obvious secrets.
- `pending_approval` agents cannot run heartbeats, receive assignments, or create keys.
- All actions are logged in activity for auditability.
- Use markdown in issue/approval comments and include links to approval, agent, and source issue.
- After approval resolution, requester may be woken with `PAPERCLIP_APPROVAL_ID` and should reconcile linked issues.

View File

@@ -14,7 +14,7 @@ You run in **heartbeats** — short execution windows triggered by Paperclip. Ea
## Authentication ## Authentication
Env vars auto-injected: `PAPERCLIP_AGENT_ID`, `PAPERCLIP_COMPANY_ID`, `PAPERCLIP_API_URL`, `PAPERCLIP_RUN_ID`. Optional wake-context vars may also be present: `PAPERCLIP_TASK_ID` (issue/task that triggered this wake) and `PAPERCLIP_WAKE_REASON` (why this run was triggered). For local adapters, `PAPERCLIP_API_KEY` is auto-injected as a short-lived run JWT. For non-local adapters, your operator should set `PAPERCLIP_API_KEY` in adapter config. All requests use `Authorization: Bearer $PAPERCLIP_API_KEY`. All endpoints under `/api`, all JSON. Never hard-code the API URL. Env vars auto-injected: `PAPERCLIP_AGENT_ID`, `PAPERCLIP_COMPANY_ID`, `PAPERCLIP_API_URL`, `PAPERCLIP_RUN_ID`. Optional wake-context vars may also be present: `PAPERCLIP_TASK_ID` (issue/task that triggered this wake), `PAPERCLIP_WAKE_REASON` (why this run was triggered), `PAPERCLIP_APPROVAL_ID`, `PAPERCLIP_APPROVAL_STATUS`, and `PAPERCLIP_LINKED_ISSUE_IDS` (comma-separated). For local adapters, `PAPERCLIP_API_KEY` is auto-injected as a short-lived run JWT. For non-local adapters, your operator should set `PAPERCLIP_API_KEY` in adapter config. All requests use `Authorization: Bearer $PAPERCLIP_API_KEY`. All endpoints under `/api`, all JSON. Never hard-code the API URL.
**Run audit trail:** You MUST include `-H 'X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID'` on ALL API requests that modify issues (checkout, update, comment, create subtask, release). This links your actions to the current heartbeat run for traceability. **Run audit trail:** You MUST include `-H 'X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID'` on ALL API requests that modify issues (checkout, update, comment, create subtask, release). This links your actions to the current heartbeat run for traceability.
@@ -24,12 +24,20 @@ Follow these steps every time you wake up:
**Step 1 — Identity.** If not already in context, `GET /api/agents/me` to get your id, companyId, role, chainOfCommand, and budget. **Step 1 — Identity.** If not already in context, `GET /api/agents/me` to get your id, companyId, role, chainOfCommand, and budget.
**Step 2 — Get assignments.** `GET /api/companies/{companyId}/issues?assigneeAgentId={your-agent-id}&status=todo,in_progress,blocked`. Results sorted by priority. This is your inbox. **Step 2 — Approval follow-up (when triggered).** If `PAPERCLIP_APPROVAL_ID` is set (or wake reason indicates approval resolution), review the approval first:
- `GET /api/approvals/{approvalId}`
- `GET /api/approvals/{approvalId}/issues`
- For each linked issue:
- close it (`PATCH` status to `done`) if the approval fully resolves requested work, or
- add a markdown comment explaining why it remains open and what happens next.
Always include links to the approval and issue in that comment.
**Step 3 — Pick work.** Work on `in_progress` first, then `todo`. Skip `blocked` unless you can unblock it. **If nothing is assigned, exit the heartbeat. Do not look for unassigned work. Do not self-assign.** **Step 3 — Get assignments.** `GET /api/companies/{companyId}/issues?assigneeAgentId={your-agent-id}&status=todo,in_progress,blocked`. Results sorted by priority. This is your inbox.
**Step 4 — Pick work.** Work on `in_progress` first, then `todo`. Skip `blocked` unless you can unblock it. **If nothing is assigned, exit the heartbeat. Do not look for unassigned work. Do not self-assign.**
If `PAPERCLIP_TASK_ID` is set and that task is assigned to you, prioritize it first for this heartbeat. If `PAPERCLIP_TASK_ID` is set and that task is assigned to you, prioritize it first for this heartbeat.
**Step 4 — Checkout.** You MUST checkout before doing any work. Include the run ID header: **Step 5 — Checkout.** You MUST checkout before doing any work. Include the run ID header:
``` ```
POST /api/issues/{issueId}/checkout POST /api/issues/{issueId}/checkout
Headers: Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID Headers: Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
@@ -37,11 +45,11 @@ Headers: Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLI
``` ```
If already checked out by you, returns normally. If owned by another agent: `409 Conflict` — stop, pick a different task. **Never retry a 409.** If already checked out by you, returns normally. If owned by another agent: `409 Conflict` — stop, pick a different task. **Never retry a 409.**
**Step 5 — Understand context.** `GET /api/issues/{issueId}` (includes `ancestors` array — parent chain to root). `GET /api/issues/{issueId}/comments`. Read ancestors to understand *why* this task exists. **Step 6 — Understand context.** `GET /api/issues/{issueId}` (includes `ancestors` array — parent chain to root). `GET /api/issues/{issueId}/comments`. Read ancestors to understand *why* this task exists.
**Step 6 — Do the work.** Use your tools and capabilities. **Step 7 — Do the work.** Use your tools and capabilities.
**Step 7 — Update status and communicate.** Always include the run ID header: **Step 8 — Update status and communicate.** Always include the run ID header:
``` ```
PATCH /api/issues/{issueId} PATCH /api/issues/{issueId}
Headers: X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID Headers: X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
@@ -49,7 +57,7 @@ Headers: X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
``` ```
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`.
**Step 8 — Delegate if needed.** Create subtasks with `POST /api/companies/{companyId}/issues`. Always set `parentId` and `goalId`. Set `billingCode` for cross-team work. **Step 9 — Delegate if needed.** Create subtasks with `POST /api/companies/{companyId}/issues`. Always set `parentId` and `goalId`. Set `billingCode` for cross-team work.
## Critical Rules ## Critical Rules
@@ -63,6 +71,27 @@ Status values: `backlog`, `todo`, `in_progress`, `in_review`, `done`, `blocked`,
- **@-mentions** (`@AgentName` in comments) trigger heartbeats — use sparingly, they cost budget. - **@-mentions** (`@AgentName` in comments) trigger heartbeats — use sparingly, they cost budget.
- **Budget**: auto-paused at 100%. Above 80%, focus on critical tasks only. - **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. - **Escalate** via `chainOfCommand` when stuck. Reassign to manager or create a task for them.
- **Hiring**: use `paperclip-create-agent` skill for new agent creation workflows.
## Comment Style (Required)
When posting issue comments, use concise markdown with:
- a short status line
- bullets for what changed / what is blocked
- links to related entities when available (`[Issue XYZ](/issues/<id>)`, `[Approval](/approvals/<id>)`, `[Agent](/agents/<id>)`)
Example:
```md
## Update
Submitted CTO hire request and linked it for board review.
- Approval: [ca6ba09d](/approvals/ca6ba09d-b558-4a53-a552-e7ef87e54a1b)
- Pending agent: [CTO draft](/agents/66b3c071-6cb8-4424-b833-9d9b6318de0b)
- Source issue: [PC-142](/issues/244c0c2c-8416-43b6-84c9-ec183c074cc1)
```
## Key Endpoints (Quick Reference) ## Key Endpoints (Quick Reference)

View File

@@ -165,6 +165,16 @@ GET /api/companies/company-1/dashboard
Comments are your primary communication channel. Use them for status updates, questions, findings, handoffs, and review requests. Comments are your primary communication channel. Use them for status updates, questions, findings, handoffs, and review requests.
Use markdown formatting and include links to related entities when they exist:
```md
## Update
- Approval: [APPROVAL_ID](/approvals/<approval-id>)
- Pending agent: [AGENT_NAME](/agents/<agent-id>)
- Source issue: [ISSUE_ID](/issues/<issue-id>)
```
**@-mentions:** Mention another agent by name using `@AgentName` to automatically wake them: **@-mentions:** Mention another agent by name using `@AgentName` to automatically wake them:
``` ```
@@ -226,24 +236,22 @@ Some actions require board approval. You cannot bypass these gates.
### Requesting a hire (management only) ### Requesting a hire (management only)
``` ```
POST /api/companies/{companyId}/approvals POST /api/companies/{companyId}/agent-hires
{ {
"type": "hire_agent", "name": "Marketing Analyst",
"requestedByAgentId": "{your-agent-id}", "role": "researcher",
"payload": { "reportsTo": "{manager-agent-id}",
"name": "Marketing Analyst", "capabilities": "Market research, competitor analysis",
"role": "researcher", "budgetMonthlyCents": 5000
"reportsTo": "{manager-agent-id}",
"capabilities": "Market research, competitor analysis",
"budgetMonthlyCents": 5000
}
} }
``` ```
The board approves or rejects. You cannot create agents directly. If company policy requires approval, the new agent is created as `pending_approval` and a linked `hire_agent` approval is created automatically.
**Do NOT** request hires unless you are a manager or CEO. IC agents should ask their manager. **Do NOT** request hires unless you are a manager or CEO. IC agents should ask their manager.
Use `paperclip-create-agent` for the full hiring workflow (reflection + config comparison + prompt drafting).
### CEO strategy approval ### CEO strategy approval
If you are the CEO, your first strategic plan must be approved before you can move tasks to `in_progress`: If you are the CEO, your first strategic plan must be approved before you can move tasks to `in_progress`:
@@ -259,6 +267,22 @@ POST /api/companies/{companyId}/approvals
GET /api/companies/{companyId}/approvals?status=pending GET /api/companies/{companyId}/approvals?status=pending
``` ```
### Approval follow-up (requesting agent)
When board resolves your approval, you may be woken with:
- `PAPERCLIP_APPROVAL_ID`
- `PAPERCLIP_APPROVAL_STATUS`
- `PAPERCLIP_LINKED_ISSUE_IDS`
Use:
```
GET /api/approvals/{approvalId}
GET /api/approvals/{approvalId}/issues
```
Then close or comment on linked issues to complete the workflow.
--- ---
## Issue Lifecycle ## Issue Lifecycle
@@ -304,6 +328,8 @@ Terminal states: `done`, `cancelled`
| GET | `/api/agents/:agentId` | Agent details + chain of command | | GET | `/api/agents/:agentId` | Agent details + chain of command |
| GET | `/api/companies/:companyId/agents` | List all agents in company | | GET | `/api/companies/:companyId/agents` | List all agents in company |
| GET | `/api/companies/:companyId/org` | Org chart tree | | GET | `/api/companies/:companyId/org` | Org chart tree |
| GET | `/api/agents/:agentId/config-revisions` | List config revisions |
| POST | `/api/agents/:agentId/config-revisions/:revisionId/rollback` | Roll back config |
### Issues (Tasks) ### Issues (Tasks)
@@ -317,6 +343,9 @@ Terminal states: `done`, `cancelled`
| POST | `/api/issues/:issueId/release` | Release task ownership | | POST | `/api/issues/:issueId/release` | Release task ownership |
| GET | `/api/issues/:issueId/comments` | List comments | | GET | `/api/issues/:issueId/comments` | List comments |
| POST | `/api/issues/:issueId/comments` | Add comment (@-mentions trigger wakeups) | | POST | `/api/issues/:issueId/comments` | Add comment (@-mentions trigger wakeups) |
| GET | `/api/issues/:issueId/approvals` | List approvals linked to issue |
| POST | `/api/issues/:issueId/approvals` | Link approval to issue |
| DELETE | `/api/issues/:issueId/approvals/:approvalId` | Unlink approval from issue |
### Companies, Projects, Goals ### Companies, Projects, Goals
@@ -339,6 +368,13 @@ Terminal states: `done`, `cancelled`
| ------ | -------------------------------------------- | ---------------------------------- | | ------ | -------------------------------------------- | ---------------------------------- |
| GET | `/api/companies/:companyId/approvals` | List approvals (`?status=pending`) | | GET | `/api/companies/:companyId/approvals` | List approvals (`?status=pending`) |
| POST | `/api/companies/:companyId/approvals` | Create approval request | | POST | `/api/companies/:companyId/approvals` | Create approval request |
| POST | `/api/companies/:companyId/agent-hires` | Create hire request/agent draft |
| GET | `/api/approvals/:approvalId` | Approval details |
| GET | `/api/approvals/:approvalId/issues` | Issues linked to approval |
| GET | `/api/approvals/:approvalId/comments` | Approval comments |
| POST | `/api/approvals/:approvalId/comments` | Add approval comment |
| POST | `/api/approvals/:approvalId/request-revision`| Board asks for revision |
| POST | `/api/approvals/:approvalId/resubmit` | Resubmit revised approval |
| GET | `/api/companies/:companyId/costs/summary` | Company cost summary | | GET | `/api/companies/:companyId/costs/summary` | Company cost summary |
| GET | `/api/companies/:companyId/costs/by-agent` | Costs by agent | | GET | `/api/companies/:companyId/costs/by-agent` | Costs by agent |
| GET | `/api/companies/:companyId/costs/by-project` | Costs by project | | GET | `/api/companies/:companyId/costs/by-project` | Costs by project |