DSH / Atlas
2026-08-11implementedarchitecture

Repository naming contract and pre-release rename ledger

仓库命名约定与预发布重命名清单

The repository had grown faster than some names. Several package names described the first implementation instead of the capability. Several classes used `Service` even when they were registries, runtimes, engines, controllers, or resolvers. Some `ctx` keys were singular for registries and plural for one engine. Some provider names said `local` even though they used replaceable filesystem or subprocess services and c

English

Problem

The repository had grown faster than some names. Several package names described the first implementation instead of the capability. Several classes used Service even when they were registries, runtimes, engines, controllers, or resolvers. Some ctx keys were singular for registries and plural for one engine. Some provider names said local even though they used replaceable filesystem or subprocess services and could run in another execution world.

These names are not harmless. A name tells a contributor where a responsibility starts and stops. Store suggests data access. Registry suggests registrations and lookup. Runtime suggests live execution and lifecycle. When one word is used for all three, callers cannot tell which object owns policy, work, or state without reading the implementation.

The repository also used SDK in two meanings. The supported Python and TypeScript clients use the JSON-RPC SDK protocol. The project as a whole is DeepSeek Harness, not an SDK project. The removed SDK project toolchain made the broad meaning obsolete, but prose and names preserved parts of it.

The last pre-release window made repository-wide renames cheap. Keeping weak names would have turned accidental vocabulary into a compatibility contract.

Decision

The repository uses every current name in this ledger. This decision changes names only; package responsibilities, service boundaries, behavior, defaults, and data models stay the same. A name that exposes a bad boundary requires a separate proposed Agent Note for that boundary change.

Each renamed family has one vocabulary. Its directory, npm package name, imports, Cordis plugin name, ctx key, public types, directly coupled event or tool identifiers, configuration, tests, fixtures, examples, generated references, and current documentation use the current name where the ledger names those interfaces. No alias, compatibility package, duplicate service key, dual event name, or fallback parser remains. The repository rejects the old name.

No family exposes two public vocabularies.

Use SDK for one thing

SDK means the JSON-RPC-based client/server protocol used by the supported Python and TypeScript SDKs. The repository keeps @deepseek-ai/dsh-sdk-client, @deepseek-ai/dsh-sdk-protocol, and the wire identity deepseek-harness-sdk-runtime; the JSON-RPC server belongs to the same family. DeepSeek Harness itself is not an SDK, and the removed project generator, launcher, helper, and launcher telemetry packages stay absent.

This decision partially supersedes three active decisions. It replaces the retained bash/, pty/, and self-modification/ group names and both deferred package targets in the package-regrouping decision. It replaces only the repository-wide SDK claim in the SDK project toolchain removal, which remains the owner of the deletion and the surviving runtime SDK. It replaces only the package-name rationale in the tool-call timeout policy; the timeout mechanism and its guard/timeout-policy/ home remain unchanged.

Other implemented notes that use a renamed package, path, or type are not superseded when their boundary and rationale remain intact. They carry the current factual names. The three partially superseded decisions link back to this decision.

Name the role that exists

Use a common, concrete noun. Name the stable responsibility, not the first implementation, the current folder, or a possible future expansion. Do not add a word that carries no information. Do not shorten a name by deleting the word that distinguishes its scope.

An interface package names the capability. An implementation package adds the mechanism, protocol, environment, or vendor that distinguishes that implementation. Use local only when same-host execution is part of the contract. Do not use it for a provider that happens to read local-looking paths through replaceable ctx.fs or starts work through replaceable ctx.subprocess.

Use a singular ctx key for one engine, runtime, policy, controller, resolver, store, or current configuration. Use a plural key for a registry or a service that owns multiple named members. The class role and key number must agree. A plural key does not by itself make an object a registry; its operations and ownership do. Do not reuse one Cordis Context key for incompatible host and client declarations. TypeScript declaration merging sees both faces even when they use separate runtime contexts. Add the role suffix when the natural plural already belongs to another face.

Use Service only when no sharper role is honest. GoalService and SessionTitleService are valid retained names because each owns a domain service whose work is not accurately reduced to storage, registration, or one execution mechanism.

Role words are contracts

WordUse it whenDo not use it when
ControllerThe object accepts commands or user intent and changes one existing domain or presentation state. It coordinates a bounded state transition.The object executes arbitrary work, owns a provider fleet, or only converts values for display.
StoreThe object owns one data set and mainly provides create, read, update, delete, snapshot, or subscription operations for that data.It validates a state machine, arbitrates authority, dispatches work, owns provider precedence, or coordinates several domains. A map inside a class does not make the class a store.
DirectoryThe object exposes entries for discovery or selection. Its consumer asks what choices exist and reads their metadata.Producers register arbitrary implementations into it, or callers execute work through it. A directory can be backed by a registry, but the two faces are not the same.
PresenterThe object is a pure conversion from domain values or tool arguments to render intent. It has no I/O, subscription, mutation, or lifecycle ownership.It reads services, changes state, or controls when work runs. Those jobs belong to a controller or runtime.
RegistryThe object owns a dynamic set of named registrations. It defines lookup, duplicate or precedence rules, registration lifetime, and disposal.The main caller contract is dispatch, execution, cancellation, policy enforcement, or orchestration. A runtime can contain a registry as an internal part.
RuntimeThe object runs live work. It owns dispatch, cancellation, provider coordination, or operation lifecycle across calls.The object only stores records, returns a catalog, resolves one value, or holds configuration. Runtime is not a generic replacement for Service.
ResolverThe object computes or locates one answer from supplied inputs, usually without owning the answer's lifecycle.It owns a mutable collection or a long-running execution lifecycle.
BinderThe object attaches one declared interface to the caller's context or lifecycle and returns the bound value.It owns the bound value as a collection, controls its domain state, or merely converts data.
EngineThe object implements a domain algorithm or stateful execution model, such as workflow, compaction, or query evaluation.It only selects a provider or forwards a request across a protocol boundary.
PolicyThe object decides what is allowed, selected, limited, or observed.It performs the mechanism that the decision permits. Keep policy and executor names separate.
ExecutorThe object runs an explicit request or resolved specification in one capability.It owns a broad application lifecycle or a catalog of providers.
GatewayThe object adapts a process, network, RPC, or API boundary and translates between the two sides.It only registers same-process services or stores metadata.
ProviderThe object supplies one implementation of a capability definition. Add a mechanism or vendor qualifier when more than one provider can exist.It is the capability definition, the registry of providers, or the consumer-facing runtime.
BackendThe object implements a replaceable lower-level persistence, transport, or execution backend behind a defined interface.It is a user-facing service or only a returned reference to one live object.
HandleThe value is a reference to one live resource and controls or observes that resource.The object creates and manages the whole resource pool. Do not use Owner or the vague Resource when Handle or a sharper manager role fits.
ConfigThe object owns one resolved configuration value or one tightly bounded configuration record and its update contract.It stores a general collection, executes work, or exposes unrelated settings.
ServiceThe object owns a cohesive domain service whose authority cannot be stated honestly as one of the sharper roles above.The name is used only because the class extends Cordis Service, or because choosing the real role takes more thought.

The practical tests are direct. If callers mainly call register() and receive a disposer, use Registry. If callers mainly call run(), dispatch(), cancel(), or execute(), use Runtime, Engine, or Executor. If callers mainly browse choices, use Directory. If an object mainly binds one specification to caller-owned context and lifetime, use Binder. If the object only maps domain data to UI data, use Presenter. If it also changes state, it is not a presenter.

Use qualifiers that add information

Keep a protocol or dialect name when it distinguishes implementations. Keep Bash, Pwsh, JSON-RPC, SQLite, JSONL, OpenTelemetry, Claude Code, and E2B where the implementation depends on that mechanism. Do not put LLM into a compaction backend name when every current backend already uses the LLM seam; basic is the honest neutral name until a more specific algorithm name exists.

Do not invent a process sandbox concept. The current sandbox family already names its product responsibility. This decision does not change that responsibility.

Use title case for initialisms inside PascalCase identifiers: Ui, Llm, JsonRpc, and ApiProxy. Use the conventional uppercase form in prose and package names where applicable: UI, LLM, JSON-RPC, and API. Typert is the exact product spelling in identifiers and prose; do not write TypeRT, TypeRt, or Typert with another internal split.

Do not remove an intentional vendor qualifier to avoid repetition. dsh-subagent-dsh-sdk names the DeepSeek Harness SDK provider and avoids confusion with another SDK. Its private class becomes SdkSubagentProvider because the class also needs to say what it provides.

Put the rule in project documentation

The paired package-creation guide at docs/cookbook/adding-a-package.md contains the full role-word contract, and packages/AGENTS.md links to it. The terminology table and root project description give SDK and Typert one meaning. This Agent Note owns the rationale and rejected alternatives; the guide owns the rule contributors follow.

Rename ledger

The tables record public and repository-wide renames. The Current column holds the current name. Private local variables use the same vocabulary when they refer to the same role. A retained low-level or product-visible name is stated where a broad replacement would be wrong.

Runtime SDK

FormerCurrentReason
@deepseek-ai/dsh-jsonrpc@deepseek-ai/dsh-sdk-jsonrpc-serverIt is the server half of the SDK protocol. jsonrpc alone names an encoding; sdk-jsonrpc-server gives the family, mechanism, and role.
HarnessSdkServerHarnessSdkJsonRpcServerThe class is one JSON-RPC server implementation, not every possible SDK server.

Keep @deepseek-ai/dsh-sdk-client, @deepseek-ai/dsh-sdk-protocol, and deepseek-harness-sdk-runtime. Exclude @deepseek-ai/create-sdk, @deepseek-ai/dsh-scripts, @deepseek-ai/dsh-helper, and @deepseek-ai/dsh-telemetry; the separate removal decision deletes them and their support graph.

Shell and terminal

FormerCurrentReason
packages/bash/packages/shell/The group contains the dialect-neutral executor seam, Bash and PowerShell implementations, environment support, and shell tools.
@deepseek-ai/dsh-bash, ctx.bash@deepseek-ai/dsh-shell, ctx.shellPowerShell already implements this seam. The capability is shell execution, not Bash.
Dialect-neutral BashExecutor, BashExecRequest, BashExecSpec, BashProcess, BashRunResult, BashSandboxInfo, BashProcessRead, and BashProcessStatus namesCorresponding Shell* namesThese types cross both Bash and PowerShell implementations. Leaf types that describe Bash syntax or behavior keep Bash.
BASH_SETTINGS_NAMESPACE, settings namespace bashSHELL_SETTINGS_NAMESPACE, settings namespace shellBoth shell providers register this capability-owned settings section. The constant and durable namespace must use the capability name.
@deepseek-ai/dsh-bash-env, ctx.bashEnv, BashEnvRegistry@deepseek-ai/dsh-shell-env, ctx.shellEnv, ShellEnvRegistryThe environment registry is shared by Bash and PowerShell tools.
docs/subsystems/bash.mddocs/subsystems/shell.mdThe subsystem page documents the dialect-neutral capability.
packages/pty/packages/terminal/The package family owns persistent terminal sessions. Raw PTY allocation remains in the subprocess layer.
@deepseek-ai/dsh-pty, ctx.pty, PtyService@deepseek-ai/dsh-terminal, ctx.terminals, TerminalSessionServiceCallers manage multiple named terminal sessions. They do not allocate raw PTYs through this service.
Public high-level Pty* session and backend namesTerminal* namesThe public abstraction is a terminal session. Keep low-level SubprocessTerminal* names because they already name the substrate.
@deepseek-ai/dsh-pty-local, LocalPtyBackend@deepseek-ai/dsh-terminal-bash, BashTerminalBackendThe provider depends on Bash prompt and shell behavior. local hides the actual dialect.
@deepseek-ai/dsh-tool-pty@deepseek-ai/dsh-tool-terminalThe model-facing tools are already terminal_*; the package should use the same product noun.
tool-bash-persistent in the former PTY familyshell/tool-bash-persistent/The tool is a Bash tool and belongs with shell tools. Keep its npm name: persistent distinguishes it from one-shot bash, while bash-terminal would blur the product tool with the terminal-session family.
docs/subsystems/pty.mddocs/subsystems/terminal.mdThe page documents terminal sessions, not raw PTY allocation.

Keep the Bash- and PowerShell-specific leaf packages, plugin ids, types, and tools. Their dialect names are accurate.

Language server and jobs

FormerCurrentReason
@deepseek-ai/dsh-lsp-local@deepseek-ai/dsh-lsp-stdioThe provider speaks LSP over stdio through replaceable filesystem and subprocess services. It is not necessarily local.
packages/tasks/packages/jobs/The family owns detached tool jobs. jobs is short and avoids collision with user task or todo concepts.
@deepseek-ai/dsh-tasks, ctx.tasks, TaskService@deepseek-ai/dsh-jobs, ctx.jobs, JobRegistryThe service registers, owns, observes, waits for, and cancels multiple background jobs. It is a registry, not a general task service.
Public TaskId, TaskKindMap, TaskStart, TaskHooks, TaskOutcome, TaskSnapshot, TaskRead, and TaskDoneListener namesCorresponding Job* namesThese types belong to the renamed job domain. JobId is shorter and clearer than BackgroundTaskId or BgTaskId.
@deepseek-ai/dsh-tasks-local, LocalTaskService@deepseek-ai/dsh-jobs-local, LocalJobRegistryThis is the process-local provider of the job registry. Here local is meaningful because the jobs and callbacks live in one process.
@deepseek-ai/dsh-tool-tasks@deepseek-ai/dsh-tool-jobsThe consumer controls the job registry and should use the same domain noun.
ToolTasks, toolTasks, ToolTasksConfigSchema, PublicTaskSnapshot, publicTask, validateTaskIdCorresponding *Jobs, *Job*, and validateJobId namesImports, forwarded config, public tool values, and helpers are part of the same job domain. Keeping Task after the package rename would create a second vocabulary for one feature.
task_output, task_list, task_killjob_output, job_list, job_killThese model tools act on jobs, not user tasks. run_in_background returns a JobId.
@deepseek-ai/dsh-client-ui-task, client/ui-task/@deepseek-ai/dsh-client-ui-jobs, client/ui-jobs/The client package presents the background-job collection. It is not one user task.
TaskView, wire frame session/tasks, tasksBySessionJobView, wire frame session/jobs, jobsBySessionThe browser contract and its mirror expose the same job domain as the registry and tools.
docs/subsystems/tasks.mddocs/subsystems/jobs.mdThe subsystem page must use the public job vocabulary.

Keep the base LSP package, ctx.lsp, LSP protocol types, and the LSP tool. The seam deliberately exposes language-server semantics; only its provider qualifier is wrong.

Input triggers, tool presentation, permission presets, and user questions

FormerCurrentReason
@deepseek-ai/dsh-client-ui-slash, ui-slash/@deepseek-ai/dsh-client-ui-input-trigger, ui-input-trigger/The client handles /, @, keyboard arbitration, candidate menus, and programmatic launch. It is not only slash commands.
ctx.slash, SlashService, SlashController, SlashSourcectx.inputTriggers, InputTriggerService, InputTriggerController, InputTriggerSourceThe names cover every supported trigger and keep the existing service, controller, and source roles. Coupled locale and public type names follow InputTrigger.
@deepseek-ai/dsh-agent-tool-mode, plugin tool-mode@deepseek-ai/dsh-agent-tool-presentation, plugin tool-presentationThe plugin changes how tools are presented to the model. It does not change execution behavior. Keep local Config.mode and ToolPresentationMode.
packages/interaction/permission/packages/interaction/permission-presets/The package owns named combinations of sandbox and approval settings, not permission enforcement.
@deepseek-ai/dsh-permission, ctx.permission, PermissionService@deepseek-ai/dsh-permission-presets, ctx.permissionPresets, PermissionPresetServiceThe service selects and persists presets. Sandbox and approval services enforce the result.
@deepseek-ai/dsh-client-ui-permission@deepseek-ai/dsh-client-ui-permission-presetsThe UI edits and selects permission presets.
docs/subsystems/permission.mddocs/subsystems/permission-presets.mdThe page documents preset selection, not permission enforcement.
@deepseek-ai/dsh-user-interaction, user-interaction/@deepseek-ai/dsh-user-questions, user-questions/The seam supports question batches and answers only. Approval, commands, and directory picking are separate interaction seams.
ctx.userInteraction, UserInteractionService, UserInteractionProvider, UserInteractionErrorctx.userQuestions, UserQuestionService, UserQuestionProvider, UserQuestionErrorThese names state the one supported interaction form. Keep AskUserQuestion*, the ask_user_question tool, and @deepseek-ai/dsh-tool-ask-user.
docs/subsystems/user-interaction.mddocs/subsystems/user-questions.mdThe page documents questions and answers only.

Keep /permission, the permissions projection, the permission settings namespace, and permission/preset; they are accurate product or durable vocabulary. Keep the full PermissionPresetSettingsController name. Dropping Preset would remove the word that limits its authority. Removal of the both tool-presentation mode remains deferred to a separate proposal; this rename does not remove behavior.

Typert, API gateway, and tools

FormerCurrentReason
packages/typert/type-meta/, @deepseek-ai/dsh-type-metatypert/protocol/, @deepseek-ai/dsh-typert-protocolThe package owns the Typert Remote protocol, decorators, bindings, codecs, lookups, and context contracts. It is not generic type metadata.
GatewayService in the protocol packageTypertRemoteServiceThe base class marks a same-process service for Remote export. It is not the API gateway.
bindTypeRTGateway, typertGateway bindingbindTypertRemote, typertRemoteThese bindings expose Typert Remote services, not the concrete API gateway service.
Public TypeRT* and camel-case typeRT* identifiersTypert* and typert*Typert is the one canonical product spelling.
Protocol interface TypeRTServiceTypertRegistryContractThe protocol-owned interface is the dependency-inverted face implemented by the existing concrete TypertRegistry. A distinct suffix prevents an import and declaration collision.
ToolRegistryToolRuntimeThe class owns presentation, approval and guard policy, dispatch, cancellation, validation, finalization, and observation. Registration is only one internal part.
ToolRegistryScheduler, TOOL_REGISTRY_SCHEDULERToolRuntimeScheduler, TOOL_RUNTIME_SCHEDULERThe scheduler controls runtime dispatch, not registration.

Keep @deepseek-ai/dsh-tools and ctx.tools. Keep @deepseek-ai/dsh-api-gateway, its gateway/ folder, ctx.typertGateway, and TypertGatewayService; that service is a real API gateway. Its internal TypeRT* identifiers still follow the Typert* spelling rule.

Workspace instructions, telemetry, identity, and launch environment

FormerCurrentReason
Host ctx.workspaceHost ctx.workspaceRegistryWorkspaceRegistry owns multiple workspaces, but Client ctx.workspaces already has an incompatible type. Both declarations merge into the same Cordis Context interface at compile time even though their runtime contexts are separate. The role suffix states the host service and avoids that collision. Keep @deepseek-ai/dsh-workspace, WorkspaceRegistry, Workspace, and workspace.* wire names.
@deepseek-ai/dsh-workspace-context, context/workspace-context/@deepseek-ai/dsh-agent-instructions, context/agent-instructions/The package loads hierarchical AGENTS.md and CLAUDE.md files for the agent. It is not general workspace context.
Plugin and durable source names workspace-context and workspace-instructionsagent-instructionsThe recorded source is a specific class of agent instructions. AgentInstruction* replaces public WorkspaceInstruction* names. This term does not include system, developer, or user messages.
ctx.telemetry, abstract Telemetryctx.sessionTelemetry, SessionTelemetryBackendThe service captures session-ledger telemetry and hands it to a reporting backend. It is not a repository-wide metrics or tracing service.
TelemetryBackendSessionTelemetrySinkThis lower layer receives emitted records. Sink distinguishes it from the coordinating backend service.
TelemetryCoordinator, TelemetryRecord, TelemetrySeverity, TelemetrySharingStatus, and TelemetryCaptureCorresponding SessionTelemetry* namesThese public types belong only to session telemetry.
telemetry/recordsession-telemetry/recordThe event name must state its owning domain.
TelemetryOtel, TelemetryMode, plugin telemetry-otelOpenTelemetrySessionBackend, SessionTelemetryMode, plugin session-telemetry-otelThe provider name states both the OpenTelemetry mechanism and session scope. Keep the package names dsh-session-telemetry and dsh-session-telemetry-otel.
docs/subsystems/telemetry.mddocs/subsystems/session-telemetry.mdThe page documents session telemetry, not repository-wide observability.
session/user-id/, @deepseek-ai/dsh-user-ididentity/anonymous-user-id/, @deepseek-ai/dsh-anonymous-user-idThe value is a random correlation id shared by telemetry, feedback, and DeepSeek requests. It is neither a Session concern nor an authenticated user identity.
USER_ID_FILE_NAME, .userid, feedback label UserANONYMOUS_USER_ID_FILE_NAME, .anonymous-user-id, feedback label Anonymous userThe file and UI must not imply account identity. Keep the existing AnonymousUserId functions and the standard OTel attribute user.id.
util/environment/, @deepseek-ai/dsh-environmentutil/launch-environment/, @deepseek-ai/dsh-launch-environmentThe package captures one immutable layered snapshot at launch. It is not a general environment API.
Public Environment*, createEnvironmentSnapshot, environmentOf, DSH_ENVIRONMENT_KEYLaunchEnvironment*, createLaunchEnvironmentSnapshot, launchEnvironmentOf, DSH_LAUNCH_ENVIRONMENT_KEYThe names state the snapshot's lifetime and purpose.
ctx.launcherEnvironmentctx.launchEnvironmentThe value describes the application launch, not only a launcher component. Keep source labels process, project-env, and user-env.

Schedule, workflow, goals, and compaction

FormerCurrentReason
@deepseek-ai/dsh-tool-schedule, schedule/tool-schedule/, plugin tool-schedule@deepseek-ai/dsh-schedule, schedule/schedule/, plugin scheduleThe package owns the durable Schedule domain, persistence barriers, management tools, timers, follow-ups, and runtime lifecycle. tool- describes only one part.
ScheduleOwnerScheduleRuntimeThe per-agent object runs live timers, durable projection, dispatch, idle waits, and disposal. Owner does not state that execution role. Coupled private owner* names follow runtime*.
WorkflowService, ctx.workflowsWorkflowEngine, ctx.workflowEngineOne engine parses and executes workflow programs. The plural key wrongly suggests a registry. Keep @deepseek-ai/dsh-workflow and workflow events and tools.
@deepseek-ai/dsh-workflow-workerthread, WorkerWorkflowEngine@deepseek-ai/dsh-workflow-worker-thread, WorkerThreadWorkflowEngineworker thread is the precise Node mechanism and the repository spelling uses the full words.
@deepseek-ai/dsh-goal-session, goal/goal-session/@deepseek-ai/dsh-goal-round-driver, goal/goal-round-driver/The plugin drives same-session Goal Rounds. It neither stores goals nor defines sessions. Keep GoalService, goal source, events, and contracts.
packages/compact/packages/compaction/The group is a noun-domain family. compact remains the user command verb.
@deepseek-ai/dsh-compact, ctx.compact, CompactService@deepseek-ai/dsh-compaction, ctx.compaction, CompactionEngineThe object runs the compaction algorithm and lifecycle. It is an engine, not a generic service.
compact/* events and public domain prefixescompaction/*Events and domain types use the noun. Keep verb-shaped operations such as compactNow, compactRegion, and compactIfNeeded.
@deepseek-ai/dsh-compact-basic, BasicCompactService, public BasicCompact*@deepseek-ai/dsh-compaction-basic, BasicCompactionEngine, corresponding BasicCompaction*basic is plain but honest. compaction-llm adds no information because LLM use is already part of the current implementation family.
@deepseek-ai/dsh-compact-tool-result-prune, ToolResultPruneService, ctx.toolResultPrune@deepseek-ai/dsh-compaction-tool-result-pruner, ToolResultPruner, ctx.toolResultPrunerThe plugin is an actor that prunes tool results. The noun pruner names that role.

Keep /compact, the command package, and the separate compaction definition and provider packages. Merging those packages remains rejected. The rename changes vocabulary, not that package boundary.

Settings, credentials, client modules, and small core roles

FormerCurrentReason
Abstract SettingsSettingsProviderThe class supplies settings through a replaceable capability. Keep the package, key, and events.
@deepseek-ai/dsh-settings-local, SettingsLocal@deepseek-ai/dsh-settings-file, FileSettingsProviderThe implementation is file-backed through the filesystem seam. file states the mechanism; local does not.
Abstract CredentialsCredentialProviderThe class resolves credential references. Keep package names, keys, and events.
CredentialsLocalLocalCredentialProviderThis provider reads the host process and .env state, so local execution is part of its contract.
ClientModuleHostService, ctx.clientModuleHostClientModuleRegistry, ctx.clientModulesThe service owns multiple registered client modules. Keep the package and the browser ClientModuleLoader.
AgentDefaultModelServiceAgentDefaultModelConfigThe object stores one default model selection. It does not run a service or general registry. Keep its package, key, settings namespace, and type.
SessionReferenceService, ctx.sessionReferencesSessionReferenceResolver, ctx.sessionReferenceResolverIt resolves one session reference from a URI or input. It does not own a reference collection.
SessionQueryService, SessionQuerySqliteSessionQueryEngine, SqliteSessionQueryEngineThe classes execute a query model and its SQLite implementation. Keep package names, key, and tool.
@deepseek-ai/dsh-session-export, session-export/, Loader id session-export, ctx.sessionExport@deepseek-ai/dsh-session-log-export, session-log-export/, Loader id session-log-download, ctx.sessionLogDownloadThe npm package names the Session-log export because npm rejects download in package names. The Loader id and browser API retain download because they describe the browser side effect.
SessionExportDownloadController, other SessionExport* browser types, useSessionExport, SessionExportHeaderSessionLogDownloadController, corresponding SessionLogDownload* types, useSessionLogDownload, SessionLogDownloadHeaderActionThe controller owns preflight, duplicate-request collapse, modal state, and browser save. ExportDownload repeats the action, and the component contributes one Header action rather than the Header.
CommandService in the host command packageCommandRuntimeThe object registers and executes host commands across live calls. Keep its package, key, types, and events.
TokenMeterServiceTokenMeterThe object measures token use. Service adds no scope.
LlmServiceLlmRuntimeThe object selects providers and runs live model requests. Keep the package, key, adapters, and events.

Host web server, session data, and code execution

FormerCurrentReason
HttpServerService, ctx.httpServerWebServer, ctx.webServerThe server owns HTTP routes and WebSocket upgrade routes. Web leaves room for both; Http is too narrow here. Keep packages/host/webserver, @deepseek-ai/dsh-host-webserver, WebRoute, and WebUpgradeRoute.
Documentation subsystem label http-serverweb-serverThe subsystem must use the same scope as the service.
SessionPersistenceJsonlJsonlSessionPersistencePut the implementation qualifier first and keep the capability role intact.
SessionPersistenceSqliteSqliteSessionPersistenceUse the same provider naming order as JSONL.
@deepseek-ai/dsh-session-title-first-message-llm, cadence first-message@deepseek-ai/dsh-session-title-first-prompt-llm, cadence first-promptThe trigger is the first user prompt, not any message in the session log.
@deepseek-ai/dsh-session-title-all-messages-llm, cadence all-user-messages@deepseek-ai/dsh-session-title-all-prompts-llm, cadence all-promptsThe backend refreshes from user prompts. all messages wrongly includes assistant and tool events.
@deepseek-ai/dsh-code-runtime-worker, WorkerCodeRuntime@deepseek-ai/dsh-code-runtime-worker-thread, WorkerThreadCodeRuntimeThe implementation uses a Node worker thread. worker alone is too broad.
SubprocessServiceSubprocessRuntimeThe service owns live child-process execution and lifecycle. Keep its package and key.
LocalSubprocessServiceLocalSubprocessRuntimeThe provider runs same-host processes and process trees.
E2BSubprocessServiceE2BSubprocessRuntimeThe provider runs subprocesses in the E2B runtime.

Keep the complete session projection family and SessionProjection* vocabulary. A projection is a maintained read model; Reducer would name only its fold operation and would understate caching and lookup. Keep SessionTitleService, checkpoint policy, persistence package names, time context, and tmux context.

Filesystem, skill, subagent, and web providers

FormerCurrentReason
@deepseek-ai/dsh-fs-policy@deepseek-ai/dsh-fs-observation-policyThe package defines which filesystem observations authorize later effects. It is not the complete filesystem or sandbox policy.
FsPolicyExecFsObservationActorThe value names the actor whose observations and effects the policy relates. It does not execute the policy itself.
SkillServiceSkillRegistryThe service registers providers and resolves skills from their catalogs.
@deepseek-ai/dsh-skill-local, LocalSkillProvider, provider id local@deepseek-ai/dsh-skill-filesystem, FileSystemSkillProvider, provider id filesystemThe provider discovers skill files through ctx.fs, which can be local or remote. The mechanism is filesystem access, not locality.
SubagentServiceSubagentRuntimeThe service selects providers and owns live spawn, resume, follow-up, cancellation, and settlement behavior.
@deepseek-ai/dsh-subagent-spawn, SpawnProvider@deepseek-ai/dsh-subagent-spawn-in-process, SpawnInProcessProviderThis provider starts a child agent in the current process. The configured provider id remains spawn.
@deepseek-ai/dsh-subagent-fork, ForkProvider@deepseek-ai/dsh-subagent-fork-in-process, ForkInProcessProviderThis provider forks an agent in the current process. The configured provider id remains fork.
@deepseek-ai/dsh-subagent-inprocess, subagent-inprocess/@deepseek-ai/dsh-subagent-in-process-driver, subagent-in-process-driver/The package contains common in-process driving logic, not a third provider.
Private SdkProvider in dsh-subagent-dsh-sdkSdkSubagentProviderThe repeated package qualifier is intentional, and the class must say that it provides subagents through the SDK.
WebService, WebServiceConfigWebRuntime, WebRuntimeConfigThe object selects providers and runs live search and fetch operations. Keep the package, key, provider packages, and model tool.
@deepseek-ai/dsh-web-fetch-local, LocalFetchProvider, LocalFetchLimits, provider id local-http@deepseek-ai/dsh-web-fetch-http, HttpFetchProvider, HttpFetchLimits, provider id httpThis provider performs direct HTTP fetches. local says where code happens to run, not which mechanism it provides.

Keep @deepseek-ai/dsh-subagent-dsh-sdk, its provider id dsh-sdk, external ACP, Codex, and Claude Code provider families, the subagent tool package names, the main filesystem package and backends, filesystem tools and events, and the skill badge and tool packages.

Hooks, guards, plan mode, extensions, and diagnostics

FormerCurrentReason
@deepseek-ai/dsh-hooks-claude, ClaudeHookConfig, parseClaudeConfig, dialect claude@deepseek-ai/dsh-hooks-claude-code, ClaudeCodeHookConfig, parseClaudeCodeConfig, dialect claude-codeThe hook bridge targets Claude Code, not every Anthropic or Claude product.
@deepseek-ai/dsh-repeat-tool-guard, plugin/source repeat-tool-guard@deepseek-ai/dsh-repeat-tool-reminder, plugin/source repeat-tool-reminderThe plugin adds a model reminder. It does not block or enforce a guard decision.
@deepseek-ai/dsh-timeout-policy@deepseek-ai/dsh-tool-call-timeout-policyThe full tool-call qualifier names what the policy limits without calling the plugin a model-facing tool. Keep its guard/timeout-policy/ directory and plugin id timeout-policy; the packages/*/tool-* catalog convention still applies only to packages that register tools.
PlanModeServicePlanModeControllerThe object controls transitions into and out of plan mode. It is not a general execution runtime.
packages/self-modification/packages/extensions/The group contains repository plugin inspection and mounting tools. extensions states the stable package role without asserting that the agent modifies itself. Keep the package names tool-cordis and repository-plugin names.
packages/support/packages/test-support/The group is test-only infrastructure. Its path must say so.
invariants/ in the former support familyruntime-diagnostics/invariants/Invariants can run in production diagnostics even though shipped presets omit them. They are not test support.
InvariantServiceInvariantRegistryThe object owns registered invariant checks. Keep @deepseek-ai/dsh-invariants and ctx.invariants.
packages/client/test-runtime/packages/test-support/client-runtime/The package is client test infrastructure. Keep its npm name if it already states that contract.

Keep MCP, Todo, and the Plan Mode package, key, events, and tool names. This decision renames the controller class, not the product feature.

Utilities, E2B, host, bundles, examples, and applications

FormerCurrentReason
util/paths/, @deepseek-ai/dsh-pathsutil/home-paths/, @deepseek-ai/dsh-home-pathsThe helpers resolve paths under the Harness home. They are not a general path library. Keep the individual function names when they already state the returned path.
util/retention/, @deepseek-ai/dsh-retentionutil/output-retention/, @deepseek-ai/dsh-output-retentionThe policy retains command and tool output. It is not a general data-retention framework.
E2BSandboxServiceE2BRuntimeThe class creates, reuses, and disposes the E2B execution environment used by filesystem and subprocess adapters. It is broader than one sandbox handle and narrower than a generic owner. Keep @deepseek-ai/dsh-e2b, ctx.e2b, and the e2b/ group.
@deepseek-ai/dsh-frontend-static@deepseek-ai/dsh-host-frontend-staticThe package is the Host plugin that serves the frontend assets. The prefix distinguishes it from frontend application code.
PluginInventoryServicePluginInventoryGatewayThe class is a Remote-only adapter from the live Loader tree to the pluginInventory/list RPC. It owns no same-process service, cache, history, or mutation path. Gateway states the role that exists.
@deepseek-ai/dsh-jsonrpc-demo@deepseek-ai/dsh-sdk-jsonrpc-demoThe example demonstrates the runtime SDK over JSON-RPC. It belongs to the one SDK meaning.
@deepseek-ai/dsh-frontend@deepseek-ai/dsh-web-frontendThe application is the web frontend. Keep its physical apps/web/ folder.

Keep atomic-write, brand, native-command, timeout utility, directory-picker, dsh-base, dsh-web-app, app boot, CLI names, and the headless package, bundle, and example identity. headless is the intended product essence and may later support more than one-shot execution.

Client runtime and UI

FormerCurrentReason
SlotsServiceSlotRegistryThe object owns named slot declarations and registrations.
SessionsServiceSessionRuntimeThe object owns live client session coordination, not a passive session list.
WorkspacesServiceWorkspaceRuntimeThe client object coordinates live workspace selection and operations. Existing ctx keys stay where the ledger does not name a key change.
WorkspaceGroupBy, WorkspaceOrderBy, workspaceExpansion, setWorkspaceExpanded, expandedProjects, projectLabel, recentSessionOrder, recentSessionUpdatedAt, syncRecentSessions, setRecentSessionOrder, retainWorkspaceKeys, workspaceKeySessionGroupBy, SessionOrderBy, groupExpansion, setGroupExpanded, expandedGroups, workspaceLabel, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, retainAccountKeys, accountKeyThese are Session-list viewing names. Their accounts include real Workspaces, Ungrouped, and the flat list. Workspace, project, and recent therefore state the wrong subject or mechanism. Keep WorkspaceViewState; the store still belongs to the Workspace browser.
LocaleServiceLocaleRuntimeThe object coordinates locale definitions, selection, persistence, and change publication.
ThemeServiceThemeRuntimeThe object coordinates themes, preference resolution, system sensing, and change publication.
LayoutServiceLayoutControllerThe object controls the current UI layout state.
@deepseek-ai/dsh-client-ui-model@deepseek-ai/dsh-client-ui-model-selectionThe package controls the model selection for a session. The singular model name is too broad.
ModelService, ctx.modelsModelDirectoryResolver, ctx.modelDirectoriesIts only public operation, directoryFor(sessionId), resolves and retains one directory per live session. It has no registration API, so Registry would be false. Each ModelDirectory remains the consumer-facing catalog of selectable models.
SettingsScopeServiceSettingsScopeBinderIts sole operation binds one namespace specification to the caller's transport and lifecycle and returns a SettingsScopeController. Keep ctx.settingsScope; it names the singular binding capability, not a collection of scopes.
@deepseek-ai/dsh-client-ui-models@deepseek-ai/dsh-client-ui-settings-modelsThis package owns the Models settings panel. Keep ModelsSettingsStore; it holds one settings view model with data operations and subscriptions and is a real store.
@deepseek-ai/dsh-client-ui-plugin-config, client/ui-plugin-config/@deepseek-ai/dsh-client-ui-settings-plugins, client/ui-settings-plugins/This package owns the Plugins settings section, not a general plugin-configuration system. The target joins the ui-settings-* family and uses the section's plural product name.
PluginConfigSection, PluginConfigSectionProps, PluginConfigSectionInjected, PluginSettingsTabRow, PluginConfigKey, settings.pluginConfigPluginsSettingsSection, PluginsSettingsSectionProps, PluginsSettingsSectionInjected, PluginsSettingsTabEntry, PluginsSettingsLocaleKey, settings.pluginsThe section owns the Plugins settings presentation and tab ledger. The metadata value is one slot entry, not a rendered row. Each card still edits one plugin's configuration.
@deepseek-ai/dsh-client-ui-plugins, client/ui-plugins/, Loader id ui-plugins, client-ui-plugins-invariant@deepseek-ai/dsh-client-ui-settings-plugin-inventory, client/ui-settings-plugin-inventory/, Loader id ui-settings-plugin-inventory, client-ui-settings-plugin-inventory-invariantThis later package owns the read-only Plugin Inventory tab in the Plugins settings section. ui-plugins is too broad and does not distinguish the inventory from editable plugin settings.
PluginSettingsSection, PluginSettingsSectionProps, PluginSettingsSectionInjected, PluginsKey, settings.plugins in the former ui-plugins packagePluginInventorySettingsTab, PluginInventorySettingsTabProps, PluginInventorySettingsTabInjected, PluginInventoryLocaleKey, settings.pluginInventoryThe component is now a tab contribution, not a settings section. The other names state the inventory subject and avoid colliding with PluginsSettingsSection and its settings.plugins locale namespace. Keep the shared settings.plugins.tab slot name; both tabs contribute to the Plugins section through that slot.
@deepseek-ai/dsh-client-ui-feedback, client/ui-feedback/, Loader id ui-feedback, client-ui-feedback-invariant@deepseek-ai/dsh-client-ui-message-feedback, client/ui-message-feedback/, Loader id ui-message-feedback, client-ui-message-feedback-invariantThis package presents ratings and notes for assistant messages through the messageFeedback Remote. The old name also appears to cover command feedback and any later feedback UI. It does not.
FeedbackController, FeedbackStatus, FeedbackView, FeedbackActionResult, FeedbackInjected, FeedbackActionProps, FeedbackActions, FeedbackKey in the former ui-feedback packageMessageFeedbackController, MessageFeedbackStatus, MessageFeedbackView, MessageFeedbackActionResult, MessageFeedbackInjected, MessageFeedbackActionProps, MessageFeedbackActions, MessageFeedbackKeyThese are exported Client names. The Message qualifier prevents them from claiming every feedback domain. Keep Controller: the object accepts rating and note actions and coordinates one Session's load, mutation, conflict, reconnect, and disposal state.
agent-loop-store.ts, bash-store.ts, web-search-store.tsagent-loop-card-controller.ts, bash-card-controller.ts, web-search-card-controller.tsEach module exports a card controller. A private SnapshotStore field does not make the module a store.
card-store.tscard-form.tsThe module owns the staged form, field conversion, and form actions. The snapshot stores it returns are presentation adapters, not the module's main role.
@deepseek-ai/dsh-client-ui-question@deepseek-ai/dsh-client-ui-user-questionsThe UI presents the user-question seam, not an arbitrary question domain.
@deepseek-ai/dsh-client-ui-command, ui-command/@deepseek-ai/dsh-client-ui-commands, ui-commands/The package presents and runs a collection of commands.
@deepseek-ai/dsh-client-ui-directory-picker, client/ui-directory-picker/, Loader id ui-directory-picker, client-ui-directory-picker-invariant@deepseek-ai/dsh-client-ui-directory-picker-browse, client/ui-directory-picker-browse/, Loader id ui-directory-picker-browse, client-ui-directory-picker-browse-invariantThe Client packages now contain separate browse and native directory-picker presentations. The unqualified package is the browse implementation, not their shared definition. The target matches the Host backend family and changes no boundary.
Client ctx.command, CommandService, CommandServiceContractctx.commandUi, CommandUiRuntime, CommandUiContractThe host already owns ctx.commands. The client service is the UI runtime for command discovery and execution. Existing CommandUiSpec fixes the Ui casing.
ConversationServiceConversationControllerThe object controls the active conversation state and user actions.
InputServiceSessionInputResolverThe interface resolves the input facade for one session scope. It is neither a global input registry nor an execution service. Keep InputHub as the concrete hub and ctx.conversation.input as the published face.

Use Ui, not UI, inside PascalCase identifiers. Keep the remaining client package names unless this ledger names them. Keep the deprecated client connection and Host ApiProxy vocabulary for now; the API plane will replace them, and a rename would add churn to a surface scheduled for removal.

Explicit non-renames

The following debated names stay unchanged because the current scope is accurate or a rename would create a false concept:

  • Keep the complete sandbox family and ctx.sandbox. Do not introduce processSandbox.
  • Keep @deepseek-ai/dsh-api-gateway, ctx.typertGateway, and TypertGatewayService.
  • Keep session projection names. A projection is not only a reducer function.
  • Keep @deepseek-ai/dsh-session-stats, sessionStats, and SessionStatsProjection. They accurately name whole-session statistics and the maintained read model that carries them.
  • Keep GoalService; it owns the goal state machine, authority, compare-and-set behavior, events, and remote operations. It is not just a store.
  • Keep SessionTitleService; its role is a domain service shared by title providers.
  • Keep PermissionPresetSettingsController even though it is long. Every word limits the role.
  • Keep ModelsSettingsStore; its main contract is one settings data model with store operations.
  • Keep InputHub; it is the concrete hub that backs SessionInputResolver.
  • Keep dsh-subagent-dsh-sdk and provider id dsh-sdk; the repeated qualifier prevents ambiguity.
  • Keep headless; the product identity is accurate even if the runtime later supports more than one-shot use.
  • Keep deprecated Host ApiProxy and client connection names until the API replacement removes them.
  • Keep Web for the Host server and the provider-neutral web capability. Use HTTP only for the direct fetch provider.
  • Keep E2B, not E2B sandbox, as the package and context name.
  • Keep MCP, Todo, app boot, base bundle, web-app bundle, and CLI names. Keep the directory-picker capability and Host backend names; only the unqualified Client browse presentation is renamed.
  • Keep @deepseek-ai/dsh-client-ui-directory-picker-native; its suffix names the native-chooser presentation beside the renamed -browse variant. Keep SURFACE_PACKAGES; within the directory-picker auto selector it is the package map for the Client presentation half, contrasted with BACKEND_PACKAGES.
  • Keep @deepseek-ai/dsh-host-plugin-inventory, ctx.pluginInventory, the pluginInventory/list Remote, and the PluginInventory* payload types. They accurately name the Host-owned read-only inventory; only the adapter class and the overly broad Client presentation names change.
  • Keep ConfigurablePluginsTab. It is the tab that renders plugins with editable configuration; it does not own the complete Plugins settings section.
  • Keep the shared settings.plugins.tab slot. It belongs to the Plugins settings section. The inventory package changes its own locale namespace to settings.pluginInventory; it does not create a separate tab slot.
  • Keep the @deepseek-ai/dsh-message-feedback capability, messageFeedback Remote, assistant-action entry id feedback, hook key feedback, and locale namespace feedback. Their surrounding interfaces already limit them to message feedback or to the local assistant-message slot. Only the broad Client package and exported UI names change.
  • Keep RemoteFailure, RemoteResult, and SessionRemotes. The first two are Typert carrier-result values, while the last is the set of Remote namespaces used by the Client Session cluster. None is a store, controller, registry, or runtime.
  • Keep the /export human command, /api/session.export Host route, DownloadsApi, and its sessionLog operation. The command names the user action, the Host route exports the archive, and the API groups direct HTTP downloads. The renamed Client controller owns the separate browser-download step.
  • Keep .client and .host in test filenames. They identify the compiler face each test enters and do not claim a product role.

Alternatives considered

Keep the current names and add a glossary. Rejected. A glossary cannot make BashExecutor truthful when PowerShell implements it, or make ToolRegistry disclose that it enforces and executes tools. The identifier must carry the useful distinction.

Prefix every npm package with its group. Rejected. Flat npm names do not need a copy of the directory tree. A mechanical prefix adds length without explaining the package role.

Call the whole repository an SDK. Rejected. The project is an agent harness. SDK is the supported JSON-RPC client/server stack used by Python and TypeScript clients. Two meanings make package names and product prose ambiguous.

Use Service for every Cordis service class. Rejected. Cordis inheritance is an implementation fact. The class name must tell callers whether the object registers, stores, resolves, controls, or runs work.

Use Runtime as the standard replacement for Service. Rejected. Runtime is correct only when the object owns live execution or lifecycle. Registries, stores, directories, controllers, resolvers, engines, and configuration objects keep their sharper roles.

Prefer the shortest possible name. Rejected. Short is useful only after scope is clear. PermissionPresetSettingsController keeps Preset; JobId is short because Job already carries the domain; BgTaskId is short but cryptic.

Use broad names for possible future features. Rejected. Name the stable current role. A future boundary change can rename the object again before release or use a new proposal after release. Vague names charge every current reader for an unbuilt future.

Rename dsh-compact-basic to dsh-compaction-llm. Rejected. LLM adds no distinction in the current backend family. basic is less ambitious and does not claim an algorithm that does not exist.

Rename session projections to reducers. Rejected. Reduction is how a projection is built. The package also owns the read-model value, cache, and lookup contract.

Rename the persistent Bash tool to bash-terminal. Rejected. That name collides with the terminal-session family. Moving tool-bash-persistent under shell/ fixes its home while its current name continues to distinguish it from the one-shot Bash tool.

Rename or split boundaries while applying the ledger. Rejected. Reviewers must be able to see that behavior did not change. A real boundary defect needs its own proposal, tests, and consequences.

Keep aliases for old names. Rejected. No released consumer needs them. Aliases would preserve two vocabularies and make the first release carry a migration that never had a user.

Verification

  • Every mapping in the ledger appears in the repository. Each family has one public vocabulary; no compatibility package, re-export alias, duplicate ctx key within one Cordis context, dual plugin id, dual event id, old tool alias, or fallback parser remains.
  • Runtime behavior, package boundaries, defaults, policy, durable semantics, and model behavior remain equivalent except where an identifier is itself visible.
  • Package directories, npm names, imports, manifests, TypeScript references and paths, Cordis config, plugin ids, service keys, events, tools, RPC names, persisted names named by the ledger, fixtures, snapshots, examples, generated catalogs, and current prose use the current vocabulary.
  • Current implemented Agent Notes carry the factual name and path changes. The package-regrouping note records the group inventory and package targets, the SDK removal note reserves SDK for the runtime protocol, and the timeout-policy note records the package-name rationale.
  • The paired package-creation guide contains the role-word contract, packages/AGENTS.md links to it, the terminology table records the chosen words and Typert spelling, and root project prose calls the product DeepSeek Harness rather than DeepSeek Harness SDK.
  • The removed SDK project toolchain stays absent.
  • pnpm run check:ci covers source-plane typecheck, build, package hygiene, generated-reference checks, affected snapshots, translation pairing, doc-sync, and lint. Release-shaped Python runtime smokes and required CI cover packaged-runtime and platform paths.

Consequences

The repository has one vocabulary for each renamed family. Old on-disk names, wire values, tool names, and configuration entries named in the ledger do not work. An owning parser that can identify stale configuration fails clearly instead of accepting both forms.

Some names are longer. The extra word is intentional when it prevents a false claim about authority or mechanism. A long name remains wrong when every word does not constrain the role.

Role suffixes do not replace inspection of behavior. The package guide keeps the direct tests from this decision: inspect what callers do, what lifetime the object owns, and what failure or policy it controls.

Branches based on the former paths and symbols require conflict repair. This is a one-time pre-release cost of removing the old vocabulary without compatibility aliases.

中文

问题

仓库的发展速度曾超过部分名称的演进速度。一些包名描述的是最初的实现,而非所提供的能力。若干类即使实际承担注册表、运行时、引擎、控制器或解析器的职责,名称仍使用 Service。部分 ctx 键以单数命名注册表,却以复数命名单个引擎。还有一些提供方明明通过可替换的文件系统或子进程服务工作,可以在另一执行环境中运行,名称却使用 local

这些名称并非无关紧要。名称会告诉贡献者一项职责从哪里开始、到哪里结束。Store 表示数据访问。Registry 表示注册与查找。Runtime 表示实时执行和生命周期。如果同一个词同时表示这三者,调用方就必须阅读实现,才能判断哪个对象拥有策略、工作或状态。

仓库还曾在两种含义下使用 SDK。受支持的 Python 和 TypeScript 客户端使用 JSON-RPC SDK 协议。项目整体是 DeepSeek Harness,而不是 SDK 项目。已移除的 SDK 项目工具链使宽泛的含义失去依据,但文案和名称仍保留了部分旧用法。

首次发布带标签版本之前的最后一个窗口,使仓库级重命名仍可低成本完成。若继续保留含义不清的名称,偶然形成的词汇就会变成兼容性约定。

决策

仓库使用本清单中的全部当前名称。本决策只更改名称;包职责、服务边界、行为、默认值和数据模型保持不变。如果某个名称暴露出不合理的边界,需要另写一份 proposed Agent Note,专门提议边界变更。

每个已重命名系列只有一套词汇。清单点名某一接口时,其目录、NPM 包名、导入、Cordis 插件名称、ctx 键、公开类型、直接耦合的事件或工具标识符、配置、测试、fixture(测试前置数据)、示例、生成的参考资料以及当前文档都使用当前名称。仓库不保留别名、兼容包、重复的服务键、双重事件名称或回退解析器,并拒绝旧名称。

同一系列不会公开两套词汇。

SDK 只表示一件事

SDK 表示受支持的 Python 和 TypeScript SDK 所使用、基于 JSON-RPC 的客户端/服务器协议。仓库保留 @deepseek-ai/dsh-sdk-client@deepseek-ai/dsh-sdk-protocol 和协议身份 deepseek-harness-sdk-runtime;JSON-RPC 服务器属于同一系列。DeepSeek Harness 本身不是 SDK,已移除的项目生成器、启动器、辅助工具和启动器遥测包继续保持不存在。

本决策部分取代三项现行决策。它替换包重新分组决策中保留的 bash/pty/self-modification/ 组名,以及两项暂定包名。它只替换移除 SDK 项目工具链中将整个仓库称为 SDK 的说法;后者仍负责说明删除范围和保留的运行时 SDK。它只替换工具调用超时策略中的包名理由;超时机制及其 guard/timeout-policy/ 归属保持不变。

如果其他已实现说明中的包、路径或类型被重命名,而其边界和理由保持不变,则本决策不会取代这些说明。这些说明使用已实现的事实名称。三项被部分取代的决策都链接回本决策。

按实际职责命名

使用常见且具体的名词。名称应描述稳定职责,而不是最初的实现、当前目录或未来可能出现的扩展。不得添加不传递任何信息的词。不得为了缩短名称而删除用于限定作用域的词。

接口包以能力命名。实现包增加机制、协议、环境或供应商限定词,以区分不同实现。只有同主机执行属于约定时,才能使用 local。如果提供方只是通过可替换的 ctx.fs 读取看似本地的路径,或通过可替换的 ctx.subprocess 启动工作,就不得使用该词。

如果对象是单个引擎、运行时、策略、控制器、解析器、存储或当前配置,使用单数 ctx 键。如果对象是注册表,或服务拥有多个具名成员,使用复数键。类的职责和键的单复数必须一致。复数键本身不能证明对象是注册表;应由其操作和所有权决定。不得让不兼容的 host 与 client 声明复用同一个 Cordis Context 键。即使二者使用独立的运行时上下文,TypeScript 声明合并仍会同时看到两种类型。如果自然复数已经属于另一个端面,就增加职责后缀。

仅当没有更精确的职责词能够如实描述对象时,才使用 ServiceGoalServiceSessionTitleService 是保留的有效名称,因为它们各自拥有领域服务,其工作无法准确归约为存储、注册或单一执行机制。

职责词即约定

适用场景不适用场景
Controller对象接受命令或用户意图,并更改一项已有的领域状态或呈现状态。它协调有界的状态转换。对象执行任意工作、管理一组提供方,或仅将值转换为显示形式。
Store对象拥有一组数据,主要对这些数据提供创建、读取、更新、删除、快照或订阅操作。对象验证状态机、行使裁决权、分派工作、决定提供方优先级,或协调多个领域。类内部存在映射并不会让该类成为存储。
Directory对象公开条目,供发现或选择。消费方会查询有哪些选项,并读取其元数据。生产方可向其中注册任意实现,或调用方通过它执行工作。目录可以由注册表支撑,但两者的对外职责并不相同。
Presenter对象只负责将领域值或工具参数转换为渲染意图。它不拥有 I/O、订阅、变更或生命周期。对象读取服务、更改状态或控制工作运行时机。这些职责属于控制器或运行时。
Registry对象拥有一组动态的具名注册项。它定义查找规则、重复项或优先级规则、注册生命周期和资源释放。调用方的主要约定是分派、执行、取消、策略执行或编排。运行时可以在内部包含注册表。
Runtime对象运行实时工作。它跨调用拥有分派、取消、提供方协调或操作生命周期。对象只存储记录、返回目录、解析单个值或保存配置。Runtime 不是 Service 的通用替代词。
Resolver对象根据所提供的输入计算或定位一个答案,通常不拥有答案的生命周期。对象拥有可变集合或长时间运行的执行生命周期。
Binder对象将一个已声明接口附加到调用方的上下文或生命周期,并返回绑定后的值。对象以集合形式拥有绑定值、控制其领域状态,或仅转换数据。
Engine对象实现领域算法或有状态执行模型,例如工作流、压缩或查询求值。对象只选择提供方,或跨协议边界转发请求。
Policy对象决定允许、选择、限制或观察什么。对象执行决策所允许的机制。策略和执行器必须分别命名。
Executor对象在一项能力内运行明确的请求或已解析的规范。对象拥有宽泛的应用生命周期或提供方目录。
Gateway对象适配进程、网络、RPC 或 API 边界,并在两侧之间转换。对象只注册同进程服务或存储元数据。
Provider对象为一项能力定义提供一种实现。如果可以存在多个提供方,应增加机制或供应商限定词。对象是能力定义、提供方注册表或面向消费方的运行时。
Backend对象在已定义接口之后,实现可替换的底层持久化、传输或执行后端。对象是面向用户的服务,或只是对某个实时对象返回的引用。
Handle该值是对一个实时资源的引用,并控制或观察该资源。对象创建并管理整个资源池。不得使用 Owner 或含义模糊的 Resource;如果 Handle 或更精确的管理职责合适,就应采用后者。
Config对象拥有一个已解析的配置值,或一份边界严格受限的配置记录及其更新约定。对象存储通用集合、执行工作或公开不相关的设置。
Service对象拥有一项职责内聚的领域服务,且以上更精确的职责词都无法如实描述其职责范围。仅因为类继承自 Cordis Service 而使用该名称,或因为确定真正的职责需要进一步思考。

实用判断方式很直接。如果调用方主要调用 register() 并收到资源释放函数,应使用 Registry。如果调用方主要调用 run()dispatch()cancel()execute(),应使用 RuntimeEngineExecutor。如果调用方主要浏览选项,应使用 Directory。如果对象主要将一份规范绑定到调用方拥有的上下文和生命周期,应使用 Binder。如果对象只将领域数据映射为 UI 数据,应使用 Presenter。如果它还会更改状态,就不是呈现器。

使用能够补充信息的限定词

如果协议或方言名称能够区分实现,就应保留。实现依赖相应机制时,保留 BashPwshJSON-RPCSQLiteJSONLOpenTelemetryClaude CodeE2B。每个当前后端都已使用 LLM(大语言模型)seam 时,不要在压缩后端名称中加入 LLM;在出现更具体的算法名称之前,basic 才是如实且中性的名称。

不得虚构 process sandbox 概念。当前 sandbox 系列已经准确命名其产品职责。本决策不改变该职责。

PascalCase 标识符中的首字母缩略词使用首字母大写格式:UiLlmJsonRpcApiProxy。在文案和适用的包名中使用惯例规定的全大写形式:UI、LLM、JSON-RPC 和 API。Typert 是标识符和文案中的唯一准确产品拼写;不得写成 TypeRTTypeRt,也不得对 Typert 作其他内部拆分。

不得为了避免重复而删除有意保留的供应商限定词。dsh-subagent-dsh-sdk 表示 DeepSeek Harness SDK 提供方,可避免与其他 SDK 混淆。其私有类改名为 SdkSubagentProvider,因为类名还需要说明它提供什么。

将规则写入项目文档

配对的包创建指南 docs/cookbook/adding-a-package.md 包含完整的职责词约定,packages/AGENTS.md 链接到该约定。术语表和根项目说明使 SDKTypert 各自只有一种含义。本 Agent Note 负责记录理由和被否决的替代方案;指南负责记录贡献者应遵循的规则。

重命名清单

以下表格记录公开名称和仓库级名称的变更。当前名称 栏记录当前名称。引用相同职责的私有局部变量也使用相同词汇。若宽泛替换并不正确,清单会明确指出保留的底层名称或产品可见名称。

运行时 SDK

旧名称当前名称理由
@deepseek-ai/dsh-jsonrpc@deepseek-ai/dsh-sdk-jsonrpc-server它是 SDK 协议的服务器端。单独使用 jsonrpc 只说明编码;sdk-jsonrpc-server 则同时说明所属系列、机制和职责。
HarnessSdkServerHarnessSdkJsonRpcServer该类是 JSON-RPC 服务器的一种实现,并不代表所有可能的 SDK 服务器。

保留 @deepseek-ai/dsh-sdk-client@deepseek-ai/dsh-sdk-protocoldeepseek-harness-sdk-runtime。排除 @deepseek-ai/create-sdk@deepseek-ai/dsh-scripts@deepseek-ai/dsh-helper@deepseek-ai/dsh-telemetry;单独的移除决策负责删除这些包及其支撑依赖图。

Shell 与终端

旧名称当前名称理由
packages/bash/packages/shell/该组包含方言无关的执行器 seam、Bash 和 PowerShell 实现、环境支持以及 shell 工具。
@deepseek-ai/dsh-bash, ctx.bash@deepseek-ai/dsh-shell, ctx.shellPowerShell 已经实现该 seam。此项能力是 shell 执行,而不是 Bash。
方言无关的 BashExecutorBashExecRequestBashExecSpecBashProcessBashRunResultBashSandboxInfoBashProcessReadBashProcessStatus 名称对应的 Shell* 名称这些类型横跨 Bash 和 PowerShell 实现。描述 Bash 语法或行为的叶层类型保留 Bash
BASH_SETTINGS_NAMESPACE,设置命名空间 bashSHELL_SETTINGS_NAMESPACE,设置命名空间 shell两个 shell 提供方都注册这项由能力拥有的设置分区。常量和持久化命名空间必须使用能力名称。
@deepseek-ai/dsh-bash-env, ctx.bashEnv, BashEnvRegistry@deepseek-ai/dsh-shell-env, ctx.shellEnv, ShellEnvRegistryBash 和 PowerShell 工具共享该环境注册表。
docs/subsystems/bash.mddocs/subsystems/shell.md该子系统页面记录方言无关的能力。
packages/pty/packages/terminal/该包系列负责持久终端会话。原始 PTY 分配仍位于子进程层。
@deepseek-ai/dsh-pty, ctx.pty, PtyService@deepseek-ai/dsh-terminal, ctx.terminals, TerminalSessionService调用方管理多个具名终端会话,而不是通过该服务分配原始 PTY。
公开的高层 Pty* 会话和后端名称Terminal* 名称公开抽象是终端会话。保留底层 SubprocessTerminal* 名称,因为它们已经说明底层机制。
@deepseek-ai/dsh-pty-local, LocalPtyBackend@deepseek-ai/dsh-terminal-bash, BashTerminalBackend该提供方依赖 Bash 提示符和 shell 行为。local 隐藏了实际方言。
@deepseek-ai/dsh-tool-pty@deepseek-ai/dsh-tool-terminal面向模型的工具已使用 terminal_*;包应采用相同的产品名词。
原 PTY 系列中的 tool-bash-persistentshell/tool-bash-persistent/该工具是 Bash 工具,应与 shell 工具放在一起。保留其 NPM 名称:persistent 将它与一次性 bash 区分开来,而 bash-terminal 会混淆产品工具与终端会话系列。
docs/subsystems/pty.mddocs/subsystems/terminal.md该页面记录终端会话,而不是原始 PTY 分配。

保留 Bash 和 PowerShell 专用的叶层包、插件 id、类型和工具。这些方言名称准确无误。

语言服务器与作业

旧名称当前名称理由
@deepseek-ai/dsh-lsp-local@deepseek-ai/dsh-lsp-stdio该提供方通过可替换的文件系统和子进程服务,以 stdio 传输 LSP。它不一定在本地运行。
packages/tasks/packages/jobs/该系列负责脱离前台运行的工具作业。jobs 简短,并可避免与用户任务或 todo 概念冲突。
@deepseek-ai/dsh-tasks, ctx.tasks, TaskService@deepseek-ai/dsh-jobs, ctx.jobs, JobRegistry该服务注册、拥有、观察、等待并取消多个后台作业。它是注册表,而不是通用任务服务。
公开的 TaskIdTaskKindMapTaskStartTaskHooksTaskOutcomeTaskSnapshotTaskReadTaskDoneListener 名称对应的 Job* 名称这些类型属于重命名后的作业领域。JobIdBackgroundTaskIdBgTaskId 更短、更清晰。
@deepseek-ai/dsh-tasks-local, LocalTaskService@deepseek-ai/dsh-jobs-local, LocalJobRegistry这是作业注册表的进程内提供方。此处的 local 有明确含义,因为作业和回调都存在于同一进程。
@deepseek-ai/dsh-tool-tasks@deepseek-ai/dsh-tool-jobs消费方控制作业注册表,应使用相同的领域名词。
ToolTaskstoolTasksToolTasksConfigSchemaPublicTaskSnapshotpublicTaskvalidateTaskId对应的 *Jobs*Job*validateJobId 名称import、转发配置、公开工具值与辅助函数都属于同一个作业领域。包重命名后继续保留 Task,会为同一功能制造第二套词汇。
task_output, task_list, task_killjob_output, job_list, job_kill这些模型工具操作的是作业,而不是用户任务。run_in_background 返回 JobId
@deepseek-ai/dsh-client-ui-taskclient/ui-task/@deepseek-ai/dsh-client-ui-jobsclient/ui-jobs/该客户端包呈现后台作业集合,而不是一项用户任务。
TaskView、线路帧 session/taskstasksBySessionJobView、线路帧 session/jobsjobsBySession浏览器约定及其镜像应采用与注册表和工具相同的作业领域名称。
docs/subsystems/tasks.mddocs/subsystems/jobs.md该子系统页面必须采用公开的作业词汇。

保留基础 LSP 包、ctx.lsp、LSP 协议类型和 LSP 工具。该 seam 有意公开语言服务器语义;错误的只有提供方限定词。

输入触发器、工具呈现、权限预设和用户问题

旧名称当前名称理由
@deepseek-ai/dsh-client-ui-slash, ui-slash/@deepseek-ai/dsh-client-ui-input-trigger, ui-input-trigger/客户端处理 /@、键盘仲裁、候选菜单和程序化启动,并非只处理斜杠命令。
ctx.slashSlashServiceSlashControllerSlashSourcectx.inputTriggersInputTriggerServiceInputTriggerControllerInputTriggerSource这些名称覆盖所有受支持的触发器,并保留现有的服务、控制器和来源职责。耦合的区域设置和公开类型名称也改用 InputTrigger
@deepseek-ai/dsh-agent-tool-mode,插件 tool-mode@deepseek-ai/dsh-agent-tool-presentation,插件 tool-presentation该插件改变工具向模型呈现的方式,而不改变执行行为。保留局部 Config.modeToolPresentationMode
packages/interaction/permission/packages/interaction/permission-presets/该包拥有沙箱与审批设置的具名组合,而不负责执行权限。
@deepseek-ai/dsh-permission, ctx.permission, PermissionService@deepseek-ai/dsh-permission-presets, ctx.permissionPresets, PermissionPresetService该服务选择并持久化预设。沙箱和审批服务负责执行结果。
@deepseek-ai/dsh-client-ui-permission@deepseek-ai/dsh-client-ui-permission-presetsUI 编辑和选择权限预设。
docs/subsystems/permission.mddocs/subsystems/permission-presets.md该页面记录预设选择,而不是权限执行。
@deepseek-ai/dsh-user-interaction, user-interaction/@deepseek-ai/dsh-user-questions, user-questions/该 seam 仅支持批量问题和答案。审批、命令和目录选择属于其他交互 seam。
ctx.userInteraction, UserInteractionService, UserInteractionProvider, UserInteractionErrorctx.userQuestions, UserQuestionService, UserQuestionProvider, UserQuestionError这些名称说明唯一受支持的交互形式。保留 AskUserQuestion*ask_user_question 工具和 @deepseek-ai/dsh-tool-ask-user
docs/subsystems/user-interaction.mddocs/subsystems/user-questions.md该页面只记录问题和答案。

保留 /permissionpermissions 投影、permission 设置命名空间和 permission/preset;它们都是准确的产品词汇或持久化词汇。保留完整名称 PermissionPresetSettingsController。删除 Preset 会去掉限定其权限的词。移除 both 工具呈现模式的工作仍推迟到另一份提案;本次重命名不移除行为。

Typert、API 网关与工具

旧名称当前名称理由
packages/typert/type-meta/, @deepseek-ai/dsh-type-metatypert/protocol/, @deepseek-ai/dsh-typert-protocol该包拥有 Typert Remote 协议、装饰器、绑定、编解码器、查找逻辑和上下文约定。它不是通用类型元数据。
协议包中的 GatewayServiceTypertRemoteService该基类标记要导出为 Remote 的同进程服务。它不是 API 网关。
bindTypeRTGatewaytypertGateway 绑定bindTypertRemotetypertRemote这些绑定公开 Typert Remote 服务,而非具体的 API 网关服务。
公开的 TypeRT* 标识符和小驼峰形式的 typeRT* 标识符Typert*typert*Typert 是唯一规范的产品拼写。
协议接口 TypeRTServiceTypertRegistryContract该协议拥有的接口是现有具体类 TypertRegistry 所实现的依赖倒置接口。不同的后缀可避免导入和声明冲突。
ToolRegistryToolRuntime该类拥有呈现、审批与防护策略、分派、取消、验证、终结和观察。注册只是内部组成部分。
ToolRegistryScheduler, TOOL_REGISTRY_SCHEDULERToolRuntimeScheduler, TOOL_RUNTIME_SCHEDULER调度器控制运行时分派,而不是注册。

保留 @deepseek-ai/dsh-toolsctx.tools。保留 @deepseek-ai/dsh-api-gateway、其 gateway/ 目录、ctx.typertGateway 以及 TypertGatewayService;该服务是真正的 API 网关。其内部的 TypeRT* 标识符仍应遵循 Typert* 拼写规则。

工作区指令、遥测、身份和启动环境

旧名称当前名称理由
Host ctx.workspaceHost ctx.workspaceRegistryWorkspaceRegistry 拥有多个工作区,但 Client ctx.workspaces 已经使用不兼容的类型。即使二者运行时上下文独立,两份声明仍会在编译时合并进同一个 Cordis Context 接口。职责后缀明确指出 host 服务,并避免该冲突。保留 @deepseek-ai/dsh-workspaceWorkspaceRegistryWorkspaceworkspace.* 协议名称。
@deepseek-ai/dsh-workspace-context, context/workspace-context/@deepseek-ai/dsh-agent-instructions, context/agent-instructions/该包为 agent(智能体)加载分层的 AGENTS.mdCLAUDE.md 文件。它并非通用工作区上下文。
插件名称和持久来源名称 workspace-contextworkspace-instructionsagent-instructions记录的来源是一类具体的 agent 指令。以 AgentInstruction* 替换公开的 WorkspaceInstruction* 名称。该术语不包括系统消息、开发者消息或用户消息。
ctx.telemetry、抽象类 Telemetryctx.sessionTelemetrySessionTelemetryBackend该服务捕获会话账本遥测,并交给报告后端。它不是仓库级指标或追踪服务。
TelemetryBackendSessionTelemetrySink该底层接收已发出的记录。Sink 用于将它与协调型后端服务区分开。
TelemetryCoordinatorTelemetryRecordTelemetrySeverityTelemetrySharingStatusTelemetryCapture对应的 SessionTelemetry* 名称这些公开类型只属于会话遥测。
telemetry/recordsession-telemetry/record事件名称必须说明所属领域。
TelemetryOtelTelemetryMode,插件 telemetry-otelOpenTelemetrySessionBackendSessionTelemetryMode,插件 session-telemetry-otel提供方名称同时说明 OpenTelemetry 机制和会话作用域。保留包名 dsh-session-telemetrydsh-session-telemetry-otel
docs/subsystems/telemetry.mddocs/subsystems/session-telemetry.md该页面记录会话遥测,而不是仓库级可观测性。
session/user-id/, @deepseek-ai/dsh-user-ididentity/anonymous-user-id/, @deepseek-ai/dsh-anonymous-user-id该值是遥测、反馈和 DeepSeek 请求共用的随机关联 id。它既不属于 Session 领域,也不是经过身份验证的用户身份。
USER_ID_FILE_NAME.userid,反馈标签 UserANONYMOUS_USER_ID_FILE_NAME.anonymous-user-id,反馈标签 Anonymous user文件和 UI 不得暗示账户身份。保留现有 AnonymousUserId 函数和标准 OTel 属性 user.id
util/environment/, @deepseek-ai/dsh-environmentutil/launch-environment/, @deepseek-ai/dsh-launch-environment该包在启动时捕获一份不可变的分层快照。它不是通用环境 API。
公开的 Environment*createEnvironmentSnapshotenvironmentOfDSH_ENVIRONMENT_KEYLaunchEnvironment*createLaunchEnvironmentSnapshotlaunchEnvironmentOfDSH_LAUNCH_ENVIRONMENT_KEY这些名称说明快照的生命周期和用途。
ctx.launcherEnvironmentctx.launchEnvironment该值描述应用启动,而不只描述启动器组件。保留来源标签 processproject-envuser-env

日程、工作流、目标与压缩

旧名称当前名称理由
@deepseek-ai/dsh-tool-scheduleschedule/tool-schedule/、插件 tool-schedule@deepseek-ai/dsh-scheduleschedule/schedule/、插件 schedule该包拥有持久 Schedule 领域、持久化屏障、管理工具、定时器、后续轮次和运行时生命周期。tool- 只描述其中一部分。
ScheduleOwnerScheduleRuntime该逐 agent 对象运行实时定时器、持久化投影、分派、空闲等待和资源释放。Owner 没有说明这一执行职责。耦合的私有 owner* 名称也改用 runtime*
WorkflowService, ctx.workflowsWorkflowEngine, ctx.workflowEngine一个引擎负责解析并执行工作流程序。复数键错误地暗示这是注册表。保留 @deepseek-ai/dsh-workflow 以及工作流事件和工具。
@deepseek-ai/dsh-workflow-workerthread, WorkerWorkflowEngine@deepseek-ai/dsh-workflow-worker-thread, WorkerThreadWorkflowEngineworker thread 是准确的 Node 机制,仓库拼写要求使用完整单词。
@deepseek-ai/dsh-goal-session, goal/goal-session/@deepseek-ai/dsh-goal-round-driver, goal/goal-round-driver/该插件驱动同一会话内的 Goal Rounds。它既不存储目标,也不定义会话。保留 GoalService、目标来源、事件和约定。
packages/compact/packages/compaction/该组是以名词命名的领域系列。compact 仍作为面向用户的命令动词。
@deepseek-ai/dsh-compact, ctx.compact, CompactService@deepseek-ai/dsh-compaction, ctx.compaction, CompactionEngine该对象运行压缩(compaction)算法和生命周期。它是引擎,而不是通用服务。
compact/* 事件和公开领域前缀compaction/*事件和领域类型使用名词形式。保留动词形式的操作,例如 compactNowcompactRegioncompactIfNeeded
@deepseek-ai/dsh-compact-basicBasicCompactService、公开的 BasicCompact*@deepseek-ai/dsh-compaction-basicBasicCompactionEngine、对应的 BasicCompaction*basic 朴素但准确。compaction-llm 没有增加信息,因为当前实现系列已使用 LLM。
@deepseek-ai/dsh-compact-tool-result-prune, ToolResultPruneService, ctx.toolResultPrune@deepseek-ai/dsh-compaction-tool-result-pruner, ToolResultPruner, ctx.toolResultPruner该插件是剪除工具结果的执行主体。名词 pruner 说明了这一职责。

保留 /compact、命令包,以及相互独立的压缩定义包和提供方包。合并这些包的提议仍被否决。本次重命名只改变词汇,不改变该包边界。

设置、凭据、客户端模块和较小的核心职责

旧名称当前名称理由
抽象类 SettingsSettingsProvider该类通过可替换能力提供设置。保留包、键和事件。
@deepseek-ai/dsh-settings-local, SettingsLocal@deepseek-ai/dsh-settings-file, FileSettingsProvider该实现通过文件系统 seam 以文件为后端。file 说明机制,local 则不能。
抽象类 CredentialsCredentialProvider该类解析凭据引用。保留包名、键和事件。
CredentialsLocalLocalCredentialProvider该提供方读取宿主进程和 .env 状态,因此本地执行属于其约定。
ClientModuleHostService, ctx.clientModuleHostClientModuleRegistry, ctx.clientModules该服务拥有多个已注册的客户端模块。保留包和浏览器端的 ClientModuleLoader
AgentDefaultModelServiceAgentDefaultModelConfig该对象存储一项默认模型选择。它不运行服务,也不是通用注册表。保留其包、键、设置命名空间和类型。
SessionReferenceService, ctx.sessionReferencesSessionReferenceResolver, ctx.sessionReferenceResolver它从 URI 或输入解析一个会话引用,并不拥有引用集合。
SessionQueryService, SessionQuerySqliteSessionQueryEngine, SqliteSessionQueryEngine这些类执行查询模型及其 SQLite 实现。保留包名、键和工具。
@deepseek-ai/dsh-session-export, session-export/, Loader id session-export, ctx.sessionExport@deepseek-ai/dsh-session-log-export, session-log-export/, Loader id session-log-download, ctx.sessionLogDownloadnpm 包名使用 Session 日志导出语义,因为 npm 禁止包名包含 download。Loader id 与浏览器 API 保留 download,因为它们描述浏览器副作用。
SessionExportDownloadController, 其他 SessionExport* 浏览器类型、useSessionExportSessionExportHeaderSessionLogDownloadController, 对应的 SessionLogDownload* 类型、useSessionLogDownloadSessionLogDownloadHeaderAction该 controller 拥有预检、重复请求合并、弹窗状态和浏览器保存。ExportDownload 重复表达同一动作,该组件贡献的是一个 Header action,不是整个 Header。
宿主命令包中的 CommandServiceCommandRuntime该对象跨实时调用注册并执行宿主命令。保留其包、键、类型和事件。
TokenMeterServiceTokenMeter该对象测量 token 用量。Service 没有补充作用域信息。
LlmServiceLlmRuntime该对象选择提供方并运行实时模型请求。保留包、键、适配器和事件。

Host Web 服务器、会话数据与代码执行

旧名称当前名称理由
HttpServerService, ctx.httpServerWebServer, ctx.webServer该服务器拥有 HTTP 路由和 WebSocket 升级路由。Web 可以同时涵盖两者;此处的 Http 作用域过窄。保留 packages/host/webserver@deepseek-ai/dsh-host-webserverWebRouteWebUpgradeRoute
文档子系统标签 http-serverweb-server子系统标签必须与服务采用相同作用域。
SessionPersistenceJsonlJsonlSessionPersistence将实现限定词放在前面,同时完整保留能力职责。
SessionPersistenceSqliteSqliteSessionPersistence采用与 JSONL 相同的提供方命名顺序。
@deepseek-ai/dsh-session-title-first-message-llm,触发周期 first-message@deepseek-ai/dsh-session-title-first-prompt-llm,触发周期 first-prompt触发条件是第一条用户提示词,而不是会话日志中的任意消息。
@deepseek-ai/dsh-session-title-all-messages-llm,触发周期 all-user-messages@deepseek-ai/dsh-session-title-all-prompts-llm,触发周期 all-prompts后端根据用户提示词刷新。all messages 会错误地包含助手消息和工具事件。
@deepseek-ai/dsh-code-runtime-worker, WorkerCodeRuntime@deepseek-ai/dsh-code-runtime-worker-thread, WorkerThreadCodeRuntime该实现使用 Node 工作线程。单独的 worker 作用域过宽。
SubprocessServiceSubprocessRuntime该服务拥有实时子进程的执行和生命周期。保留其包和键。
LocalSubprocessServiceLocalSubprocessRuntime该提供方运行同主机进程和进程树。
E2BSubprocessServiceE2BSubprocessRuntime该提供方在 E2B 运行时中运行子进程。

保留完整的会话投影系列和 SessionProjection* 词汇。投影是持续维护的读取模型;Reducer 只说明其折叠操作,会淡化缓存和查找职责。保留 SessionTitleService、检查点策略、持久化包名、时间上下文和 tmux 上下文。

文件系统、skill、subagent 和 Web 提供方

旧名称当前名称理由
@deepseek-ai/dsh-fs-policy@deepseek-ai/dsh-fs-observation-policy该包定义哪些文件系统观察可以授权后续操作。它不是完整的文件系统策略或沙箱策略。
FsPolicyExecFsObservationActor该值表示策略所关联的观察与操作的执行主体。它本身不执行策略。
SkillServiceSkillRegistry该服务注册提供方,并从其目录解析 skill(技能)。
@deepseek-ai/dsh-skill-localLocalSkillProvider,提供方 id local@deepseek-ai/dsh-skill-filesystemFileSystemSkillProvider,提供方 id filesystem该提供方通过可位于本地或远端的 ctx.fs 发现 skill 文件。其机制是文件系统访问,而不是本地性。
SubagentServiceSubagentRuntime该服务选择提供方,并拥有实时 spawn、恢复、跟进、取消和结算行为。
@deepseek-ai/dsh-subagent-spawn, SpawnProvider@deepseek-ai/dsh-subagent-spawn-in-process, SpawnInProcessProvider该提供方在当前进程内启动子 agent。配置的提供方 id 仍为 spawn
@deepseek-ai/dsh-subagent-fork, ForkProvider@deepseek-ai/dsh-subagent-fork-in-process, ForkInProcessProvider该提供方在当前进程内 fork 一个 agent。配置的提供方 id 仍为 fork
@deepseek-ai/dsh-subagent-inprocess, subagent-inprocess/@deepseek-ai/dsh-subagent-in-process-driver, subagent-in-process-driver/该包包含通用的进程内驱动逻辑,而不是第三个提供方。
私有的 SdkProvider,位于 dsh-subagent-dsh-sdkSdkSubagentProvider重复的包限定词是有意保留的,类名还必须说明它通过 SDK 提供 subagent。
WebService, WebServiceConfigWebRuntime, WebRuntimeConfig该对象选择提供方并运行实时搜索和抓取操作。保留包、键、提供方包和模型工具。
@deepseek-ai/dsh-web-fetch-localLocalFetchProviderLocalFetchLimits,提供方 id local-http@deepseek-ai/dsh-web-fetch-httpHttpFetchProviderHttpFetchLimits,提供方 id http该提供方执行直接 HTTP 抓取。local 只说明代码恰好在哪里运行,并未说明它提供哪种机制。

保留 @deepseek-ai/dsh-subagent-dsh-sdk、其提供方 id dsh-sdk、外部 ACP(Agent Client Protocol)、Codex 和 Claude Code 提供方系列、subagent 工具包名、主文件系统包和后端、文件系统工具和事件,以及 skill 徽章和工具包。

钩子、防护、Plan Mode、扩展与诊断

旧名称当前名称理由
@deepseek-ai/dsh-hooks-claudeClaudeHookConfigparseClaudeConfig,方言 claude@deepseek-ai/dsh-hooks-claude-codeClaudeCodeHookConfigparseClaudeCodeConfig,方言 claude-code该钩子桥接面向 Claude Code,而非所有 Anthropic 或 Claude 产品。
@deepseek-ai/dsh-repeat-tool-guard,插件/来源 repeat-tool-guard@deepseek-ai/dsh-repeat-tool-reminder,插件/来源 repeat-tool-reminder该插件向模型添加提醒,并不阻止工具调用,也不执行防护决策。
@deepseek-ai/dsh-timeout-policy@deepseek-ai/dsh-tool-call-timeout-policy完整的 tool-call 限定词说明该策略限制的对象,而不会把插件称为面向模型的工具。保留其 guard/timeout-policy/ 目录和插件 id timeout-policypackages/*/tool-* 目录约定仍只适用于注册工具的包。
PlanModeServicePlanModeController该对象控制进入和退出计划模式的状态转换,而不是通用执行运行时。
packages/self-modification/packages/extensions/该组包含仓库插件检查和挂载工具。extensions 说明稳定的包职责,但不声称 agent 会修改自身。保留包名 tool-cordis 和仓库插件名称。
packages/support/packages/test-support/该组仅包含测试基础设施,其路径必须明确说明这一点。
原 support 系列中的 invariants/runtime-diagnostics/invariants/尽管交付预设未包含不变量检查,它们仍可在生产诊断中运行,因此不属于测试支持。
InvariantServiceInvariantRegistry该对象拥有已注册的不变量检查。保留 @deepseek-ai/dsh-invariantsctx.invariants
packages/client/test-runtime/packages/test-support/client-runtime/该包是客户端测试基础设施。如果现有 NPM 名称已经说明这一约定,则予以保留。

保留 MCP、Todo、Plan Mode 包、键、事件和工具名称。本决策重命名控制器类,而不是产品功能。

实用工具、E2B、Host、组合包、示例与应用

旧名称当前名称理由
util/paths/, @deepseek-ai/dsh-pathsutil/home-paths/, @deepseek-ai/dsh-home-paths这些辅助函数解析 Harness 主目录下的路径,并非通用路径库。已准确说明返回路径的函数名保持不变。
util/retention/, @deepseek-ai/dsh-retentionutil/output-retention/, @deepseek-ai/dsh-output-retention该策略保留命令和工具输出,而不是通用数据保留框架。
E2BSandboxServiceE2BRuntime该类创建、复用和释放文件系统与子进程适配器所使用的 E2B 执行环境。它比单个沙箱句柄的职责更广,又比通用所有者更具体。保留 @deepseek-ai/dsh-e2bctx.e2be2b/ 组。
@deepseek-ai/dsh-frontend-static@deepseek-ai/dsh-host-frontend-static该包是提供前端资源的 Host 插件。此前缀可将它与前端应用代码区分开。
PluginInventoryServicePluginInventoryGateway该类只负责把实时 Loader 树适配到 pluginInventory/list RPC。它不拥有同进程服务、缓存、历史或修改路径。Gateway 准确说明现有角色。
@deepseek-ai/dsh-jsonrpc-demo@deepseek-ai/dsh-sdk-jsonrpc-demo该示例演示通过 JSON-RPC 使用运行时 SDK,属于 SDK 的唯一含义。
@deepseek-ai/dsh-frontend@deepseek-ai/dsh-web-frontend该应用是 Web 前端。保留其物理目录 apps/web/

保留 atomic-write、brand、native-command、timeout 实用工具、目录选择器、dsh-basedsh-web-app、应用启动、CLI(命令行界面)名称,以及 headless 包、组合包和示例身份。headless 是预期的产品本质,未来也可以支持不止一次性执行。

客户端运行时与 UI

旧名称当前名称理由
SlotsServiceSlotRegistry该对象拥有具名 slot 声明和注册项。
SessionsServiceSessionRuntime该对象拥有实时客户端会话协调职责,而不是被动的会话列表。
WorkspacesServiceWorkspaceRuntime该客户端对象协调实时工作区选择和操作。如果清单未点名更改某个现有 ctx 键,则该键保持不变。
WorkspaceGroupByWorkspaceOrderByworkspaceExpansionsetWorkspaceExpandedexpandedProjectsprojectLabelrecentSessionOrderrecentSessionUpdatedAtsyncRecentSessionssetRecentSessionOrderretainWorkspaceKeysworkspaceKeySessionGroupBySessionOrderBygroupExpansionsetGroupExpandedexpandedGroupsworkspaceLabelsessionOrderByAccountsessionUpdatedAtByAccountsyncSessionOrderAccountsetSessionOrderretainAccountKeysaccountKey这些名称描述的是会话列表查看状态。其 account 包括真实工作区、未分组项和平铺列表。因此,Workspaceprojectrecent 指向了错误的对象或机制。保留 WorkspaceViewState;该存储仍属于工作区浏览器。
LocaleServiceLocaleRuntime该对象协调区域设置定义、选择、持久化和变更发布。
ThemeServiceThemeRuntime该对象协调主题、偏好解析、系统感知和变更发布。
LayoutServiceLayoutController该对象控制当前 UI 布局状态。
@deepseek-ai/dsh-client-ui-model@deepseek-ai/dsh-client-ui-model-selection该包控制会话的模型选择。单数 model 名称作用域过宽。
ModelService, ctx.modelsModelDirectoryResolver, ctx.modelDirectories它唯一的公开操作 directoryFor(sessionId) 为每个实时会话解析并保留一个目录。它没有注册 API,因此使用 Registry 并不准确。每个 ModelDirectory 仍是面向消费方的可选模型目录。
SettingsScopeServiceSettingsScopeBinder它唯一的操作把一份命名空间规范绑定到调用方的传输层和生命周期,并返回 SettingsScopeController。保留 ctx.settingsScope;它命名的是单一绑定能力,而不是 scope 集合。
@deepseek-ai/dsh-client-ui-models@deepseek-ai/dsh-client-ui-settings-models该包拥有 Models 设置面板。保留 ModelsSettingsStore;它保存一个具有数据操作和订阅能力的设置视图模型,确实是存储。
@deepseek-ai/dsh-client-ui-plugin-configclient/ui-plugin-config/@deepseek-ai/dsh-client-ui-settings-pluginsclient/ui-settings-plugins/该包拥有 Plugins 设置分区,而不是通用的插件配置系统。目标名称归入 ui-settings-* 系列,并采用该分区的复数产品名。
PluginConfigSectionPluginConfigSectionPropsPluginConfigSectionInjectedPluginSettingsTabRowPluginConfigKeysettings.pluginConfigPluginsSettingsSectionPluginsSettingsSectionPropsPluginsSettingsSectionInjectedPluginsSettingsTabEntryPluginsSettingsLocaleKeysettings.plugins该分区拥有 Plugins 设置呈现和 tab 清单。元数据值表示一项 slot entry,而不是一条渲染行。每张卡片仍编辑一个插件的配置。
@deepseek-ai/dsh-client-ui-pluginsclient/ui-plugins/、Loader id ui-pluginsclient-ui-plugins-invariant@deepseek-ai/dsh-client-ui-settings-plugin-inventoryclient/ui-settings-plugin-inventory/、Loader id ui-settings-plugin-inventoryclient-ui-settings-plugin-inventory-invariant这个后来加入的包拥有 Plugins 设置分区中的只读 Plugin Inventory tab。ui-plugins 作用域过宽,也无法将该清单与可编辑插件设置区分开。
ui-plugins 包中的 PluginSettingsSectionPluginSettingsSectionPropsPluginSettingsSectionInjectedPluginsKeysettings.pluginsPluginInventorySettingsTabPluginInventorySettingsTabPropsPluginInventorySettingsTabInjectedPluginInventoryLocaleKeysettings.pluginInventory该组件现在贡献一个 tab,而不是设置分区。其余名称明确说明清单主题,并避免与 PluginsSettingsSection 及其 settings.plugins 区域设置命名空间冲突。保留共享的 settings.plugins.tab slot 名;两个 tab 都通过该 slot 向 Plugins 分区贡献内容。
@deepseek-ai/dsh-client-ui-feedbackclient/ui-feedback/、Loader id ui-feedbackclient-ui-feedback-invariant@deepseek-ai/dsh-client-ui-message-feedbackclient/ui-message-feedback/、Loader id ui-message-feedbackclient-ui-message-feedback-invariant这个包通过 messageFeedback Remote 展示 assistant 消息的评分和说明。旧名称看起来还涵盖 command feedback 和以后可能出现的其他反馈界面,但实际并非如此。
ui-feedback 包中的 FeedbackControllerFeedbackStatusFeedbackViewFeedbackActionResultFeedbackInjectedFeedbackActionPropsFeedbackActionsFeedbackKeyMessageFeedbackControllerMessageFeedbackStatusMessageFeedbackViewMessageFeedbackActionResultMessageFeedbackInjectedMessageFeedbackActionPropsMessageFeedbackActionsMessageFeedbackKey这些名称会从 Client 包导出。增加 Message 限定词,避免它们声称代表所有反馈领域。保留 Controller:该对象接受评分和说明操作,并协调一个 Session 的加载、修改、冲突、重连和释放状态。
agent-loop-store.tsbash-store.tsweb-search-store.tsagent-loop-card-controller.tsbash-card-controller.tsweb-search-card-controller.ts每个模块都导出一个卡片控制器。私有 SnapshotStore 字段不会让模块成为存储。
card-store.tscard-form.ts该模块拥有暂存表单、字段转换和表单操作。它返回的快照存储是呈现适配器,而不是模块的主要职责。
@deepseek-ai/dsh-client-ui-question@deepseek-ai/dsh-client-ui-user-questionsUI 呈现用户问题 seam,而不是任意问题领域。
@deepseek-ai/dsh-client-ui-command, ui-command/@deepseek-ai/dsh-client-ui-commands, ui-commands/该包呈现并运行一组命令。
@deepseek-ai/dsh-client-ui-directory-pickerclient/ui-directory-picker/、Loader id ui-directory-pickerclient-ui-directory-picker-invariant@deepseek-ai/dsh-client-ui-directory-picker-browseclient/ui-directory-picker-browse/、Loader id ui-directory-picker-browseclient-ui-directory-picker-browse-invariant客户端包现已拆成 browsenative 两种目录选择器呈现。未加限定词的包实际只是 browse 实现,并非两者的共同定义。目标名称与 Host 后端系列一致,不改变边界。
客户端 ctx.commandCommandServiceCommandServiceContractctx.commandUiCommandUiRuntimeCommandUiContractHost 已拥有 ctx.commands。该客户端服务是命令发现和执行的 UI 运行时。现有 CommandUiSpec 确立了 Ui 大小写格式。
ConversationServiceConversationController该对象控制当前对话状态和用户操作。
InputServiceSessionInputResolver该接口为一个会话作用域解析输入外观。它既不是全局输入注册表,也不是执行服务。保留 InputHub 作为具体中枢,并保留 ctx.conversation.input 作为对外接口。

PascalCase 标识符内部使用 Ui,不要使用 UI。除非清单明确要求重命名,否则保留其余客户端包名。暂时保留已弃用的客户端连接和 Host ApiProxy 词汇;API 平面将替换它们,而在计划移除的表面上重命名只会增加改动量。

明确保留的名称

以下经过讨论的名称保持不变,因为当前作用域准确,或重命名会制造虚假概念:

  • 保留完整的 sandbox 系列和 ctx.sandbox。不得引入 processSandbox
  • 保留 @deepseek-ai/dsh-api-gatewayctx.typertGatewayTypertGatewayService
  • 保留会话投影名称。投影并不只是归约函数。
  • 保留 @deepseek-ai/dsh-session-statssessionStatsSessionStatsProjection。这些名称准确表示全会话统计数据及承载它们的持续维护读模型。
  • 保留 GoalService;它拥有目标状态机、裁决权、比较并设置行为、事件和远程操作,不只是存储。
  • 保留 SessionTitleService;它的职责是由多个标题提供方共享的领域服务。
  • 保留 PermissionPresetSettingsController,即使它很长。每个词都在限定其职责。
  • 保留 ModelsSettingsStore;其主要约定是一个具有存储操作的设置数据模型。
  • 保留 InputHub;它是支撑 SessionInputResolver 的具体中枢。
  • 保留 dsh-subagent-dsh-sdk 和提供方 id dsh-sdk;重复的限定词可避免歧义。
  • 保留 headless;即使运行时以后支持不止一次性使用,该产品身份仍然准确。
  • 保留已弃用的 Host ApiProxy 和客户端连接名称,直至 API 替代方案将其移除。
  • Host 服务器和提供方无关的 Web 能力都保留 Web。仅直接抓取提供方使用 HTTP
  • 保留 E2B 作为包名和上下文名称,不改为 E2B sandbox
  • 保留 MCP、Todo、应用启动、基础组合包、web-app 组合包和 CLI 名称。保留目录选择器能力和 Host 后端名称;只重命名未加限定词的 Client browse 呈现。
  • 保留 @deepseek-ai/dsh-client-ui-directory-picker-native;其后缀说明它是在重命名后的 -browse 变体旁使用原生选择器的呈现。保留 SURFACE_PACKAGES;在目录选择器自动选择器中,它是客户端呈现端面的包映射,并与 BACKEND_PACKAGES 对照。
  • 保留 @deepseek-ai/dsh-host-plugin-inventoryctx.pluginInventorypluginInventory/list Remote 以及 PluginInventory* 载荷类型。它们准确命名由 Host 拥有的只读清单;只有适配器类和作用域过宽的客户端呈现名称需要修改。
  • 保留 ConfigurablePluginsTab。该 tab 渲染具有可编辑配置的插件,不拥有完整的 Plugins 设置分区。
  • 保留共享的 settings.plugins.tab slot。它属于 Plugins 设置分区。清单包只把自己的 locale namespace 改为 settings.pluginInventory,不会创建独立的 tab slot。
  • 保留 @deepseek-ai/dsh-message-feedback 能力、messageFeedback Remote、assistant-action entry id feedback、hook key feedback 和 locale namespace feedback。它们所在的接口已经把作用域限定为消息反馈或本地 assistant-message slot。只修改作用域过宽的 Client 包名和导出的 UI 名称。
  • 保留 RemoteFailureRemoteResultSessionRemotes。前两者是 Typert 载体结果值,后者是客户端 Session 集群使用的一组 Remote 命名空间。它们都不是 store、controller、registry 或 runtime。
  • 保留用户命令 /export、Host 路由 /api/session.exportDownloadsApi 及其 sessionLog 操作。命令说明用户动作,Host 路由导出归档,API 则归类直接 HTTP 下载。重命名的 Client controller 拥有独立的浏览器下载步骤。
  • 测试文件名保留 .client.host。它们标识测试进入的编译端面,不声称产品职责。

考虑过的替代方案

**保留现有名称并添加词汇表。**不予采纳。词汇表无法让由 PowerShell 实现的 BashExecutor 名副其实,也无法让 ToolRegistry 表明它会执行并强制实施工具策略。标识符本身必须承载有用的区别。

**为每个 NPM 包添加所属组前缀。**不予采纳。扁平的 NPM 名称不需要复刻目录树。机械添加前缀只会增加长度,无法解释包的职责。

**将整个仓库称为 SDK。**不予采纳。该项目是 agent harness(智能体框架)。SDK 是 Python 和 TypeScript 客户端使用的、受支持的 JSON-RPC 客户端/服务器栈。一词两义会使包名和产品文案产生歧义。

**所有 Cordis 服务类都使用 Service。**不予采纳。Cordis 继承只是实现事实。类名必须告诉调用方该对象负责注册、存储、解析、控制还是运行工作。

**统一使用 Runtime 替换 Service。**不予采纳。只有对象拥有实时执行或生命周期时,Runtime 才正确。注册表、存储、目录、控制器、解析器、引擎和配置对象都应保留更精确的职责名。

**优先使用最短的名称。**不予采纳。只有作用域明确之后,简短才有价值。PermissionPresetSettingsController 保留 PresetJobId 简短,是因为 Job 已经表明领域;BgTaskId 虽短,却晦涩难懂。

**为未来可能出现的功能使用宽泛名称。**不予采纳。应按稳定的当前职责命名。未来若要改变边界,可以在发布前再次重命名对象,或在发布后另写提案。含义模糊的名称会让每位当前读者为尚未构建的未来付出理解成本。

**将 dsh-compact-basic 重命名为 dsh-compaction-llm。**不予采纳。LLM 没有在当前后端系列中增加区别。basic 意图更克制,也不会声称存在一个实际并不存在的算法。

**将会话投影重命名为归约器。**不予采纳。归约只是构建投影的方式。该包还拥有读取模型值、缓存和查找约定。

**将持久 Bash 工具重命名为 bash-terminal。**不予采纳。该名称与终端会话系列冲突。将 tool-bash-persistent 移到 shell/ 可以纠正其归属位置,同时现有名称仍能将其与一次性 Bash 工具区分开。

**应用清单时一并重命名或拆分边界。**不予采纳。评审人必须能够确认行为没有改变。真正的边界缺陷需要独立提案、测试和后果分析。

**为旧名称保留别名。**不予采纳。没有已发布的消费方需要这些别名。别名会保留两套词汇,使首次发布携带一项从未有用户需要的迁移。

验证

  • 清单中的每项映射都出现在仓库中。每个系列只有一套公开词汇;同一个 Cordis 上下文中没有兼容包、重新导出别名、重复的 ctx 键、双重插件 id、双重事件 id、旧工具别名或回退解析器。
  • 运行时行为、包边界、默认值、策略、持久化语义和模型行为保持等价,只有标识符本身可见时除外。
  • 包目录、NPM 名称、导入、manifest(元数据清单)、TypeScript 引用和路径、Cordis 配置、插件 id、服务键、事件、工具、RPC 名称、清单点名的持久化名称、fixture、快照、示例、生成的目录和当前文案都使用已实现词汇。
  • 当前处于 implemented 状态的 Agent Note 使用事实名称和路径。包重新分组说明记录分组清单和包名目标,SDK 移除说明将 SDK 限定为运行时协议,超时策略说明记录包名理由。
  • 配对的包创建指南包含职责词约定,packages/AGENTS.md 链接到该约定,术语表记录选定用词和 Typert 拼写,根项目文案将产品称为 DeepSeek Harness,而不是 DeepSeek Harness SDK。
  • 已移除的 SDK 项目工具链继续保持不存在。
  • pnpm run check:ci 覆盖源代码平面的类型检查、构建、包卫生检查、生成参考资料检查、受影响的快照、翻译配对、doc-sync 和 lint。发布形态的 Python 运行时冒烟测试和必需 CI 覆盖打包运行时与平台路径。

后果

仓库为每个重命名系列保留一套词汇。清单点名的旧磁盘名称、协议值、工具名称和配置项不再工作。能够识别陈旧配置的所属解析器会明确报错,而不是同时接受两种形式。

一些名称更长。额外增加的词只有在防止误述权限或机制时才有意义。如果名称中的词不能全部限定职责,长名称仍然错误。

职责后缀不能替代对行为的检查。包创建指南保留本决策中的直接判断方式:检查调用方执行什么操作、对象拥有什么生命周期,以及对象控制什么失败或策略。

基于旧路径和旧符号的分支需要解决冲突。这是发布前移除旧词汇且不保留兼容别名的一次性成本。