feat(requests): P5 — approval tools become shims over unified requests + docs (RFC) #57
Reference in New Issue
Block a user
Delete Branch "feat/unified-requests-inbox-p5-shims"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 5 (final) of the unified requests/inbox RFC. The four legacy approval MCP tools become thin shims over the unified
/requestssubsystem (kind=approval). Tool names and parameter signatures are unchanged — fully backward-compatible. New approvals now land in the unifiedrequeststable and surface in the unified inbox / Approvals tab.Shimmed handlers → new endpoints
handleCreateApproval(workspace_id, action, reason?)POST /workspaces/{id}/requests{kind:"approval", recipient_type:"user", recipient_id:"", title: action, detail: reason}handleDecideApproval(workspace_id, approval_id, decision)POST /workspaces/{id}/requests/{approval_id}/respond{action: decision==="approved" ? "approved" : "rejected", responder_type:"user", responder_id:"admin"}(legacydeniedmaps torejected)handleListPendingApprovals()GET /requests/pending?kind=approvalhandleGetWorkspaceApprovals(workspace_id)GET /workspaces/{id}/requests(outgoing)Each tool description gains:
(deprecated — routes to the unified requests system; prefer create_request / respond_request).P1-contract gap noted
The per-workspace reads
ListOutgoing(GET /workspaces/:id/requests) andListInbox(.../requests/inbox) take only astatusfilter — P1 has NOkindquery param on those reads. Soget_workspace_approvalscannot filter to approvals server-side; it returns the workspace's outgoing requests (tasks + approvals). The cross-orgGET /requests/pendingdoes support?kind=approval, whichlist_pending_approvalsuses. We deliberately did not invent akindquery param the server would ignore.Docs
README.md: added a Requests / Inbox highlights row; marked Approvals deprecated-but-supported; annotated the management-mode Audit row.CLAUDE.md: tool registry's Approvals section rewritten as deprecated shims with a routes-to column.docs/design/rfc-unified-requests-inbox.mdlives in molecule-core), so skipped here.Tests
src/__tests__/index.test.tsapproval tests re-pointed to assert the/requestsendpoints + request bodies (fetch-mock, existing style). Tool count unchanged (handlers re-pointed, no tools added/removed) —management.test.tstool-count assertion still passes.Build / test
npm run build— clean (tsc)npx jest— 10 suites passed, 283 passed / 1 skippedMerges AFTER P1 (molecule-core #2525) and P2 (molecule-mcp-server #56).
🤖 Generated with Claude Code
qa APPROVE (5-axis, 1st genuine lane — author devops-engineer≠me; CR-A security via cb15acea = 2nd). Correctness: P5 — the 4 approval tools (list_pending_approvals/decide_approval/create_approval/get_workspace_approvals) become BACKWARD-COMPAT DEPRECATED SHIMS routing to the unified /requests subsystem with kind=approval (RFC unified-requests-inbox). Names + parameter signatures preserved; decide_approval→POST /workspaces/:id/requests/:id/respond (legacy decision=denied→action=rejected), create→POST /requests (kind=approval), list→GET /requests/pending?kind=approval. Sound routing. Robustness/Tests: non-vacuous — assert the EXACT endpoint URLs + POST bodies (action/responder_type/responder_id/kind/title/detail) + the legacy denied→rejected mapping. ⚠️ APPROVAL-INTEGRITY (the critical axis): the tools are CLIENT SHIMS — they FORWARD the decision to the server-side /respond endpoint; they do NOT and CANNOT self-enforce approval-integrity (no self-approve/forge/bypass is possible AT the tool layer because the tool has no authority — it just POSTs). The responder_type=user/responder_id=admin are CLIENT-SUPPLIED LABELS in the body; the real authz boundary is server-side (the workspace-server /respond handler must derive identity from the authenticated token, NOT trust the client responder_id). This PR introduces NO NEW integrity risk — it routes to the SAME /respond endpoint the unified respond_request tool already uses (boundary unchanged). NON-BLOCKING server-side note (pre-existing, not introduced here): confirm /respond validates authz from the token vs the client responder fields. Security/Content-sec: clean — 0 eval/exec/child_process, 0 cred-values, deprecation-only client routing. Performance: n/a. Readability: clear deprecation docs (CLAUDE.md/README). Gate green, mergeable. Approving the shim; integrity is server-side-bounded + unchanged.
Security 5-axis — APPROVE (head
5adc303d47). feat(requests): P5 — legacy approval tools become deprecated aliases routing to the unified requests system (+105/-40, approvals.ts + docs + tests). 2nd security lane (CR-B 1st); author devops-engineer != me.Gate GREEN. APPROVE → 2-distinct with CR-B. (Gated, like mcp#56, on #2525's server authz fix.)