Skip to content

tracking(serve): daemon capability gaps & prioritized backlog (post v0.16-alpha) #4514

@doudouOUC

Description

@doudouOUC

Purpose

Track the remaining real gaps in the qwen serve HTTP/SSE surface after accounting for the existing slash-command passthrough path.

A remote client can already invoke ACP-compatible slash commands by sending them through:

POST /session/:id/prompt
{"prompt":[{"type":"text","text":"/stats"}]}

So this issue tracks only work that needs a dedicated HTTP/SSE/SDK surface or cannot be represented by POST /session/:id/prompt. Commands that already work through /prompt are not treated as missing capabilities unless there is a concrete downstream need for typed JSON, download semantics, SDK helpers, or event echoes.

Baseline refreshed: main (fa684552b, 2026-06-12). Cross-checked against command supportedModes, GET /session/:id/supported-commands, current docs, and the current merged PR set.

Rating scale

  • Importance: ⭐⭐⭐⭐⭐ blocks serious downstream use · ⭐ nice-to-have
  • Difficulty: S (<1 PR) · M (2-4 PRs) · L (one wave) · XL (cross-quarter)

Already shipped / already covered

Item Status Notes
Permission scope -> per-session Shipped: #4232 + #4335 POST /session/:id/permission/:requestId route + MultiClientPermissionMediator owns per-session pending state. Legacy POST /permission/:requestId kept for back-compat.
/capabilities.protocolVersions Shipped: #4191 getServeProtocolVersions() is in the capabilities envelope.
Replay ring configurable Shipped: #4237 --event-ring-size <n> plus slow_client_warning hysteresis backpressure.
Cross-client mutation event echo (partial) Shipped: #4484 Closed 5 of 8 audit gaps. Follow-up cleanup shipped in #4510.
Daemon-stamped client identity (partial) Shipped: #4231 X-Qwen-Client-Id stamping + audit. Pair tokens + per-client revocation remain open below.
POST /session/:id/{load,resume} stable surface (T2.1) Shipped: #4222 + #4897 Base routes shipped in #4222. #4897 restored cross-session file history snapshots and added the stable session_resume capability tag; legacy unstable_session_resume remains only as a compatibility alias while docs/older clients catch up.
File history snapshot persistence (T2.1 prereq) Shipped: #4897 Main now persists file history snapshots for cross-session /rewind / resume hardening. This replaced the stalled #4253 prerequisite and unblocked stable resume advertising.
Session close + display metadata Shipped: #4240 DELETE /session/:id and PATCH /session/:id/metadata for displayName. This is not arbitrary IM-style KV.
POST /session/:id/recap Shipped: #4504 Dedicated route + SDK helper merged. /recap slash passthrough is not needed.
--allow-origin <pattern> CORS allowlist Shipped: #4527 Boot refuses --allow-origin '*' without a bearer token. Origin: null always rejected.
Prompt absolute deadline + SSE writer idle timeout Shipped: #4530 --prompt-deadline-ms + --writer-idle-timeout-ms flags with env fallbacks. Per-prompt body deadlineMs field. Both off by default.
Cross-client sync follow-up cleanup Shipped: #4510 Epoch-reset resync, approval-mode serialization, catch-up indicator.
In-session model switch bus (A1) Shipped: #4546 /model slash command and plan-mode switch publish model_switched over extNotification side-channel. Covers the "in-session ACP setModel bus emit" part of T2.7-followups.
Runtime MCP server add/remove Shipped: #4552 POST /workspace/mcp/servers (add) + DELETE /workspace/mcp/servers/:name (remove). ACP hot-reload for MCPClient lifecycle, cross-client workspace_mcp_servers_changed event echo.
ACP Streamable HTTP transport Shipped: #4472 ACP Streamable HTTP transport at /acp per RFD #721.
Non-blocking POST /prompt Shipped: #4585 POST /session/:id/prompt returns 202 with promptId for non-blocking semantics.
Session tasks snapshot Shipped: #4578 Dedicated tasks snapshot endpoint. Upgrades background tasks from slash-command-only to structured API.
Server-side shell execution Shipped: #4576 ! (bang) prefix for server-side shell command execution via daemon.
Context-usage API Shipped: #4573 Context-usage API endpoint + daemon-react-sdk refactor + dialog UX.
POST /session/:id/btw side questions Shipped: #4610 Dedicated endpoint for side questions within an active session.
Request-level logging for serve routes Shipped: #4606 Structured per-request logging for all serve routes.
Daemon file logger Shipped: #4559 File-based logging for daemon process.
Web-shell memory commands ACP mode Shipped: #4819 (re-target of #4811) /remember, /forget, /dream enabled in ACP mode via supportedModes declaration + argumentHint for command palette.
Web-shell /tasks command Shipped: #4578 Session tasks snapshot endpoint + web-shell local handler (handleTasksSlashCommand).
Per-request ACP _meta Covered by POST /session/:id/prompt Prompt requests already accept and forward ACP _meta. A separate session-level KV store is optional unless a concrete channel adapter needs daemon-owned metadata.
Manual compaction Covered by /prompt -> /compress /compress supports ACP. A dedicated route is optional structured API polish, not a missing base capability. #4516 was closed on that basis.
Session stats Covered by /prompt -> /stats /stats, /stats model, /stats tools support ACP. #4515 was closed because structured JSON/SDK helpers are optional convenience.
Session export Covered by /prompt -> /export /export md/html/json/jsonl supports ACP. #4515 was closed because download/SDK helpers are optional convenience.
Project summary Covered by /prompt -> /summary /summary supports ACP and saves .qwen/PROJECT_SUMMARY.md. Dedicated GET /summary is not needed unless a structured endpoint is explicitly requested.
/rewind HTTP endpoints Shipped: #4820 GET /session/:id/rewind/snapshots + POST /session/:id/rewind. Conversation + file rewind over HTTP with session_rewound SSE event, SDK helpers, SessionBusyError / InvalidRewindTargetError typed errors.
Web-shell /directory command ACP mode Shipped: #4826 /directory show + /directory add enabled in ACP mode. Refactored from addItem to MessageActionReturn, partial-success warning messageType, gemini.addDirectoryContext() try-catch, argumentHint for command palette.
Hooks diagnostic HTTP/ACP surface Shipped: #4822 GET /workspace/hooks + GET /session/:id/hooks endpoints, SDK helpers, capability tags, ACP mode for /hooks command.
Extensions diagnostic HTTP/ACP surface Shipped: #4832 GET /workspace/extensions endpoint, SDK workspaceExtensions() helper, workspace_extensions capability tag, ACP extMethod, /extensions list in ACP/non-interactive mode.
Load-test harness (T3.4 partial) Shipped: #4862 Mock-ACP connection stress test (5 scenarios), shared perf harness refactoring (_daemon-benchmark-helpers.ts, _daemon-perf-report.ts), vitest.loadtest.config.ts. Gated by QWEN_LOADTEST_ENABLED=1.
MCP transport pool (T3.7) Shipped: #4336 + #4490 McpTransportPool with SHA-256 config fingerprint dedup, per-entry refcounting, drain timers, SessionMcpView per-session tool/prompt filtering, WorkspaceMcpBudget workspace-scoped budget. Merged to main via daemon batch #4490; mcp_workspace_pool is advertised when the pool is active.
POST /session/:id/branch (T3.1) Shipped: #4812 Session fork HTTP route with resume semantics, promptQueue serialization, session_branched SSE event, SDK branchSession() helper, BranchWhilePromptActiveError → 409, title-length enforcement.
/settings, /hooks, /extensions HTTP surface (T3.9) Shipped: #4816 + #4822 + #4832 /settings slash command + workspace_settings capability tag. /hooks + /extensions diagnostic endpoints. All three sub-items complete.
/auth command ACP mode Covered: #4827 + #4490 Already declares supportedModes: ['interactive', 'non_interactive', 'acp']. Auth device-flow _qwen/* methods for REST parity shipped in #4827 and reached main via #4490.
/goal command ACP mode Covered: #4273 + #4314 Already declares supportedModes: ['interactive', 'non_interactive', 'acp']. Goal stream events + non-interactive goals shipped.
Per-tier HTTP rate limiting (T3.4) Shipped: #4861 --rate-limit opt-in flag with token bucket (continuous drip). Three tiers: prompt (10/min), mutation (30/min), read (120/min). Health/heartbeat/SSE/ACP exempt. Fail-open at 10k bucket cap. rate_limit conditional capability tag. onError callback for observability. Typed setRateLimiter/getRateLimiter accessors. Shutdown setDraining + dispose.
/language, /doctor, /diff Covered by /prompt These declare ACP/non-interactive support, so they should not be listed as "not on the wire".

Closed as optional after re-triage

PR Original scope Reason closed
#4515 GET /session/:id/stats + GET /session/:id/export Base behavior already works through /prompt slash passthrough. Reopen only if a client needs typed JSON or browser-download-friendly export.
#4516 POST /session/:id/compress + POST/GET /session/:id/_meta /compress already works through /prompt. Session-level _meta is conditional product work: per-request ACP _meta already exists, and daemon-owned session KV should wait for a concrete channel-adapter need and a decision on whether/how it affects subsequent prompts.
N/A /restore over HTTP Dropped / superseded by /session/:id/rewind (#4820). Remote rollback is already covered over HTTP; the remaining /restore-specific behavior is interactive pending tool-call replay, which should stay TUI-only unless a concrete remote client needs daemon-side tool replay semantics.

In flight - do not duplicate

No active duplicate-avoidance rows right now. #4897 replaced the stalled #4253 file-history snapshot prerequisite for T2.1.


Tier 1 - actual must-do gaps

No Tier 1 rows after the 2026-05-31 re-triage. Previously listed S-sized rows are either shipped, already covered by slash-command passthrough, or conditional product work.

Tier 2 - should-do gaps

# Gap Importance Difficulty Notes
T2.1 loadSession / resume over HTTP graduated from unstable_ ⭐⭐⭐⭐⭐ M-L Shipped: #4897 added the stable session_resume capability tag and closed the file-history snapshot persistence blocker. unstable_session_resume remains as a backwards-compatible alias, not an active gap.
T2.2 Pair tokens + per-client revocation ⭐⭐⭐⭐ L Builds on #4231 identity stamping. Needed only for direct multi-client-to-daemon auth where BFF-style token mediation is not enough. Requires token store, revocation infra, audit, and security review.

Tier 3 - real but deferred / product-decision gaps

# Gap Importance Difficulty Notes
T3.1 POST /session/:id/branch (fork a session) ⭐⭐⭐ M Shipped: #4812. Session fork HTTP route with resume semantics, promptQueue serialization, session_branched SSE event, SDK branchSession() helper.
T3.2 /restore over HTTP ⭐⭐⭐ M-L Dropped / superseded by /session/:id/rewind (#4820). Remote rollback is already covered; the only remaining /restore-specific behavior is interactive pending tool-call replay, which is not worth exposing over HTTP without a concrete remote-client need.
T3.3 --max-body-size flag ⭐⭐ S Becomes urgent only after multimodal / larger upload paths land, or enterprise hardening wants a smaller cap.
T3.4 Rate limiting + observability + load-test harness ⭐⭐ L Shipped: rate limiting #4861 (per-tier token bucket, --rate-limit opt-in) + load-test harness #4862 (mock-ACP connection stress test, 5 scenarios). Observability: #4606 (request-level logging) + #4559 (daemon file logger).
T3.5 Containerized deployment templates ⭐⭐ S-M Docker / Compose / k8s / nginx docs and templates; gated on an enterprise pilot validating them.
T3.6 Auto-generated daemon tokens + token store ⭐⭐ M Pair with T2.2 client identity / revocation work if direct multi-client auth becomes a target.
T3.7 MCP server children refcounted by (workspace, config-hash) ⭐⭐ M Shipped to main via #4490 after #4336 / daemon batch work: McpTransportPool with SHA-256 fingerprint dedup, per-entry refcounting (refs: Set<sessionId>), drain timers, SessionMcpView per-session projection, WorkspaceMcpBudget, and mcp_workspace_pool capability advertising.
T3.8 Session-level arbitrary metadata KV (/_meta) S Conditional. Do only if a concrete channel adapter wants daemon-owned chat/thread/sender metadata. Per-request prompt _meta already exists, and a session KV route needs a product decision on whether/how it is injected into later prompts.
T3.9 /extensions, /settings, /hooks HTTP surface M All shipped. /settings: #4816. /hooks: #4822. /extensions: #4832.
T3.10 Web-shell slash command gap: /permissions ⭐⭐ S Covered by #4816 settings API. /permissions rule CRUD maps to permissions.allow/ask/deny arrays in settings.json — once #4816 ships, web-shell can read/write these via GET/POST /workspace/settings. Dedicated sub-commands (/permissions list/add/remove) deferred unless a concrete need for rule validation + source annotation arises beyond what settings API provides. /directory shipped: #4826. /auth + /goal already declare ACP support.
T3.11 Multi-daemon cross-host coordination XL Outside current single-daemon architectural boundary.

Explicitly not tracked here

These are either TUI-local UX, already ACP-compatible slash commands, or optional convenience endpoints rather than missing daemon capabilities.

Item Why not tracked as a required gap
/summary, /stats, /export, /compress, /language, /doctor, /diff Already callable by POST /session/:id/prompt as ACP-compatible slash commands. Add dedicated routes only if a client explicitly needs typed JSON, download semantics, SDK helpers, or SSE event echoes.
/restore over HTTP Dropped in favor of /session/:id/rewind for remote rollback. The TUI-only /restore flow also replays a pending tool call, and daemon-side tool replay should not be added without a concrete remote client and explicit permission/event semantics.
POST/GET /session/:id/_meta Not required without a concrete channel-adapter consumer. POST /session/:id/prompt already supports per-request ACP _meta; daemon-owned session KV is optional product work.
/vim, /editor, /theme, /statusline, /terminal-setup, /ide, /lsp, /memory, /mcp, /agents, /tools, /approval-mode slash UX Mostly TUI-local dialogs/settings or already covered by more specific HTTP routes/backlog rows. Do not add broad "mirror the TUI" routes without a concrete client need.
/arena Deeply interactive (tmux, terminal sizing, dialogs). Not feasible in ACP/web-shell without major redesign.
/trust Returns dialog; trust concept in ACP is managed at operator level, not end-user.
Multimodal prompt path, multipart/form-data uploads, containerized deploy, multi-daemon cross-host coordination Known limits outside the current Stage 1.5 backlog unless a pilot commits to validate the design.

Recommended next pulls after current open PRs

  1. T2.2 pair tokens + per-client revocation — security-sensitive Stage 1 → 1.5 gate; plan a full review cycle only if direct multi-client daemon auth remains a target.
  2. T3.6 auto-generated daemon tokens + token store — should be designed with T2.2 rather than as a separate one-off token path.

How to use this issue

  • Pull only rows from the actual gap tables above.
  • Do not open duplicate PRs for rows already listed in In flight.
  • If a requested feature can be invoked via /prompt slash passthrough, first decide whether the client truly needs a structured HTTP/SDK surface. If not, document the passthrough usage instead of adding a route.
  • If a requested feature is only useful for a specific downstream client, link that consumer or pilot before promoting it above Tier 3.
  • When a row ships, move it to Already shipped / already covered with the merged PR link.

🤖 Generated with Qwen Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions