{
  "openapi": "3.0.0",
  "info": {
    "title": "driftless API",
    "version": "1.0.0",
    "description": "API documentation for the driftless project management system"
  },
  "servers": [
    {
      "url": "https://app.godriftless.ai",
      "description": "Development server"
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key for authentication"
      }
    },
    "schemas": {
      "WikiPage": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string",
            "description": "Wiki page ID"
          },
          "initiativeId": {
            "type": "string",
            "description": "ID of the initiative this page belongs to"
          },
          "parentId": {
            "type": "string",
            "nullable": true,
            "description": "ID of the parent page (null for root pages)"
          },
          "title": {
            "type": "string",
            "description": "Title of the wiki page"
          },
          "content": {
            "type": "string",
            "description": "Content of the wiki page"
          },
          "order": {
            "type": "number",
            "description": "Display order of the page"
          },
          "createdBy": {
            "type": "string",
            "description": "ID of the user who created the page"
          }
        }
      },
      "LlmUsage": {
        "type": "object",
        "description": "LLM usage tracking subdocument on each task. Per-model counters keyed by provider:model (dot-safe encoded), plus aggregate rollup.",
        "properties": {
          "aggregate": {
            "type": "object",
            "description": "Rollup totals across all models",
            "properties": {
              "totalPromptTokens": {
                "type": "integer",
                "description": "Total prompt tokens across all models"
              },
              "totalCacheTokens": {
                "type": "integer",
                "description": "Total cache tokens across all models"
              },
              "totalInferenceTokens": {
                "type": "integer",
                "description": "Total inference tokens across all models"
              },
              "totalCost": {
                "type": "integer",
                "description": "Total cost in integer cents"
              },
              "totalRequests": {
                "type": "integer",
                "description": "Total LLM requests across all models"
              },
              "updatedDate": {
                "type": "string",
                "format": "date-time",
                "description": "Last usage update timestamp"
              }
            }
          },
          "models": {
            "type": "object",
            "description": "Map keyed by provider:model composite string (dots in model names encoded as underscores). Same model from different providers produces independent entries.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "promptTokens": {
                  "type": "integer"
                },
                "cacheTokens": {
                  "type": "integer"
                },
                "inferenceTokens": {
                  "type": "integer"
                },
                "cost": {
                  "type": "integer",
                  "description": "Cost in cents"
                },
                "requests": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "Initiative": {
        "type": "object",
        "description": "An initiative containing product requirements and tech spec sections with rich text editing",
        "properties": {
          "_id": {
            "type": "string",
            "description": "Initiative ID"
          },
          "name": {
            "type": "string",
            "description": "Name of the initiative"
          },
          "description": {
            "type": "string",
            "description": "Description of the initiative"
          },
          "organizationId": {
            "type": "string",
            "description": "Organization ID this initiative belongs to"
          },
          "projectId": {
            "type": "string",
            "nullable": true,
            "description": "Project ID this initiative belongs to"
          },
          "status": {
            "type": "string",
            "enum": [
              "planning",
              "active",
              "completed",
              "archived"
            ],
            "description": "Initiative status"
          },
          "prdSections": {
            "type": "array",
            "description": "Product Requirements sections with rich text (HTML) content. Each section can be linked 1:1 with a tech spec section via techSpecId.",
            "items": {
              "type": "object",
              "properties": {
                "_id": {
                  "type": "string",
                  "description": "Section ID"
                },
                "content": {
                  "type": "string",
                  "description": "HTML content from rich text editor"
                },
                "techSpecId": {
                  "type": "string",
                  "nullable": true,
                  "description": "ID of linked Tech Spec section (bidirectional link)"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "techSpecSections": {
            "type": "array",
            "description": "Tech Spec sections with rich text (HTML) content. Each section can be linked 1:1 with a PRD section via prdId.",
            "items": {
              "type": "object",
              "properties": {
                "_id": {
                  "type": "string",
                  "description": "Section ID"
                },
                "content": {
                  "type": "string",
                  "description": "HTML content from rich text editor"
                },
                "prdId": {
                  "type": "string",
                  "nullable": true,
                  "description": "ID of linked PRD section (bidirectional link)"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Authentication",
      "description": "User authentication and authorization endpoints"
    },
    {
      "name": "Bots",
      "description": "Bot management endpoints"
    },
    {
      "name": "Comments",
      "description": "Task comment management endpoints"
    },
    {
      "name": "Health",
      "description": "Service health check endpoints"
    },
    {
      "name": "Initiatives",
      "description": "Initiative management endpoints"
    },
    {
      "name": "Media",
      "description": "Media file management endpoints"
    },
    {
      "name": "Organizations",
      "description": "Organization management endpoints"
    },
    {
      "name": "Projects",
      "description": "Project management endpoints"
    },
    {
      "name": "Tasks",
      "description": "Task management endpoints"
    },
    {
      "name": "Wiki",
      "description": "Wiki page management endpoints"
    }
  ],
  "paths": {
    "/api/organizations/{orgId}/initiatives/{initiativeId}/wiki": {
      "get": {
        "tags": [
          "Wiki"
        ],
        "summary": "Get all wiki pages for an initiative",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "parentId",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wiki pages retrieved successfully"
          }
        }
      },
      "post": {
        "tags": [
          "Wiki"
        ],
        "summary": "Create a new wiki page"
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/wiki/search": {
      "get": {
        "tags": [
          "Wiki"
        ],
        "summary": "Search wiki pages by content",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/wiki/{id}": {
      "get": {
        "tags": [
          "Wiki"
        ],
        "summary": "Get a single wiki page"
      },
      "put": {
        "tags": [
          "Wiki"
        ],
        "summary": "Update a wiki page"
      },
      "delete": {
        "tags": [
          "Wiki"
        ],
        "summary": "Delete a wiki page"
      }
    },
    "/api/organizations/{orgId}/tasks-debug": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Debug - Test tasks endpoint",
        "description": "Debug endpoint to test tasks functionality.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Organization ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Debug endpoint working"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/resolve": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Batch-resolve task IDs to titles",
        "description": "Given a comma-separated list of task IDs (e.g. MC-111,MC-150), returns a map of task ID → { title, status }.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "ids",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated task IDs to resolve"
          }
        ],
        "responses": {
          "200": {
            "description": "Map of task ID to task info"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "List tasks in organization",
        "description": "Retrieve a list of tasks with optional filters",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "assigneeType",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "projectId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "initiativeId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "assigneeId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "priority",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "priority",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated priority filter (e.g. \"high,critical\")"
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated type filter (e.g. \"bug,feature\")"
          },
          {
            "in": "query",
            "name": "lite",
            "schema": {
              "type": "string"
            },
            "description": "MC-703 — \"1\"/\"true\" returns the lightweight poll payload (minimal fields, no ref populates, no comment/unread post-work)."
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "doneWithinDays",
            "schema": {
              "type": "integer"
            },
            "description": "MC-714 — when set (e.g. 5), done tasks older than this many days are excluded at the DB level. Only restricts the done column; other statuses are unaffected. Used by the kanban board to avoid transferring stale done tasks."
          }
        ],
        "responses": {
          "200": {
            "description": "List of tasks"
          }
        }
      },
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Create a new task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "priority": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "projectId": {
                    "type": "string"
                  },
                  "initiativeId": {
                    "type": "string"
                  },
                  "assigneeId": {
                    "type": "string"
                  },
                  "assigneeType": {
                    "type": "string"
                  },
                  "acceptanceCriteriaSections": {
                    "type": "array",
                    "description": "Structured acceptance criteria (MC-644)",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string",
                          "description": "Short human-readable label for the AC section"
                        },
                        "description": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "not-started",
                            "in-progress",
                            "ready-to-test",
                            "passed",
                            "failed"
                          ]
                        },
                        "testRefs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "ci-check",
                                  "s3-log",
                                  "playwright-video",
                                  "pr",
                                  "comment"
                                ]
                              },
                              "ref": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pass",
                                  "fail",
                                  "pending"
                                ]
                              },
                              "testType": {
                                "type": "string",
                                "enum": [
                                  "unit",
                                  "integration",
                                  "e2e",
                                  "manual"
                                ]
                              },
                              "timestamp": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Task created"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/search": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Search tasks",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/count": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get task count by status",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "projectId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "initiativeId",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task counts by status"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get a single task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task details"
          }
        }
      },
      "patch": {
        "tags": [
          "Tasks"
        ],
        "summary": "Update a task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "acceptanceCriteriaSections": {
                    "type": "array",
                    "description": "Structured acceptance criteria (MC-644)",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string",
                          "description": "Short human-readable label for the AC section"
                        },
                        "description": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "not-started",
                            "in-progress",
                            "ready-to-test",
                            "passed",
                            "failed"
                          ]
                        },
                        "testRefs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "ci-check",
                                  "s3-log",
                                  "playwright-video",
                                  "pr",
                                  "comment"
                                ]
                              },
                              "ref": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pass",
                                  "fail",
                                  "pending"
                                ]
                              },
                              "testType": {
                                "type": "string",
                                "enum": [
                                  "unit",
                                  "integration",
                                  "e2e",
                                  "manual"
                                ]
                              },
                              "timestamp": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Task updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Tasks"
        ],
        "summary": "Delete a task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task deleted"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/cost": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get task cost (MC-619 Task Cost Center)",
        "description": "Returns the total customer cost for a task. Org admins may pass ?detail=models to get a per-model customerCost breakdown (in dollars). actualCost, token counts, and provider rates are never returned.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "detail",
            "schema": {
              "type": "string",
              "enum": [
                "models"
              ]
            },
            "description": "Per-model breakdown (org admins only; silently omitted otherwise)"
          }
        ],
        "responses": {
          "200": {
            "description": "Task cost",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "totalCustomerCost": {
                      "type": "number",
                      "description": "Total customer cost in dollars"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Task not found"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/bulk": {
      "patch": {
        "tags": [
          "Tasks"
        ],
        "summary": "Bulk update tasks (status, initiative, assignee)",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "taskIds",
                  "operation"
                ],
                "properties": {
                  "taskIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "operation": {
                    "type": "string",
                    "enum": [
                      "setStatus",
                      "moveToInitiative",
                      "assign"
                    ]
                  },
                  "data": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk operation results"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/status": {
      "patch": {
        "tags": [
          "Tasks"
        ],
        "summary": "Update task status",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task status updated"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/reorder": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Reorder tasks within a status",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "taskIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "status": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tasks reordered"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/assign": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Assign a user/bot to a task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task assigned"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/links": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Add a link to another task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Link added"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/links/{linkId}": {
      "delete": {
        "tags": [
          "Tasks"
        ],
        "summary": "Remove a link from a task",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "linkId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Link removed"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/llm-usage": {
      "patch": {
        "tags": [
          "Tasks"
        ],
        "summary": "Record LLM usage data on a task",
        "description": "Atomically increments per-model and aggregate LLM usage counters on a task.\nProvider and model are accepted as separate fields and composed into a dot-safe\nmap key internally (e.g. `ollama/glm-5.1`). Does NOT bump `task.updatedDate` —\nusage is a passive metric. Requires `PROJECT_TASKS_WRITE` scope.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Organization ID"
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Task ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "provider",
                  "model",
                  "promptTokens",
                  "cacheTokens",
                  "inferenceTokens",
                  "cost",
                  "requests"
                ],
                "properties": {
                  "provider": {
                    "type": "string",
                    "description": "LLM provider name (e.g. \"ollama\", \"openrouter\")",
                    "example": "ollama"
                  },
                  "model": {
                    "type": "string",
                    "description": "Model name (may contain dots, e.g. \"glm-5.1\")",
                    "example": "glm-5.1"
                  },
                  "promptTokens": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Number of prompt tokens consumed"
                  },
                  "cacheTokens": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Number of cache tokens consumed"
                  },
                  "inferenceTokens": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Number of inference (completion) tokens consumed"
                  },
                  "cost": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Cost in float cents (MC-641; display layers divide by 100)"
                  },
                  "requests": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Number of LLM requests (typically 1 per call)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "LLM usage recorded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "llmUsage": {
                      "type": "object",
                      "description": "Updated llmUsage subdocument (not the full task)",
                      "properties": {
                        "aggregate": {
                          "type": "object",
                          "properties": {
                            "totalPromptTokens": {
                              "type": "integer"
                            },
                            "totalCacheTokens": {
                              "type": "integer"
                            },
                            "totalInferenceTokens": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number",
                              "description": "Total cost in cents (float, MC-641)"
                            },
                            "totalRequests": {
                              "type": "integer"
                            },
                            "updatedDate": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "models": {
                          "type": "object",
                          "description": "Map keyed by `provider/model` (dot-safe encoded).\nSame model from different providers produces independent entries.\n",
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "promptTokens": {
                                "type": "integer"
                              },
                              "cacheTokens": {
                                "type": "integer"
                              },
                              "inferenceTokens": {
                                "type": "integer"
                              },
                              "cost": {
                                "type": "number"
                              },
                              "requests": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — missing/invalid fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "msg": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Insufficient scope (requires PROJECT_TASKS_WRITE)"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/logs": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Append a log archive entry to task.logs (MC-565)",
        "description": "Appends a record { s3Key, timestamp } to the task's logs array after\nthe satellite successfully pushes a log file to S3. This makes the task\nitself the authoritative index of archived runs — eliminates the need\nfor S3 ListObjectsV2 by path prefix.\n\nThe organizationId is derived from the authenticated session, never\nfrom the request body. The task must belong to the caller's org.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Organization ObjectId (from auth session)"
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Task ID (MC-123 or ObjectId)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "s3Key",
                  "timestamp"
                ],
                "properties": {
                  "s3Key": {
                    "type": "string",
                    "description": "S3 key path for the archived log file"
                  },
                  "timestamp": {
                    "type": "string",
                    "description": "ISO 8601 timestamp of the run (post-S3-push time)"
                  },
                  "runTimestamp": {
                    "type": "string",
                    "description": "Subprocess start time, used as file identifier for retrieval"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Log entry appended successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "logs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "s3Key": {
                            "type": "string"
                          },
                          "timestamp": {
                            "type": "string"
                          },
                          "runTimestamp": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — s3Key and timestamp are required"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Insufficient scope or org mismatch (requires PROJECT_TASKS_WRITE)"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/phase-progress": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Replace task.phaseProgress snapshot (MC-670)",
        "description": "Atomically $set task.phaseProgress to the latest phase snapshot emitted\nby the agent's todo tool. Full replace, not merge — the phases array is\nthe complete current state. The satellite calls this after a 2s debounce\nwindow closes.\n\nThe organizationId is derived from the authenticated session, never\nfrom the request body. The task must belong to the caller's org.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Organization ObjectId (from auth session)"
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Task ID (MC-123 or ObjectId)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phases"
                ],
                "properties": {
                  "phases": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "name"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "tasks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "name",
                              "status"
                            ],
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "in-progress",
                                  "completed"
                                ]
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Phase progress snapshot persisted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "phaseProgress": {
                      "type": "object",
                      "properties": {
                        "phases": {
                          "type": "array"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — phases array required"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Insufficient scope or org mismatch (requires PROJECT_TASKS_WRITE)"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "apiKey": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get all projects for organization",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Projects retrieved successfully"
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create a new project",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "taskPrefix": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Project created successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/projects/prefixes": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get all valid task prefixes",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of valid task prefixes"
          }
        }
      }
    },
    "/api/organizations/{orgId}/projects/{projectId}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get single project by ID",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project retrieved successfully"
          }
        }
      },
      "put": {
        "tags": [
          "Projects"
        ],
        "summary": "Update a project",
        "description": "Updates project fields. The slug is immutable and will not change even if the name is updated.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "New project name (slug will NOT change)"
                  },
                  "description": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project updated successfully"
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Delete a project (soft delete)",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project deleted successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/projects/{projectId}/toggle-star": {
      "patch": {
        "tags": [
          "Projects"
        ],
        "summary": "Toggle project star status",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project star status toggled successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/projects/{projectId}/members": {
      "get": {
        "tags": [
          "Project Members"
        ],
        "summary": "List all members of a project",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Members retrieved successfully"
          }
        }
      },
      "post": {
        "tags": [
          "Project Members"
        ],
        "summary": "Add a member to a project",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "roles"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Member added successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/projects/{projectId}/members/{userId}": {
      "get": {
        "tags": [
          "Project Members"
        ],
        "summary": "Get a single project member",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Member retrieved successfully"
          }
        }
      },
      "patch": {
        "tags": [
          "Project Members"
        ],
        "summary": "Update a member's roles",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "roles"
                ],
                "properties": {
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Member roles updated successfully"
          }
        }
      },
      "delete": {
        "tags": [
          "Project Members"
        ],
        "summary": "Remove a member from a project",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Member removed successfully"
          }
        }
      }
    },
    "/api/organizations": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "List all organizations (admin only)"
      },
      "post": {
        "tags": [
          "Organizations"
        ],
        "summary": "Create a new organization"
      }
    },
    "/api/organizations/{orgId}/members": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "List human members in organization"
      }
    },
    "/api/organizations/{orgId}/users": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "List users in organization"
      }
    },
    "/api/organizations/{orgId}/users/{userId}": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "Get a user by ID"
      },
      "patch": {
        "tags": [
          "Organizations"
        ],
        "summary": "Update a user"
      },
      "delete": {
        "tags": [
          "Organizations"
        ],
        "summary": "Delete a user"
      }
    },
    "/api/organizations/{orgId}/users/{userId}/toggle-online": {
      "patch": {
        "tags": [
          "Organizations"
        ],
        "summary": "Toggle user online/offline status"
      }
    },
    "/api/organizations/{orgId}/bots": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "List bots in organization"
      },
      "post": {
        "tags": [
          "Organizations"
        ],
        "summary": "Create a new bot"
      }
    },
    "/api/organizations/{orgId}/bots/{botId}/regenerate-api-key": {
      "post": {
        "tags": [
          "Organizations"
        ],
        "summary": "Regenerate bot API key"
      }
    },
    "/api/organizations/{orgId}/users/{userId}/project-settings": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "Get project settings for a user"
      }
    },
    "/api/organizations/{orgId}/users/{userId}/project-settings/{projectId}": {
      "patch": {
        "tags": [
          "Organizations"
        ],
        "summary": "Update project settings for a user"
      }
    },
    "/api/organizations/{orgId}/stats": {
      "get": {
        "tags": [
          "Organizations"
        ],
        "summary": "Get organization statistics"
      }
    },
    "/api/organizations/{orgId}/logs/presign": {
      "get": {
        "tags": [
          "Logs"
        ],
        "summary": "Generate a presigned PUT URL for S3 log archive upload",
        "description": "Generates a presigned S3 PUT URL for uploading agent run logs to the\nlog archive bucket. This is the credential boundary — only the main\nserver holds AWS IAM permissions for S3. The orchestrator calls this\nendpoint to obtain presigned URLs for the satellite.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Task display ID (e.g. \"MC-123\") or ObjectId"
          }
        ],
        "responses": {
          "200": {
            "description": "Presigned URL and S3 key path",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "presignedUrl": {
                      "type": "string"
                    },
                    "s3Key": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing taskId query parameter"
          },
          "403": {
            "description": "Insufficient scope or task belongs to a different org"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "sessionAuth": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/logs/{taskId}": {
      "get": {
        "tags": [
          "Logs"
        ],
        "summary": "List archived log objects for a task",
        "description": "Returns metadata for all archived run logs in S3 for the given task.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Task display ID (e.g. \"MC-123\") or ObjectId"
          }
        ],
        "responses": {
          "200": {
            "description": "List of archived log objects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "logs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "runTimestamp": {
                            "type": "string"
                          },
                          "s3Key": {
                            "type": "string"
                          },
                          "size": {
                            "type": "integer"
                          },
                          "lastModified": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Task belongs to a different org"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "sessionAuth": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/logs/{taskId}/{runTimestamp}": {
      "get": {
        "tags": [
          "Logs"
        ],
        "summary": "Get a single archived log file as JSONL text",
        "description": "Streams the raw JSONL log content from S3 for a specific run.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "runTimestamp",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Timestamp portion of the S3 key (e.g. \"2026-07-12T16-27-03-123Z\")"
          }
        ],
        "responses": {
          "200": {
            "description": "JSONL log content",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid run timestamp format"
          },
          "403": {
            "description": "Task belongs to a different org"
          },
          "404": {
            "description": "Task or log file not found"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "sessionAuth": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/logs/{taskId}/{runTimestamp}/download": {
      "get": {
        "tags": [
          "Logs"
        ],
        "summary": "Download a single archived log file as a .txt attachment",
        "description": "Returns the raw JSONL log content from S3 with a\nContent-Disposition: attachment header so the browser downloads it\nas a .txt file. The filename follows {taskId}_{date}_{time}.txt\n(e.g. MC-755_2026-07-22_171400.txt). Gated identically to the read\npath — same PROJECT_TASKS_VIEW scope and org check.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "runTimestamp",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Timestamp portion of the S3 key (e.g. \"2026-07-12T16-27-03-123Z\")"
          }
        ],
        "responses": {
          "200": {
            "description": "Log content as a .txt file download",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "description": "attachment; filename=\"{taskId}_{date}_{time}.txt\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid run timestamp format"
          },
          "403": {
            "description": "Task belongs to a different org"
          },
          "404": {
            "description": "Task or log file not found"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "sessionAuth": []
          }
        ]
      }
    },
    "/api/organizations/{orgId}/initiatives": {
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Get all initiatives for organization",
        "description": "Retrieve all initiatives for the specified organization, optionally filtered by project. Each initiative includes a taskCount field.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "projectId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "searchTerm",
            "schema": {
              "type": "string"
            },
            "description": "Search term to filter initiatives by name, description, or search terms/aliases"
          }
        ],
        "responses": {
          "200": {
            "description": "Initiatives retrieved successfully"
          }
        }
      },
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Create new initiative",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "projectId": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "searchTerms": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Search terms/aliases for finding this initiative"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Initiative created successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/by-project/{projectId}": {
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "List initiatives categorized by home vs linked for a project",
        "description": "Returns an object with home and linked arrays where home initiatives have this project as their home project and linked initiatives have this project as a linked project.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Initiatives categorized by role"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}/tasks": {
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Get tasks for an initiative filtered by accessible projects",
        "description": "Returns tasks from the initiative, optionally filtered by projects the user has access to.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "projectIds",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of project ObjectIds to filter tasks by"
          }
        ],
        "responses": {
          "200": {
            "description": "Filtered task list"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}": {
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Get single initiative by ID",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Initiative retrieved successfully"
          }
        }
      },
      "put": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Update an initiative (full replace)",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Initiative updated successfully"
          }
        }
      },
      "patch": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Partially update an initiative",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Initiative updated successfully"
          }
        }
      },
      "delete": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Delete an initiative",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Initiative deleted successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}/export-pdf": {
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Export initiative as PDF",
        "description": "Generates a landscape PDF of the initiative with PRD/Tech Spec sections side-by-side and task summary.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF document",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/api/organizations/{orgId}/projects/{projectId}/initiatives/{initiativeId}/cascade-cycle": {
      "get": {
        "summary": "Get cascade cycle snapshot",
        "description": "Returns pre-aggregated data for all four cascade phases (Shape, Gate, Ship, Verify) in a single response.",
        "tags": [
          "Initiatives"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cascade cycle snapshot with shape, gate, ship, and verify buckets"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient scope or organization access"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}/prd-paragraphs": {
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Get PRD paragraphs for an initiative"
      },
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Create a PRD paragraph"
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/prd-paragraphs/{paragraphId}": {
      "put": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Update a PRD paragraph"
      },
      "delete": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Delete a PRD paragraph"
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/prd-paragraphs/reorder": {
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Reorder PRD paragraphs"
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/prd-sections": {
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Create a PRD section (also creates paired Tech Spec section)",
        "description": "Creates a new PRD section embedded in the initiative. Automatically creates a linked Tech Spec section with bidirectional references: the PRD section's `techSpecId` points to the new Tech Spec section, and the Tech Spec section's `prdId` points back to the PRD section.\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Organization ID"
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Initiative ID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "HTML content for the PRD section (defaults to empty string)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PRD section (and paired Tech Spec section) created successfully. Returns the full updated initiative.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Initiative"
                }
              }
            }
          },
          "404": {
            "description": "Initiative not found"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/prd-sections/reorder": {
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Reorder PRD sections",
        "description": "Sets the order of PRD sections by providing an array of section IDs in the desired order.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sectionIds"
                ],
                "properties": {
                  "sectionIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of PRD section IDs in the desired order"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PRD sections reordered successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/prd-sections/{sectionId}": {
      "put": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Update a PRD section",
        "description": "Updates a PRD section's content. If the section is locked by another user via WebSocket, returns 423 Locked.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "content"
                ],
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "Updated HTML content for the PRD section"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Section updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "section": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string"
                        },
                        "techSpecId": {
                          "type": "string",
                          "nullable": true
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "423": {
            "description": "Section is locked by another user",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "lockedBy": {
                      "type": "object",
                      "properties": {
                        "userId": {
                          "type": "string"
                        },
                        "userName": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Partially update a PRD section (auto-save)",
        "description": "Lightweight partial update for auto-save. Only sends changed fields. If the section is locked by another user via WebSocket, returns 423 Locked.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Section updated successfully"
          },
          "423": {
            "description": "Section is locked by another user"
          }
        }
      },
      "delete": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Delete a PRD section (and its linked Tech Spec section)",
        "description": "Deletes a PRD section by ID. If the PRD section has a linked Tech Spec section (via `techSpecId`), the linked Tech Spec section is also deleted (cascading delete).\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PRD section (and linked Tech Spec section) deleted successfully. Returns the full updated initiative."
          },
          "404": {
            "description": "Initiative not found"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/tech-spec-sections": {
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Create a tech spec section",
        "description": "Creates a new Tech Spec section embedded in the initiative. Optionally links to an existing PRD section via `prdId` in the request body. When `prdId` is provided, the PRD section's `techSpecId` is updated to point back to the new Tech Spec section (bidirectional link).\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "HTML content for the Tech Spec section (defaults to empty string)"
                  },
                  "prdId": {
                    "type": "string",
                    "description": "ID of an existing PRD section to link bidirectionally"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tech Spec section created successfully. Returns the full updated initiative."
          },
          "404": {
            "description": "Initiative not found"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/tech-spec-sections/reorder": {
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Reorder tech spec sections",
        "description": "Sets the order of Tech Spec sections by providing an array of section IDs in the desired order.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sectionIds"
                ],
                "properties": {
                  "sectionIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of Tech Spec section IDs in the desired order"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tech Spec sections reordered successfully"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{initiativeId}/tech-spec-sections/{sectionId}": {
      "put": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Update a tech spec section",
        "description": "Updates a tech spec section. If locked by another user via WebSocket, returns 423 Locked.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "content"
                ],
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "Updated HTML content for the Tech Spec section"
                  },
                  "prdId": {
                    "type": "string",
                    "nullable": true,
                    "description": "ID of linked PRD section"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Section updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "section": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string"
                        },
                        "prdId": {
                          "type": "string",
                          "nullable": true
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "423": {
            "description": "Section is locked by another user"
          }
        }
      },
      "patch": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Partially update a tech spec section (auto-save)",
        "description": "Lightweight partial update for auto-save. If locked by another user, returns 423 Locked.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string"
                  },
                  "prdId": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Section updated successfully"
          },
          "423": {
            "description": "Section is locked by another user"
          }
        }
      },
      "delete": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Delete a tech spec section (and its linked PRD section)",
        "description": "Deletes a Tech Spec section by ID. If the Tech Spec section has a linked PRD section (via `prdId`), the linked PRD section is also deleted (cascading delete).\n",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "initiativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tech Spec section (and linked PRD section) deleted successfully. Returns the full updated initiative."
          },
          "404": {
            "description": "Initiative not found"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}/projects": {
      "post": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Add a project to an initiative's projects array",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "projectId"
                ],
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "ObjectId of the project to add"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project added to initiative"
          },
          "409": {
            "description": "Project already in initiative"
          }
        }
      },
      "get": {
        "tags": [
          "Initiatives"
        ],
        "summary": "List projects in an initiative",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of projects in the initiative"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}/projects/{projectId}": {
      "delete": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Remove a linked project from an initiative",
        "description": "Removes a project from the initiative's projects array. Cannot remove the home project.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project removed from initiative"
          },
          "400": {
            "description": "Cannot remove home project"
          }
        }
      }
    },
    "/api/organizations/{orgId}/initiatives/{id}/home-project": {
      "patch": {
        "tags": [
          "Initiatives"
        ],
        "summary": "Transfer home project role",
        "description": "Moves the specified projectId to projects[0] and updates projectId field. The target project must already be in the projects array.",
        "parameters": [
          {
            "in": "path",
            "name": "orgId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "homeProjectId"
                ],
                "properties": {
                  "homeProjectId": {
                    "type": "string",
                    "description": "ObjectId of the project to make the new home project"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Home project transferred successfully"
          },
          "400": {
            "description": "Project must already be linked"
          }
        }
      }
    },
    "/api/organizations/{orgId}/tasks/{taskId}/comments": {
      "get": {
        "tags": [
          "Comments"
        ],
        "summary": "Get comments for a task"
      },
      "post": {
        "tags": [
          "Comments"
        ],
        "summary": "Add a comment to a task"
      }
    },
    "/api/organizations/{orgId}/comments/{commentId}": {
      "delete": {
        "tags": [
          "Comments"
        ],
        "summary": "Delete a comment"
      },
      "patch": {
        "tags": [
          "Comments"
        ],
        "summary": "Edit a comment"
      }
    }
  }
}