qwen-code/docs/developers/daemon/17-configuration.md
Shaojin Wen 407cf0a7f8
feat(serve): adaptively grow live-journal caps before truncating mid-turn replay (#8905)
* feat(serve): adaptively grow live-journal caps before truncating mid-turn replay

A single turn fanning out many concurrent subagents (e.g. a /review run) can emit hundreds of thousands of source events, far past the per-session live-journal baseline caps (10 000 entries / 8 MiB), so a mid-turn (re)load silently shows a truncated replay until the turn finishes. Before evicting, the engine now asks a growth advisor: caps double (entries scaled proportionally) while the growth granted across the bridge's live sessions fits in a pool derived from the daemon memory budget (5%, clamped to [32, 1024] MB), never past a per-session hard cap of 256 MiB. Growth is on demand, throttled after a refusal, and accounted statelessly from the current caps of all live sessions, so granted headroom dies with its session. An operator-pinned --max-journal-events/--max-journal-bytes disables growth; without a pool the fixed-cap eviction behavior is unchanged.

* fix(serve): address adaptive live-journal growth review feedback (#8905)

* fix(serve): account in-flight restores in the journal growth pool (#8905)

Concurrent restores hold their buses in pendingRestoreEvents rather than
byId, so each advisor ask only saw its own caps and concurrent restores
could each draw a full doubling from the same pool. Sum the current caps
of every in-flight restore bus into allSessionLimitBytes.

Also skip the growth ask when the breaching append is a turn boundary —
compactCurrentTurn discards the journal immediately afterwards, so the
grant would be charged to the pool while buying zero eviction.

Pin the previously untested contracts with tests: restore-window
accounting, concurrent-restore accounting, headroom release on session
close, the hard-cap clamp term, partial-grant eviction, requester
discrimination in the policy fixtures, the maxEvents safe-integer
conjunct, and the dynamic-workspace bridge pool wiring. Fix the docs:
add the missing journal-flag rows to the daemon configuration and
operations pages, and correct the effective-budget definition.

* test(serve): request 'response' replay in the transport-failure test (#8905)

The merge of main pulled in #8933, which gates historyPageSize on
historyReplay === 'response'. The 'transport failure marks the channel
dying before process exit' test (from #8947) passes historyPageSize with
the default stream replay, so the paged transcript fetch it waits on is
never issued and the test times out — a cross-PR interaction between two
main commits, failing deterministically on main. Pin the response replay
mode the paged fetch requires.

* fix(serve): share one daemon-wide journal growth pool (#8905)

Address the automated review of adaptive live-journal growth:

- The growth pool is now one daemon-wide aggregate shared by every
  workspace bridge instead of a full pool per bridge, and growth is
  disabled when the budget is insufficient or leaves no headroom after
  the root reserve.
- Grants that cannot retain any additional journal entries (an oversized
  event survives as the sole entry either way) are refused so the pool
  is never charged for growth that preserves no replay.
- The refusal throttle defaults to a monotonic clock and treats a
  backward clock jump as an elapsed window.
- The proportional event hard cap is clamped to MAX_SAFE_INTEGER so a
  valid-but-extreme baseline cannot poison every grant.
- /daemon/status reports the growth semantics: limits.memory.journalGrowth
  (pool size, hard cap, baselines), per-session effective caps in full
  diagnostics, and enforced:false scoped to the child-heap model.
- Validation-boundary tests for the growth-pool normalizer and doc fixes
  (positive safe integer types; growth toward double, limited by pool
  headroom).

* fix(serve): align growth-pool docs and harden growth tests (#8905)

* fix(serve): account growth per session baseline and walk intermediate grants (#8905)

* fix(serve): harden growth-pool tests and derive help figures from constants (#8905)

* fix(serve): reject valueless journal cap flags and harden growth tests (#8905)

---------

Co-authored-by: qwen-code-ci-bot <qwen-code-ci@service.alibaba.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
2026-08-13 11:35:39 +00:00

181 lines
58 KiB
Markdown

# Configuration Reference
## Overview
This page collects every setting that affects the `qwen serve` daemon and its adapters: environment variables, CLI flags, `settings.json` keys, and programmatic options. Feature-specific pages link back here when they need cross-cutting configuration details.
## CLI flags (`qwen serve`)
| Flag | Type | Default | Effect |
| --------------------------------------- | ---------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--hostname <host>` | string | `127.0.0.1` | Bind address. Loopback values: `127.0.0.1`, `localhost`, `::1`, `[::1]`. Non-loopback requires a bearer token at boot. `host:port` input is rejected with guidance to use `--port`. |
| `--port <n>` | number | `4170` | Listen port; `0` means ephemeral. |
| `--token <s>` | string | env | Bearer token. Overrides `QWEN_SERVER_TOKEN` and is trimmed at boot. It appears in the process command line, so prefer env in deployments. |
| `--require-auth` | boolean | `false` | Extends bearer auth to loopback and `/health`; boot refuses to start without a token. |
| `--workspace <dir>` | absolute path / repeatable | `process.cwd()` | Startup workspace runtime; repeat to register additional isolated runtimes. The first is primary. Every value must be absolute and a directory; canonicalized at boot. |
| `--memory-project-scope <mode>` | `git-root` / `workspace` | `workspace` | Project-memory partitioning. `workspace` isolates by exact workspace directory; `git-root` is the legacy compatibility scope shared by workspaces at the same Git root. Overrides `QWEN_CODE_MEMORY_PROJECT_SCOPE`. |
| `--max-sessions <n>` | number | `32` | Per-workspace active session cap. `0` / `Infinity` means unlimited; `NaN` / negative values throw. |
| `--max-total-sessions <n>` | number | derived for multiple startup/restored workspaces | Daemon-wide active session cap. When omitted, a finite default is derived once from the per-workspace cap and startup/restored workspace count. `0` / `Infinity` means unlimited. |
| `--max-pending-prompts-per-session <n>` | number | `5` | Accepted but pending/running prompt cap per session. Excess prompt returns 503. `0` / `Infinity` means unlimited; negative or non-integer values throw. |
| `--max-connections <n>` | number | `256` | HTTP listener `server.maxConnections`; `0` / `Infinity` means unlimited. |
| `--enable-session-shell` | boolean | `false` | Enables direct `POST /session/:id/shell` execution. Requires bearer token, and every call must carry a session-bound `X-Qwen-Client-Id`. |
| `--event-ring-size <n>` | number | `8000` | Per-session SSE replay ring; soft cap is `1_000_000`. |
| `--compacted-replay-max-bytes <n>` | positive integer | `4194304` | Byte cap for the bounded in-memory replay snapshot returned by `POST /session/:id/load`; hard cap is `268435456`. |
| `--max-journal-events <n>` | positive safe integer | `10000` | Per-session baseline cap on in-flight `liveJournal` replay entries for the unfinished turn. Adaptive growth can raise it (see `--max-journal-bytes`); pinning either journal flag disables growth. |
| `--max-journal-bytes <n>` | positive safe integer | `8388608` (8 MiB) | Per-session baseline byte cap on the in-flight `liveJournal`. When a turn breaches it, adaptive growth raises the session's caps on demand, toward double but limited by the remaining pool headroom and never past a 256 MiB per-session hard cap — within one daemon-wide pool of 5% of the effective `--memory-budget-mb` (capped at `1024` MB; 0 — growth disabled — when the effective budget is below the 1024 MB minimum), shared by every workspace bridge; without headroom the oldest entries are dropped with a `history_truncated` marker. Pinning either journal flag disables growth. |
| `--memory-budget-mb <n>` | integer in `[1024, 1048576]` | 50% of cgroup-constrained or host memory, capped at the flag maximum (1048576 MB) | Total memory budget for the daemon process tree, capped at resolved available memory. Reported under `limits.memory` in daemon status; it does not size any child process — the one consumer today is adaptive live-journal growth (see `--max-journal-bytes`). Boot rejects out-of-range values. |
| `--memory-pressure-mode <mode>` | `off` \| `observe` | `observe` | Whether the daemon derives a memory-pressure level from its own RSS and V8 heap. Both modes report `runtime.memory.pressure`; only `observe` raises `daemon_memory_pressure`. Root process only; no remediation. |
| `--child-heap-mode <mode>` | `off` \| `observe` | `observe` | Whether the daemon models a per-child heap partition of the budget. `observe` reports it and counts spawns past it; nothing is applied. `off` publishes no partition at all — `maxConcurrentChildren` and `perChildCeilingMb` are both `null`. |
| `--http-bridge` | boolean | `true` | Stage 1 bridge mode. `--no-http-bridge` still falls back to http-bridge and prints to stderr. |
| `--mcp-client-budget <n>` | positive integer | unset | Sets `WorkspaceMcpBudget.clientBudget` and forwards it to the ACP child through `childEnvOverrides`. |
| `--mcp-budget-mode <m>` | `off` / `warn` / `enforce` | `warn` when budget is set, otherwise `off` | Sets `WorkspaceMcpBudget.mode`; `enforce` requires `--mcp-client-budget`. |
| `--external-tool-guard-mode <m>` | `off` / `required` | `off` | Enables the managed ACP external pre-execution Guard. `required` fails startup unless its loopback provider completes the v1 handshake. |
| `--external-tool-guard-endpoint <url>` | loopback HTTP(S) origin | unset | Provider origin used only in `required` mode. It must be origin-only and use `127.0.0.1`, `localhost`, or `::1`; paths, credentials, redirects, and proxy routing are rejected. |
| `--external-tool-guard-timeout-ms <n>` | integer `100..30000` | `3000` | Per-handshake and per-prepare deadline. A timeout fails startup during the handshake or fails the invocation closed during a turn. |
| `--allow-origin <pattern>` | repeatable string | unset | Cross-origin allowlist that replaces the default CORS denial. `*` allows any origin but requires a token. |
| `--allow-private-auth-base-url` | boolean | `false` | Allows `/workspace/auth/provider` to install localhost / private-network auth provider `baseUrl`; use only in trusted local development. |
| `--web` / `--no-web` | boolean | `true` | Serve the built Web Shell SPA at the daemon root (`GET /`, `/assets/*`, and `/session/:id` document navigations). These entry points are mounted before `bearerAuth`; every API route stays token-gated. `--no-web` leaves the daemon API-only. |
| `--prompt-deadline-ms <n>` | positive integer | unset | Server-side prompt wallclock limit in ms. Timeout aborts and returns an error. |
| `--writer-idle-timeout-ms <n>` | positive integer | unset | Per-SSE-connection idle timeout in ms. The daemon closes the SSE connection when no event is sent for this duration. |
| `--channel-idle-timeout-ms <n>` | non-negative integer | `0` | How long to keep the ACP child alive after the last session closes. `0` means reclaim immediately. |
| `--initialize-timeout-ms <n>` | positive integer | `10000` | ACP child request timeout, including the initialize handshake (ms). |
| `--session-restore-timeout-ms <n>` | positive integer | `60000` | ACP session load/resume timeout (ms). When this flag is omitted, an explicitly supplied initialize timeout raises the budget but never lowers it below the default. |
| `--session-reap-interval-ms <n>` | non-negative integer | `60000` | Session reaper scan interval; `0` disables it. |
| `--session-idle-timeout-ms <n>` | non-negative integer | `1800000` | Disconnected-session idle reaping time; `0` disables it. |
| `--rate-limit` / `--no-rate-limit` | boolean | env / off | Enables per-tier HTTP rate limiting for prompt, mutation, and read routes. |
| `--rate-limit-prompt <n>` | positive integer | `10` | Prompt request limit per window; requires rate limiting to be enabled. |
| `--rate-limit-mutation <n>` | positive integer | `30` | Mutation request limit per window; requires rate limiting to be enabled. |
| `--rate-limit-read <n>` | positive integer | `120` | Read request limit per window; requires rate limiting to be enabled. |
| `--rate-limit-window-ms <n>` | integer `>= 1000` | `60000` | Rate limit window length; requires rate limiting to be enabled. |
| no flag | - | - | `QWEN_SERVE_NO_MCP_POOL=1` fully disables the pool. |
## Environment variables
### Read by `runQwenServe` / Express middleware
| Env | Effect |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `QWEN_SERVER_TOKEN` | Bearer token; trimmed at boot. |
| `QWEN_SERVE_DEBUG` | `1` / `true` / `on` / `yes` (case-insensitive) enables verbose stderr logs. See [`19-observability.md`](./19-observability.md). |
| `QWEN_SERVE_NO_MCP_POOL` | `1` disables the workspace MCP transport pool and falls back to per-session `McpClientManager`; capabilities stop advertising `mcp_workspace_pool` / `mcp_pool_restart`. |
| `QWEN_SERVE_PROMPT_DEADLINE_MS` | Env fallback for `--prompt-deadline-ms`. |
| `QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS` | Env fallback for `--writer-idle-timeout-ms`. |
| `QWEN_SERVE_RATE_LIMIT` | `1` / `true` enables per-tier HTTP rate limiting; CLI `--rate-limit` / `--no-rate-limit` wins. |
| `QWEN_SERVE_RATE_LIMIT_PROMPT` | Env fallback for `--rate-limit-prompt`. |
| `QWEN_SERVE_RATE_LIMIT_MUTATION` | Env fallback for `--rate-limit-mutation`. |
| `QWEN_SERVE_RATE_LIMIT_READ` | Env fallback for `--rate-limit-read`. |
| `QWEN_SERVE_RATE_LIMIT_WINDOW_MS` | Env fallback for `--rate-limit-window-ms`. |
| `QWEN_CODE_MEMORY_PROJECT_SCOPE` | `workspace` keys project memory by the exact workspace dir; `git-root` selects the legacy shared scope. When unset, the daemon injects `workspace`; unrecognized values warn once and retain the legacy `git-root` behavior. Propagates via the runtime base env, not `childEnvOverrides`; `--memory-project-scope` wins. Each workspace remember/forget/dream lane caps pending tasks at `MAX_PENDING = 16`; N workspaces allow up to 16·N queued tasks with no daemon-wide cap. |
Blank `QWEN_CODE_MEMORY_PROJECT_SCOPE` values are treated as unset and therefore default to `workspace`; unrecognized non-empty values still warn once and retain the legacy `git-root` behavior.
### Read by the `qwen serve` CLI wrapper
| Env | Effect |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `QWEN_CODE_EXTERNAL_TOOL_GUARD_TOKEN` | Non-blank bearer token of at most 8192 UTF-16 code units without control characters, copied into `ServeOptions.externalToolGuard` only in required mode. The CLI then deletes the ambient value before runtime environments are frozen; ACP children, channel workers, and executor environments also scrub it defensively. |
### Forwarded to the ACP child through `BridgeOptions.childEnvOverrides`
`runQwenServe` builds these per handle so two daemons in one process do not race on `process.env`. The budget variables are not parent-process env fallbacks for `qwen serve`; the CLI path must generate them from `--mcp-client-budget` / `--mcp-budget-mode`.
| Env | Effect |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `QWEN_SERVE_MCP_CLIENT_BUDGET` | Positive integer string consumed by the ACP child's `readBudgetFromEnv()`. |
| `QWEN_SERVE_MCP_BUDGET_MODE` | `off` / `warn` / `enforce`. |
| `QWEN_SERVE_MCP_POOL_TRANSPORTS` | Comma-separated transport allowlist; default pooled transports are `stdio,websocket`; can explicitly include `http,sse`. |
| `QWEN_SERVE_MCP_POOL_DRAIN_MS` | Pool entry idle drain delay; default `30000`, clamped to `1000..600000` ms. |
### Read by SDK / adapters
| Env | Effect |
| ----------------------- | ----------------------------------------------------------------- |
| `QWEN_DAEMON_URL` | Daemon base URL for CLI TUI adapter, channels, and IDE companion. |
| `QWEN_DAEMON_TOKEN` | Bearer token. |
| `QWEN_DAEMON_WORKSPACE` | Overrides the `cwd` sent to `POST /session`. |
## `settings.json` keys
The daemon constructs each workspace runtime from that workspace's merged settings and environment overlay. Process-global listener/auth options are resolved once, while runtime-specific services and ACP children receive the owning runtime snapshot. Malformed settings follow the documented startup fallback or failure behavior for the affected runtime; they must not cause another workspace's settings to be reused.
| Key | Type | Effect |
| --------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `policy.permissionStrategy` | `'first-responder' \| 'designated' \| 'consensus' \| 'local-only'` | Sets `BridgeOptions.permissionPolicy`; the active value appears in `/capabilities` as `policy.permission`. **Boot validates** through `validatePolicyConfig()` against `SERVE_CAPABILITY_REGISTRY.permission_mediation.modes`. Unknown literals throw `InvalidPolicyConfigError` and fail boot explicitly. |
| `policy.consensusQuorum` | positive integer | N for the `consensus` policy. **Default** is `floor(M/2) + 1` over `votersAtIssue.size` (M=2 means unanimous; larger even M means more than half). If set under a non-consensus policy, it is ignored and boot prints a stderr warning. Non-positive integers throw `InvalidPolicyConfigError`. See [`04-permission-mediation.md`](./04-permission-mediation.md). |
| `context.fileName` | string | Overrides `getCurrentGeminiMdFilename()` through `BridgeOptions.contextFilename`. |
| `tools.disabled` | string[] | Tools disabled for the next ACP child spawn. Normalized through `normalizeDisabledToolList()` (`packages/cli/src/config/normalizeDisabledTools.ts`): non-array becomes `[]`, non-string entries are skipped, whitespace is trimmed, empty entries are dropped, and duplicates are removed while preserving first occurrence. Boot and `restartMcpServer` settings refresh both run through this function. `ToolRegistry.has(name)` is exact and case-sensitive. `POST /workspace/tools/:name/enable` and `tool_toggled` update this key. |
| `tools.approvalMode` | `'default' \| 'auto' \| ...` | Default session approval mode; `POST /session/:id/approval-mode` writes here when `persist: true`. |
| `telemetry` | object | OTel config. Keys include `enabled`, `otlpEndpoint`, `otlpProtocol`, `otlpTracesEndpoint`, `otlpLogsEndpoint`, `otlpMetricsEndpoint`, `target`, `outfile`, `userId`, `includeSensitiveSpanAttributes`, `sensitiveSpanAttributeMaxLength`, `resourceAttributes`, and `metrics.includeSessionId`. `resolveTelemetrySettings()` reads it at boot and initializes `initializeTelemetry()`. `userId` is process-wide and must not be configured as end-user identity when the daemon serves multiple users. |
## `ServeOptions` (programmatic embedding)
`packages/cli/src/serve/types.ts` defines the typed options passed through the public serve APIs. It mirrors the CLI flags above and adds:
| Field | Effect |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `eventRingSize` | Overrides the default per-session ring size. |
| `memoryProjectScope` | `runQwenServe` only; precedence is option, launch env, then `workspace`. Direct `createServeApp` callers use `deps.daemonEnv`. |
| `maxPendingPromptsPerSession` | Pending prompt cap per session; `0` / `Infinity` means unlimited. |
| `mcpPoolActive` | Programmatic switch, defaulting from `QWEN_SERVE_NO_MCP_POOL`. |
| `externalToolGuard` | Optional `{mode:'required', endpoint, token, timeoutMs?}`. Omission is fully off; required mode performs the provider handshake before listening. |
| `allowOrigins` | Cross-origin allowlist (`string[]`), corresponding to `--allow-origin`. |
| `allowPrivateAuthBaseUrl` | Allows private / localhost auth provider `baseUrl` installation. |
| `serveWebShell` | Serve the built Web Shell SPA at the daemon root (default `true`); `false` (the CLI's `--no-web`) leaves the daemon API-only. No effect when the build omits the shell assets. |
| `enableSessionShell` | Enables session shell execution; bearer token and session-bound client id are still required. |
| `promptDeadlineMs` | Prompt wallclock limit. |
| `writerIdleTimeoutMs` | SSE writer idle timeout. |
| `channelIdleTimeoutMs` | How long to keep the ACP child warm after the last session closes. |
| `initializeTimeoutMs` | ACP child request timeout, including the initialize handshake. |
| `sessionRestoreTimeoutMs` | ACP session load/resume timeout. Precedence: explicit restore value; otherwise an explicit initialize value raises the 60000 default but never lowers it; otherwise 60000. |
| `sessionReapIntervalMs` | Session reaper scan interval. |
| `sessionIdleTimeoutMs` | Disconnected-session idle reaping time. |
| `rateLimit*` | Per-tier HTTP rate limit switch, thresholds, and window. |
## `BridgeOptions` (programmatic bridge embedding)
`packages/acp-bridge/src/bridgeOptions.ts` defines bridge options. See [`03-acp-bridge.md`](./03-acp-bridge.md) for the full table. Key fields:
| Field | Effect |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `boundWorkspace` | Required canonical workspace. |
| `sessionScope` | `'single'` (default) vs `'thread'`. |
| `initializeTimeoutMs`, `sessionRestoreTimeoutMs`, `maxSessions`, `eventRingSize`, `permissionResponseTimeoutMs`, `maxPendingPermissionsPerSession` | Bounded resource caps. |
| `channelFactory` | Pluggable ACP child factory; default is `defaultSpawnChannelFactory`. |
| `fileSystem` | `BridgeFileSystem` adapter. See [`07-workspace-filesystem.md`](./07-workspace-filesystem.md). |
| `permissionPolicy`, `permissionConsensusQuorum`, `permissionAudit` | Mediator wiring. |
| `statusProvider` | Daemon-host preflight cells. |
| `childEnvOverrides` | Per-handle environment additions or removals. |
| `externalToolGuard` | Optional daemon-side handler for the private child-to-parent prepare RPC. The bridge validates channel ownership and the active Prompt before and after it calls the handler. |
| `contextFilename` | Overrides `getCurrentGeminiMdFilename()`. |
| `channelIdleTimeoutMs` | How long to keep the ACP child alive after the last session closes, in ms; default `0`. |
## Important defaults
| Constant | File | Value | Meaning |
| --------------------------------- | ----------------------- | ----------------- | ------------------------------------------------------------------------------------ |
| `DEFAULT_MAX_SESSIONS` | `bridge.ts` | `32` | Session cap before `SessionLimitExceededError`. |
| `MAX_EVENT_RING_SIZE` | `bridge.ts` | `1_000_000` | Soft cap for `BridgeOptions.eventRingSize`; guards against typos. |
| `DEFAULT_RING_SIZE` | `eventBus.ts` | `8000` | Per-session SSE replay ring depth. |
| `DEFAULT_MAX_QUEUED` | `eventBus.ts` | `256` | Per-subscriber queue cap. |
| `DEFAULT_MAX_SUBSCRIBERS` | `eventBus.ts` | `64` | Per-bus subscriber cap. |
| `WARN_THRESHOLD_RATIO` | `eventBus.ts` | `0.75` | `slow_client_warning` trigger. |
| `WARN_RESET_RATIO` | `eventBus.ts` | `0.375` | Hysteresis re-arm threshold. |
| `DEFAULT_INIT_TIMEOUT_MS` | `bridge.ts` | `10_000` | ACP `initialize` handshake timeout. |
| `MCP_RESTART_TIMEOUT_MS` | `bridge.ts` | `300_000` | Bridge timeout for `/workspace/mcp/:server/restart`. |
| `DEFAULT_PERMISSION_TIMEOUT_MS` | `bridge.ts` | `5 * 60_000` | Per-permission request wallclock. |
| `DEFAULT_MAX_PENDING_PER_SESSION` | `bridge.ts` | `64` | Aligned with `DEFAULT_MAX_SUBSCRIBERS`. |
| `MAX_RESOLVED_PERMISSION_RECORDS` | `permissionMediator.ts` | `512` | FIFO for recently resolved permissions. |
| `KILL_HARD_DEADLINE_MS` | `spawnChannel.ts` | `10_000` | Per-channel graceful shutdown window. |
| `SHUTDOWN_FORCE_CLOSE_MS` | `run-qwen-serve.ts` | `5_000` | HTTP server force-close timer. |
| `MAX_READ_BYTES` | `fs/policy.ts` | `256 * 1024` | Full-snapshot and returned-text cap; larger UTF-8 text requires a finite line limit. |
| `MAX_WRITE_BYTES` | `fs/policy.ts` | `5 * 1024 * 1024` | Write cap. |
| `MAX_DISPLAY_NAME_LENGTH` | `bridge.ts` | `256` | Session `displayName` cap. |
## Cross-references
- Auth settings: [`12-auth-security.md`](./12-auth-security.md)
- Capabilities and protocol version: [`11-capabilities-versioning.md`](./11-capabilities-versioning.md)
- Event ring and backpressure tuning: [`10-event-bus.md`](./10-event-bus.md)
- MCP pool / budget: [`05-mcp-transport-pool.md`](./05-mcp-transport-pool.md) and [`06-mcp-budget-guardrails.md`](./06-mcp-budget-guardrails.md)
- Permission policy: [`04-permission-mediation.md`](./04-permission-mediation.md)
- User operations guide: [`../../users/qwen-serve.md`](../../users/qwen-serve.md)