Intent: the admin's capacity list reads like every other list. Half of #5063, which was parked twice.
Done:
[ ] The GET /api/v1/admin/capacity handler in src/http/api.ts answers json({ items: listed.value, next_cursor: null }). Change only the HTTP handler: listCapacity in src/actions/capacity.ts keeps its return value, because MCP (src/http/mcp.ts), the pages and the terminal call it directly. The first try changed the shared action and broke the forge over MCP > limits
[ ] The admin gate and the 404 for a non-admin are unchanged
[ ] Every test that reads this route's bare array reads items: test/capacity.test.ts, test/admin_refused.test.ts, test/guard-new-accounts.test.ts (run grep -rln 'admin/capacity' test src and fix each one that reads the body)
[ ] The OpenAPI row's summary for GET /api/v1/admin/capacity says { items, next_cursor }
[ ] A test asserts the shape
Before pushing, run the files above plus test/mcp.test.ts. A red test in a file this change does not touch: check whether main is red on it too (the sentinel's red: card) and say so in the pull, rather than giving up.
Intent: the admin's capacity list reads like every other list. Half of #5063, which was parked twice.
Done:
/api/v1/admin/capacityhandler in src/http/api.ts answersjson({ items: listed.value, next_cursor: null }). Change only the HTTP handler:listCapacityin src/actions/capacity.ts keeps its return value, because MCP (src/http/mcp.ts), the pages and the terminal call it directly. The first try changed the shared action and brokethe forge over MCP > limitsitems: test/capacity.test.ts, test/admin_refused.test.ts, test/guard-new-accounts.test.ts (rungrep -rln 'admin/capacity' test srcand fix each one that reads the body)/api/v1/admin/capacitysays{ items, next_cursor }Before pushing, run the files above plus test/mcp.test.ts. A red test in a file this change does not touch: check whether main is red on it too (the sentinel's red: card) and say so in the pull, rather than giving up.