feat(api): restrict stateful APIs for migration - #943
Conversation
🧭 IronLoop Run · ReviewThis comment updates in place as the Run moves through its stages. 🟩 Final result · Completed
Automatic trigger · attempt 1 of 3 · completed in 1m 2s IronLoop completed the review and posted it to GitHub. 🔗 Result |
There was a problem hiding this comment.
🔍 IronLoop review
🟢 No actionable findings
No actionable defects found in the complete change. The retired APIs remain authenticated, stateless response validation is enforced at both HTTP and service boundaries, and request content is confined to request-scoped repositories.
Validation
- ✅ Changed-surface inspection — Reviewed all changed production code, affected call paths, replacement tests, and captured review feedback; no prior feedback or threads required deduplication.
- ✅ Captured CI — The captured Test Suite, Build release, Lint, Integration tests, E2E tests, Unit tests, cargo audit, and cargo deny checks all passed.
Review details
- Run:
2cbb6feb-1180-4639-a6e8-416118ff4dec - Workflow: Review
- Attempts: 1
|
Review — Building on the earlier IronLoop pass (no actionable findings). The mechanics of the retirement are solid: the transient repositories faithfully mirror the DB repo semantics (including the odd default 1. Response attestation/verifiability is silently removed — not mentioned anywhere user-facing
Meanwhile
2. Function calling now has no working path at all
3. ResponseTool::Mcp { require_approval, .. } if !matches!(
require_approval, McpApprovalRequirement::Simple(McpApprovalMode::Never)) => Err(...)
4. The route previously did 5. Inconsistent retirement envelopes (minor)
6.
7.
Nothing here blocks on correctness of the new code — item 1 is the one I would want resolved (or explicitly signed off) before merge, since it changes a security/trust guarantee that is still advertised in the API surface. |
|
@ironloopai review |
🧭 IronLoop Run · ReviewThis comment updates in place as the Run moves through its stages. 🟩 Final result · Completed
Manual command by hanakannzashi · attempt 1 of 3 · completed in 52s IronLoop completed the review and posted it to GitHub. 🔗 Result |
There was a problem hiding this comment.
🔍 IronLoop review
🟢 No actionable findings
The change consistently retires stateful API surfaces, enforces request-scoped Responses behavior, and preserves completed-response attestation without retaining raw content. No new actionable findings remain after accounting for the captured review discussion.
Validation
- ✅ Captured CI — Build, unit, integration, E2E, lint, cargo audit, and cargo deny checks all passed.
- ✅ Static review — Inspected the complete production-code change, affected routing, stateless validation, transient repositories, attestation handling, tests, and existing review feedback.
Review details
- Run:
2d574e9e-b969-4a7e-a801-7e067bdee0d9 - Workflow: Review
- Attempts: 1
3e8e606 to
b5ab148
Compare
(cherry picked from commit 2f3aa2232649aaee5b440b4c17b78db9e1e1df58)
Stage I scope clarificationThe current PR implements the Stage I boundary from #953, not a full Conversation/File API removal. It retains the six pre-existing, authenticated workspace-scoped Conversation/File view endpoints listed in the PR body, while mutations and unlisted descendants return Earlier review comments in this thread describe an all-410 version of the branch; they are historical context and are superseded by the current implementation and PR description. Final API removal is tracked as Stage III work. |
think-in-universe
left a comment
There was a problem hiding this comment.
Reviewed the latest patch and found one issue in the stateless function replay path.
Superseding Stage I scope clarification: retained resource DELETEThe chosen Stage I boundary retains These remain the existing API-key/workspace-scoped public endpoints, not a new trusted Chat-only route or credential. Earlier comments that characterize every Conversation/File mutation as retired are historical and superseded by the current PR description and this clarification. |
|
@ironloopai review |
Review · Status🟩 CompletedIronLoop completed the review and posted it to GitHub. ResultRun detailsManual command by think-in-universe · attempt 1 of 3 · completed in 27m 17s |
|
@claude review |
|
Review — Stage I bounded surface ( Re-reviewed against the current head, not the earlier all-410 branch. Acknowledging prior threads: the two scope clarifications from @hanakannzashi supersede my 2026-08-19 comment, and most of that comment is now resolved on this head — attestation is back ( The route-layout work is solid:
Pending Case A —
Case B — Same failure — the Net effect: a request Cloud validates as OK fails at the provider and surfaces as Two ways out — either is fine, but pick one:
Same code path, the shape your own The model originally produced one assistant turn with both text and Notes (non-blocking)
Items 1 and 2 are the ones I would want resolved before merge: both sit in the one genuinely new behaviour this PR ships (client-managed function replay), and both are currently locked in by passing unit tests. |
There was a problem hiding this comment.
Review · Summary
Found one issue in the new image-model restriction.
Findings: 🟠 Medium 1
Code-specific findings are attached to the diff.
Validation
- ✅ Static review — Reviewed the stateless request boundary, route restrictions, function replay, attestation flow, and cache controls; the change has no whitespace errors.
Review details
- Run:
841ce0c7-585d-42f6-be53-e3f3ede9f597 - Attempts: 1
|
Follow-up on this review: item 2 is fixed in a3cb82f. A replayed assistant |
Summary
This PR restricts the legacy confidential-data APIs to an explicit Stage I bounded surface. It preserves six existing retrieval views and two resource DELETE operations needed by the established Chat account-deletion workflow; every other legacy Conversation/File mutation is retired. It also makes Responses stateless and single-inference.
Exact Stage I API matrix
Unless noted otherwise,
/v1/responses, Conversation, and File routes use the existing Bearer API-key/workspace context. Their route groups applyCache-Control: no-store, including authenticated410responses.Responses
POST /v1/responsesstoreandstore: falseare accepted;store: trueis400. Each successful request performs exactly one internal Chat Completions completion-stream call. Noresponsesorresponse_itemsdatabase rows are created, read, or updated.conversation,previous_response_id,background: true400backgroundandbackground: falsenormalize tofalse.input_text, assistant-messageoutput_text, andinput_imageare accepted;input_fileis400.type: "function"function_call, but never executes or retries it. The caller replays a non-emptyfunction_calland its matchingfunction_call_outputin a new request;thought_signatureis preserved. A function merely namedweb_searchremains a client function.400mcp_approval_responseandmcp_list_toolsinput items are unsupported.400web_search,web_context_search,file_search,code_interpreter,computer, and remotemcpare rejected before provider work.400/v1/responses/{id},/v1/responses/{id}/cancel, or/v1/responses/{id}/input_items410 Gone/v1/responses/**paths retain normal router404/405behavior.GET /v1/signature/{resp_id}resp_*record.Conversations
POST /v1/conversations/batchmissing_ids. This is not a Conversation-list API.GET /v1/conversations/{id}GET /v1/conversations/{id}/itemsDELETE /v1/conversations/{id}410 GoneFiles
GET /v1/filesGET /v1/files/{id}GET /v1/files/{id}/contentDELETE /v1/files/{id}410 GoneThe six temporary retrieval views and two resource DELETE operations are the complete retained Conversation/File surface. No new Cloud export endpoint or
GET /v1/conversationslist endpoint is introduced. The DELETE exception is a product/workflow exception, not an authorization distinction: any caller already holding an authorized workspace API key can invoke it.Separate surfaces
POST /mcp/v1/mcp; its MCP server exposes onlyweb_searchand is never invoked by Responses.POST /v1/images/generations,POST /v1/images/editsPOST /v1/chat/completionsRollout boundary
The retained DELETE routes allow Chat's existing asynchronous
DELETE /v1/users/meworker to clean up Cloud resources before it performs local finalization. This PR deliberately does not introduce a trusted Chat-only credential or internal deletion route; Cloud cannot distinguish a worker request from another authorized workspace caller.The retrieval views are retired in Stage III after the migration/export window. Retiring the two DELETE exceptions remains tied to the account-deletion lifecycle and is outside this PR.
Validation
cargo fmt --all -- --checkgit diff --checkCache-Control: no-storecoveragecargo test -p api --test e2e_all -- --test-threads=16— 609 passed, 0 failed, 9 ignoredPart of #934 and #953.
Closes #936
Closes #937
Closes #939
Closes #941