From 0d73e1b40719a245fde7b972cadd6cc583ab2946 Mon Sep 17 00:00:00 2001 From: Forgotten Date: Thu, 19 Feb 2026 13:02:53 -0600 Subject: [PATCH] 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 --- packages/adapter-utils/src/types.ts | 1 + packages/adapters/claude-local/src/index.ts | 20 +++ .../claude-local/src/server/execute.ts | 20 +++ packages/adapters/codex-local/src/index.ts | 20 +++ .../codex-local/src/server/execute.ts | 20 +++ skills/paperclip-create-agent/SKILL.md | 129 ++++++++++++++++++ .../references/api-reference.md | 93 +++++++++++++ skills/paperclip/SKILL.md | 45 ++++-- skills/paperclip/references/api-reference.md | 58 ++++++-- 9 files changed, 387 insertions(+), 19 deletions(-) create mode 100644 skills/paperclip-create-agent/SKILL.md create mode 100644 skills/paperclip-create-agent/references/api-reference.md diff --git a/packages/adapter-utils/src/types.ts b/packages/adapter-utils/src/types.ts index e07f03a8..d8253edd 100644 --- a/packages/adapter-utils/src/types.ts +++ b/packages/adapter-utils/src/types.ts @@ -65,6 +65,7 @@ export interface ServerAdapterModule { execute(ctx: AdapterExecutionContext): Promise; supportsLocalAgentJwt?: boolean; models?: { id: string; label: string }[]; + agentConfigurationDoc?: string; } // --------------------------------------------------------------------------- diff --git a/packages/adapters/claude-local/src/index.ts b/packages/adapters/claude-local/src/index.ts index 802e4f54..75a2c7c4 100644 --- a/packages/adapters/claude-local/src/index.ts +++ b/packages/adapters/claude-local/src/index.ts @@ -6,3 +6,23 @@ export const models = [ { id: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 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 +`; diff --git a/packages/adapters/claude-local/src/server/execute.ts b/packages/adapters/claude-local/src/server/execute.ts index ff71fdf8..d279fcfc 100644 --- a/packages/adapters/claude-local/src/server/execute.ts +++ b/packages/adapters/claude-local/src/server/execute.ts @@ -75,12 +75,32 @@ export async function execute(ctx: AdapterExecutionContext): Promise 0 ? context.wakeReason.trim() : 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) { env.PAPERCLIP_TASK_ID = wakeTaskId; } if (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)) { if (typeof v === "string") env[k] = v; } diff --git a/packages/adapters/codex-local/src/index.ts b/packages/adapters/codex-local/src/index.ts index 4538896b..def7e68e 100644 --- a/packages/adapters/codex-local/src/index.ts +++ b/packages/adapters/codex-local/src/index.ts @@ -6,3 +6,23 @@ export const models = [ { id: "o3", label: "o3" }, { 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 +`; diff --git a/packages/adapters/codex-local/src/server/execute.ts b/packages/adapters/codex-local/src/server/execute.ts index 55cc12c4..b7b705d0 100644 --- a/packages/adapters/codex-local/src/server/execute.ts +++ b/packages/adapters/codex-local/src/server/execute.ts @@ -43,12 +43,32 @@ export async function execute(ctx: AdapterExecutionContext): Promise 0 ? context.wakeReason.trim() : 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) { env.PAPERCLIP_TASK_ID = wakeTaskId; } if (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)) { if (typeof v === "string") env[k] = v; } diff --git a/skills/paperclip-create-agent/SKILL.md b/skills/paperclip-create-agent/SKILL.md new file mode 100644 index 00000000..d103be81 --- /dev/null +++ b/skills/paperclip-create-agent/SKILL.md @@ -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": "", + "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": "" + }' +``` + +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/" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" + +curl -sS -X POST "$PAPERCLIP_API_URL/api/approvals//comments" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"body":"## CTO hire request submitted\n\n- Approval: [](/approvals/)\n- Pending agent: [](/agents/)\n- Source issue: [](/issues/)\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//approvals" \ + -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"approvalId":""}' +``` + +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` diff --git a/skills/paperclip-create-agent/references/api-reference.md b/skills/paperclip-create-agent/references/api-reference.md new file mode 100644 index 00000000..f6f1a355 --- /dev/null +++ b/skills/paperclip-create-agent/references/api-reference.md @@ -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. diff --git a/skills/paperclip/SKILL.md b/skills/paperclip/SKILL.md index f6b45f9c..22e76cc3 100644 --- a/skills/paperclip/SKILL.md +++ b/skills/paperclip/SKILL.md @@ -14,7 +14,7 @@ You run in **heartbeats** — short execution windows triggered by Paperclip. Ea ## 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. @@ -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 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. -**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 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.** -**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} 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`. -**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 @@ -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. - **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. +- **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/)`, `[Approval](/approvals/)`, `[Agent](/agents/)`) + +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) diff --git a/skills/paperclip/references/api-reference.md b/skills/paperclip/references/api-reference.md index 4a010f79..a0b8b6fe 100644 --- a/skills/paperclip/references/api-reference.md +++ b/skills/paperclip/references/api-reference.md @@ -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. +Use markdown formatting and include links to related entities when they exist: + +```md +## Update + +- Approval: [APPROVAL_ID](/approvals/) +- Pending agent: [AGENT_NAME](/agents/) +- Source issue: [ISSUE_ID](/issues/) +``` + **@-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) ``` -POST /api/companies/{companyId}/approvals +POST /api/companies/{companyId}/agent-hires { - "type": "hire_agent", - "requestedByAgentId": "{your-agent-id}", - "payload": { - "name": "Marketing Analyst", - "role": "researcher", - "reportsTo": "{manager-agent-id}", - "capabilities": "Market research, competitor analysis", - "budgetMonthlyCents": 5000 - } + "name": "Marketing Analyst", + "role": "researcher", + "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. +Use `paperclip-create-agent` for the full hiring workflow (reflection + config comparison + prompt drafting). + ### CEO strategy approval 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 ``` +### 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 @@ -304,6 +328,8 @@ Terminal states: `done`, `cancelled` | GET | `/api/agents/:agentId` | Agent details + chain of command | | GET | `/api/companies/:companyId/agents` | List all agents in company | | 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) @@ -317,6 +343,9 @@ Terminal states: `done`, `cancelled` | POST | `/api/issues/:issueId/release` | Release task ownership | | GET | `/api/issues/:issueId/comments` | List comments | | 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 @@ -339,6 +368,13 @@ Terminal states: `done`, `cancelled` | ------ | -------------------------------------------- | ---------------------------------- | | GET | `/api/companies/:companyId/approvals` | List approvals (`?status=pending`) | | 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/by-agent` | Costs by agent | | GET | `/api/companies/:companyId/costs/by-project` | Costs by project |