From efef2d0747288058ba871e2f36f21d1fe755e360 Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 9 Nov 2026 01:57:13 -0600 Subject: [PATCH] fix(chat): name the budget pages in the board-only budget catalog entries An agent that reads a board-only budget route in the catalog now also reads where the person acts, so it can reply with the link without calling the route first to learn it from the 403. Co-Authored-By: Claude Opus 5.5 --- server/src/__tests__/agent-refusal-finality.test.ts | 2 ++ server/src/routes/openapi.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/server/src/__tests__/agent-refusal-finality.test.ts b/server/src/__tests__/agent-refusal-finality.test.ts index 203fb6d6e5c..85600e83c9a 100644 --- a/server/src/__tests__/agent-refusal-finality.test.ts +++ b/server/src/__tests__/agent-refusal-finality.test.ts @@ -91,6 +91,8 @@ describe("agent refusals that are final", () => { ["/api/approvals/{id}/approve", "post"], ["/api/approvals/{id}/reject", "post"], ] as const) expect(paths[path][method]["x-paperclip-authorization"], `${method} ${path}`).toEqual({ actor: "board" }); + expect(paths["/api/companies/{companyId}/budget-incidents/{incidentId}/resolve"].post.description).toContain("[Open budgets](//activity/budgets)"); + expect(paths["/api/agents/{agentId}/budgets"].patch.description).toContain("[Open budget](//agents//budgets)"); }); it("points the API catalog at the checked MCP setup route and the complete model lists", () => { diff --git a/server/src/routes/openapi.ts b/server/src/routes/openapi.ts index bc75caf2a22..03e46dfe5e3 100644 --- a/server/src/routes/openapi.ts +++ b/server/src/routes/openapi.ts @@ -6055,6 +6055,7 @@ registry.registerPath({ path: "/api/companies/{companyId}/budget-incidents/{incidentId}/resolve", tags: ["costs"], summary: "Resolve a budget incident", + description: "Board only: agent credentials get 403, so an agent cannot raise a limit or resume a budget-stopped agent. A board user chooses the new amount and resumes on the Budgets page: link [Open budgets](//activity/budgets) with this conversation's company prefix as , and reply.", request: { params: z.object({ companyId: z.string(), incidentId: z.string() }), body: jsonBody(resolveBudgetIncidentSchema), @@ -6093,6 +6094,7 @@ registry.registerPath({ path: "/api/agents/{agentId}/budgets", tags: ["costs"], summary: "Update agent budget", + description: "Board only: agent credentials get 403. A board user changes the limit on the agent's budget tab: link [Open budget](//agents//budgets) with this conversation's company prefix as , and reply.", request: { params: z.object({ agentId: z.string() }), body: jsonBody(updateBudgetSchema),