---
title: "Architecture decisions"
description: "BotHarness 架构决策的历史、状态与理由"
version: "zh"
---

> Documentation Index
> Fetch the complete documentation index at: https://botharness.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture decisions

ADR 解释一项架构取舍为什么成立。把决策当作当前约束前，应先查看状态；[living architecture](/zh/dev/design/architecture) 是整合后的当前视图。

<details>
<summary>全部决策（131）</summary>

- [Adopt dsh-im as the base plugin](/zh/dev/adr/0001-adopt-dsh-im-as-base-plugin)
- [Build Bot memory in-house, file-first](/zh/dev/adr/0002-file-first-self-built-bot-memory)
- [Memory is written only through explicit tools](/zh/dev/adr/0003-memory-writes-are-tool-driven)
- [Inject the memory tree; retrieve bodies on demand](/zh/dev/adr/0004-inject-memory-tree-retrieve-on-demand)
- [SQLite is an optional index, never a system of record](/zh/dev/adr/0005-sqlite-is-an-optional-index) — Superseded by ADR-0037 and ADR-0041
- [Feishu app secrets live in the DSH credentials service](/zh/dev/adr/0006-feishu-secrets-in-dsh-credentials-service)
- [Configuration and management UI lives inside DSH](/zh/dev/adr/0007-configuration-ui-is-in-harness)
- [Archive inbound chat files into the Bot workspace](/zh/dev/adr/0008-archive-inbound-chat-files) — Superseded in part by ADR-0037
- [Reply scope defaults to thread-first](/zh/dev/adr/0009-reply-scope-defaults-to-thread-first) — amended by ADR-0011
- [Keep self-built capabilities in-repo for now](/zh/dev/adr/0010-upstream-contribution-deferred)
- [Integrate as a standalone DSH plugin, not a dsh-im fork](/zh/dev/adr/0011-standalone-plugin-not-a-dsh-im-fork)
- [Adopt YAML front-matter for memory files](/zh/dev/adr/0012-adopt-yaml-front-matter)
- [Memory is one brain with per-entry visibility](/zh/dev/adr/0013-memory-visibility)
- [Persona is a human-owned memory file](/zh/dev/adr/0014-persona-is-human-owned-memory)
- [Ship BotHarness as a DSH plugin layer, not a fork](/zh/dev/adr/0015-botharness-is-a-dsh-plugin-layer)
- [PersonaBots are first-class entities; sessions are their execution](/zh/dev/adr/0016-bots-are-first-class-entities)
- [Assignments are represented by Sessions; there is no Task entity](/zh/dev/adr/0017-assignments-are-sessions-no-task-entity)
- [A workspace is a single directory](/zh/dev/adr/0018-workspace-is-one-directory)
- [The Soul registry is a hosted service](/zh/dev/adr/0019-soul-registry-is-a-hosted-service)
- [SoulSnapshot is an immutable, content-addressed package](/zh/dev/adr/0020-soul-snapshot-is-content-addressed)
- [Memory has no visibility](/zh/dev/adr/0021-memory-has-no-visibility)
- [Plugin config uses the Cordis channel; settings cards are deferred](/zh/dev/adr/0022-dsh-config-and-manifest-conformance)
- [The client bridge is read-model RPC, not Cordis injection](/zh/dev/adr/0023-client-bridge-is-rpc-not-cordis)
- [One Orchestrator Session per PersonaBot; Assignment Sessions are independent](/zh/dev/adr/0024-orchestrator-session-per-personabot)
- [The Inbox is an event-stream projection, and its triggers are configurable](/zh/dev/adr/0025-inbox-is-event-stream-with-triggers)
- [Channels are platform-native spaces; Binding connects a PersonaBot to any surface](/zh/dev/adr/0026-channels-are-platform-native)
- [Model selection is local; the SoulSnapshot stays model-agnostic](/zh/dev/adr/0027-model-selection-is-local)
- [In-harness UI follows the DSH design system; COSS stays on the docs site](/zh/dev/adr/0028-in-harness-ui-uses-dsh-design-system)
- [Bot mode is chat-first; PersonaBot navigation keeps Assignment subordinate](/zh/dev/adr/0029-bot-mode-information-architecture)
- [Channel history is an append-only file log; SQLite is only an optional index](/zh/dev/adr/0030-channel-history-is-append-only-files) — Superseded by ADR-0037
- [Sidebar organization is per scope: sections, sort modes, and 未分组](/zh/dev/adr/0031-sidebar-organization-model) — Accepted
- [Default avatars are deterministic blobatars; missing glyphs are vendored, not cloned](/zh/dev/adr/0032-avatar-identity-and-icons) — Superseded by ADR-0049
- [DSH Dev Docs and the dsh-skill mirror](/zh/dev/adr/0033-dsh-dev-docs-and-skill-mirror) — Accepted; scope amended 2026-09-20
- [The persistence map: files, storage domains, and the host/client split](/zh/dev/adr/0034-persistence-map-and-host-client-split) — Superseded in part by ADR-0041
- [Session ownership is explicit, exclusive, and Registry-owned](/zh/dev/adr/0035-session-ownership-is-explicit) — Accepted
- [Messaging commands own every Messaging write](/zh/dev/adr/0036-messaging-commands-own-messaging-writes) — Accepted
- [Messaging facts share one BotHarness-owned SQLite transaction](/zh/dev/adr/0037-messaging-facts-share-one-sqlite-transaction) — Accepted
- [Provider Capabilities and Service Grants gate external actions](/zh/dev/adr/0038-provider-capabilities-and-service-grants-gate-external-actions) — Accepted
- [The external outbox is durable and idempotent, not exactly-once](/zh/dev/adr/0039-external-outbox-is-idempotent-but-not-exactly-once) — Accepted
- [PersonaBot Export wraps Soul and selected operational facets](/zh/dev/adr/0040-personabot-export-wraps-soul-and-optional-operational-facets) — Accepted
- [One database owns all BotHarness operational state](/zh/dev/adr/0041-one-database-owns-botharness-operational-state) — Accepted
- [Profile Backup coordinates BotHarness state and optional DSH Sessions](/zh/dev/adr/0042-profile-backup-coordinates-database-files-and-dsh-sessions) — Accepted
- [Profile Transfer prevents identity split brain across Hosts](/zh/dev/adr/0043-profile-transfer-prevents-identity-split-brain) — Accepted
- [Restore revalidates target runtime dependencies](/zh/dev/adr/0044-restore-revalidates-target-runtime-dependencies) — Accepted
- [Orchestrator manages Assignments through a durable directory](/zh/dev/adr/0045-orchestrator-manages-assignments-through-a-durable-directory) — Accepted
- [PersonaBot IDs are Host-owned; names and role badges are Human-facing](/zh/dev/adr/0046-personabot-id-name-and-role-badges) — Accepted
- [Memory is a default Git-backed Service with file-first Agent access](/zh/dev/adr/0047-memory-is-an-optional-git-backed-service) — Accepted
- [Workspace Grants authorize single-cwd Assignments](/zh/dev/adr/0048-workspace-grants-authorize-single-cwd-assignments) — Accepted
- [PersonaBot activity is a projection with live Cordis notifications](/zh/dev/adr/0049-personabot-activity-is-a-projection-with-live-events) — Accepted
- [Computer use is an optional standalone package mirroring the DSH provider seam](/zh/dev/adr/0050-computer-use-is-an-optional-standalone-package) — Superseded in part by ADR-0079
- [A Computer is a profile-scoped shared resource; PersonaBots are not a security boundary](/zh/dev/adr/0051-computer-is-a-profile-scoped-shared-resource) — Accepted
- [Computer storage stays on a named volume; portability is an explicit profile-level export](/zh/dev/adr/0052-computer-storage-and-export) — Accepted
- [Channel sidebar is the scoped right sidebar of Bot mode](/zh/dev/adr/0053-channel-sidebar-is-the-scoped-right-sidebar) — Accepted
- [Channel live delivery follows durable commit](/zh/dev/adr/0054-channel-live-delivery-follows-durable-commit) — Accepted
- [The Computer pulls the upstream webtop image and runs under hard resource bounds](/zh/dev/adr/0055-computer-runs-the-upstream-webtop-image-under-resource-bounds) — Accepted
- [BotHarness owns a settings section instead of adding rows to the native General page](/zh/dev/adr/0056-botharness-owns-a-settings-section) — Accepted
- [The Bot mark is a user-chosen asset; the shell-owned Settings nav wears it by DOM tagging](/zh/dev/adr/0057-the-bot-mark-is-a-user-chosen-asset) — Accepted
- [Computer settings are runtime settings, contributed into the BotHarness section through a child slot](/zh/dev/adr/0058-computer-settings-are-runtime-settings) — Accepted
- [Assignment collaboration round-trips through the Bot Inbox](/zh/dev/adr/0059-assignment-collaboration-round-trips-through-the-bot-inbox) — Accepted
- [The system prompt prefix is append-only](/zh/dev/adr/0060-system-prompt-prefix-is-append-only) — Accepted
- [Channel timeline pages use Host-owned opaque cursors](/zh/dev/adr/0061-channel-timeline-uses-opaque-cursors) — Accepted
- [Computer exports quiesce the browser, and durable work lives in ~/workspace](/zh/dev/adr/0062-computer-volume-quiesce-and-workspace) — Accepted
- [Operational logs live in a separate database file](/zh/dev/adr/0063-operational-log-database) — Accepted
- [Agent log access needs no dedicated tool](/zh/dev/adr/0064-agent-log-access-without-a-tool) — Accepted
- [PersonaBots collaborate through Channels](/zh/dev/adr/0065-bots-collaborate-through-channels) — Accepted
- [The RC2 Client Bundle has an unambiguous package identity](/zh/dev/adr/0066-rc2-client-bundle-identity) — Accepted
- [Workspace Grants bound PersonaBot file access](/zh/dev/adr/0067-workspace-grants-bound-personabot-file-access) — Accepted
- [The checked-out Git working tree is current Memory](/zh/dev/adr/0068-git-working-tree-is-current-memory) — Accepted
- [Selected Channel references do not grant membership](/zh/dev/adr/0069-selected-channel-references-and-bot-join-requests) — Accepted
- [Bot Inbox read models project canonical Admissions](/zh/dev/adr/0070-bot-inbox-projects-canonical-admissions) — Accepted
- [Human Inbox projects canonical Channel attention](/zh/dev/adr/0071-human-inbox-projects-channel-attention) — Accepted
- [PersonaBot sidebar projects owned DSH Sessions](/zh/dev/adr/0072-personabot-sidebar-projects-owned-dsh-sessions) — Accepted
- [Group membership is invitation-first with default auto-accept](/zh/dev/adr/0073-group-membership-is-invitation-first-with-auto-accept) — Accepted
- [A PersonaBot owns its Channel attention preference](/zh/dev/adr/0074-channel-attention-preference-belongs-to-the-personabot) — Accepted
- [Inbox handling classifies by Source class, not platform](/zh/dev/adr/0075-inbox-handling-classifies-by-source-not-platform) — Accepted
- [A PersonaBot manages its own attention policy](/zh/dev/adr/0076-a-personabot-manages-its-own-attention-policy) — Accepted
- [Turn-time harvest consumes the ready attention set](/zh/dev/adr/0077-turn-time-harvest-consumes-the-ready-attention-set) — Accepted
- [Local Human Group receipts use member identity](/zh/dev/adr/0078-local-human-group-receipts-use-member-identity) — Accepted
- [Adopt the official computer-use seam with a BotHarness-owned provider](/zh/dev/adr/0079-adopt-official-computer-use-seam-with-own-provider) — Accepted
- [Computer Access is per-PersonaBot; Computer Authorization is session-scoped and Human-owned](/zh/dev/adr/0080-computer-access-is-per-personabot-authorization-is-session-scoped) — Accepted
- [Group management keeps Human invitations and avatars on the Channel authority](/zh/dev/adr/0081-group-management-uses-channel-authority) — Accepted
- [Computer Target is profile-scoped: local by default, container for headless hosts](/zh/dev/adr/0082-computer-target-is-profile-scoped-local-by-default) — Accepted
- [Bot Screens are window-scoped work surfaces; per-Bot displays are an experimental opt-in](/zh/dev/adr/0083-bot-screens-are-window-scoped-first-displays-experimental) — Accepted
- [Memory continuity is agent-mediated Git plus Portability](/zh/dev/adr/0084-memory-continuity-is-agent-git-plus-portability) — Accepted
- [PersonaBot Profile is a popover plus a Channel-body view with registered Profile Cards](/zh/dev/adr/0085-personabot-profile-is-a-popover-and-a-channel-body-view) — Accepted
- [Custom PersonaBot avatars are bounded data URLs served by a read route](/zh/dev/adr/0086-custom-personabot-avatars-are-bounded-data-urls) — Accepted
- [DSH compatibility is a SemVer range whose floor is the verified host line](/zh/dev/adr/0087-dsh-compatibility-is-a-semver-range-with-a-verified-floor) — Accepted
- [Memory files and evolution use separate Channel views](/zh/dev/adr/0088-memory-files-and-evolution-are-separate-channel-views) — Accepted
- [Browser use is a profile-scoped managed Bot Browser](/zh/dev/adr/0089-browser-use-is-a-profile-scoped-managed-bot-browser) — Accepted
- [Browser Access is per-PersonaBot; Browser Authorization is session-scoped and Human-owned](/zh/dev/adr/0090-browser-access-is-per-personabot-authorization-is-session-scoped) — Accepted
- [Bot Tabs are window-scoped work surfaces on the shared Bot Browser](/zh/dev/adr/0091-bot-tabs-are-window-scoped-work-surfaces) — Superseded in part by ADR-0095
- [Memory changes enter Bot Inbox with durable observations](/zh/dev/adr/0092-memory-changes-enter-bot-inbox-with-durable-observations) — Accepted
- [Model Presets are local snapshots; each Session owns its model route](/zh/dev/adr/0093-model-presets-are-local-snapshots)
- [Keep model usage as a Bot-owned retained statistic](/zh/dev/adr/0094-retain-per-model-usage-after-session-deletion)
- [Bot tabs are background tabs on the shared Bot Browser](/zh/dev/adr/0095-bot-tabs-are-background-tabs-on-the-shared-bot-browser) — Accepted
- [Bot Browser profiles are named and assignable per PersonaBot](/zh/dev/adr/0096-bot-browser-profiles-are-named-and-assignable-per-personabot) — Accepted
- [Memory recovery checkpoints separate observation from Git authorship](/zh/dev/adr/0097-memory-recovery-checkpoints-separate-provenance-from-git-authorship) — Accepted
- [Activity Center separates overview from the personal Human Inbox](/zh/dev/adr/0098-activity-center-separates-overview-and-human-inbox) — Accepted
- [A Human's all-Bot Group mention expands to ordinary direct mentions](/zh/dev/adr/0099-human-all-bot-mention-expands-to-direct-mentions) — Accepted
- [File opening targets real Host files](/zh/dev/adr/0100-file-open-actions-target-real-host-files) — Accepted
- [External Grants require authenticated accounts and checked targets](/zh/dev/adr/0101-external-grants-require-authenticated-accounts-and-checked-targets) — Accepted
- [Model Channel reads budget content before consumption](/zh/dev/adr/0102-model-channel-reads-budget-content-before-consumption) — Accepted
- [Local Human names label one stable identity across Channels](/zh/dev/adr/0103-local-human-names-label-one-identity-across-channels) — Accepted
- [Isolated IM Profiles pin a qualified temporary provider fork](/zh/dev/adr/0104-isolated-im-profiles-pin-a-qualified-temporary-provider-fork) — Accepted
- [Attachments use native file operations under their trusted source authority](/zh/dev/adr/0105-attachments-use-native-file-operations-under-source-authority) — Accepted
- [Exclusive IM intake commits Bot Inbox before acknowledgement](/zh/dev/adr/0106-exclusive-im-intake-commits-bot-inbox-before-acknowledgement) — Accepted
- [External files use trusted source capabilities and the existing Attachment owner](/zh/dev/adr/0107-external-files-use-trusted-source-capabilities-and-existing-owner) — Accepted
- [Shared Channel bridges place canonical external sources](/zh/dev/adr/0108-shared-channel-bridge-places-canonical-external-sources) — Accepted
- [External group collection is separate from wake](/zh/dev/adr/0109-external-group-collection-is-separate-from-wake) — Accepted
- [External Thread following is scoped and explicit](/zh/dev/adr/0110-external-thread-following-is-scoped-and-explicit)
- [ADR-0111: External identity lifecycle is independent of conversation grants](/zh/dev/adr/0111-external-identity-lifecycle-is-independent-of-grants)
- [ADR-0112: Channel Bridge intake is managed at the existing grant](/zh/dev/adr/0112-channel-bridge-intake-is-managed-at-the-existing-grant)
- [ADR-0113: Shared external traffic uses member Channel harvest](/zh/dev/adr/0113-shared-external-traffic-uses-member-channel-harvest)
- [ADR-0114: Browser targets share capabilities with separate execution worlds](/zh/dev/adr/0114-browser-targets-share-capabilities-with-separate-execution-worlds)
- [ADR-0115: Explicit Inbox sharing adds a canonical Channel placement](/zh/dev/adr/0115-explicit-inbox-sharing-adds-canonical-placement)
- [ADR-0116: Daily Browser tabs use explicit ephemeral borrowing](/zh/dev/adr/0116-daily-browser-tabs-use-explicit-ephemeral-borrowing)
- [ADR-0117: External-only reports use owned Outbox correspondence](/zh/dev/adr/0117-external-only-reports-use-owned-outbox-correspondence)
- [Editable Avatar appearance is independent of activity presentation](/zh/dev/adr/0118-editable-avatar-appearance-is-independent-of-activity) — Accepted
- [External platform defaults retain explicit inheritance](/zh/dev/adr/0119-external-platform-defaults-retain-explicit-inheritance) — Accepted
- [Multiple Bridge routes retain canonical sources](/zh/dev/adr/0120-multiple-bridge-routes-retain-canonical-sources) — Accepted
- [ADR-0121: Daily Chrome control is bound to one selected document](/zh/dev/adr/0121-daily-chrome-control-is-bound-to-one-selected-document)
- [ADR-0122: Shared-source replies use responder-owned authorization](/zh/dev/adr/0122-shared-source-replies-use-responder-owned-authorization)
- [ADR-0123: Daily Chrome Profile control uses explicit persistent pairing](/zh/dev/adr/0123-daily-chrome-profile-control-is-an-explicit-persistent-pairing)
- [ADR-0124: Local Browser drivers share Host authority](/zh/dev/adr/0124-local-browser-drivers-share-host-authority)
- [ADR-0125: Nearby context combines time coverage with count minima](/zh/dev/adr/0125-nearby-context-combines-time-coverage-and-count-minima)
- [ADR-0126: Slack text intake uses an exclusive checked Provider](/zh/dev/adr/0126-slack-text-intake-uses-exclusive-checked-provider)
- [Product artifacts compose an independently versioned IM Provider](/zh/dev/adr/0127-product-artifacts-compose-an-independently-versioned-im-provider) — Proposed
- [ADR-0128: Discord checked replies preserve native child-channel routing](/zh/dev/adr/0128-discord-checked-replies-preserve-native-child-channel-routing)
- [ADR-0129: WeChat owner DMs use private source continuations](/zh/dev/adr/0129-wechat-owner-dms-use-private-source-continuations)
- [Deletion preserves history and makes Memory erasure explicit](/zh/dev/adr/0130-deletion-preserves-history-and-makes-memory-erasure-explicit) — Accepted
- [The Bot Marketplace starts as a GitHub-indexed catalog](/zh/dev/adr/0131-bot-marketplace-starts-as-a-github-indexed-catalog) — Accepted

</details>

Source: https://botharness.ai/zh/dev/adr/index.mdx
