
Claudian Collab 域架构解析Host 安装权限、所有权标记与依赖方向【免费下载链接】claudianAn Obsidian plugin that embeds Claude Code/Codex as an AI collaborator in your vault项目地址: https://gitcode.com/GitHub_Trending/cl/claudian本文基于 src/app/collab/AGENTS.md 展开深入剖析 Claudian一个把 Claude Code/Codex 嵌入 Obsidian 知识库的插件Collab 协作域中的“Host 安装权限”体系谁有资格在本地机器上启动并操作一个协作项目的权威authority状态、所有权如何通过.claudian-authority.json标记文件落盘与迁移、运行期 CA 与进程锁如何按安装实例隔离以及应用层与核心层之间的依赖方向约束。读完本文你可以从源码层面理解 Claudian 如何避免“多台设备、同一成员凭据”场景下的本地 Host 权限冲突并能定位每个策略点的实现文件与测试目录。1. 问题背景成员身份 ≠ 安装身份在 Claudian Collab 中Project membership项目成员关系拥有的是 Member 维度的身份要素Member id、角色manager/member、成员凭据、个人 ref以及成员级的hostOwnership.ownsAuthority标志。这些字段定义在 CollabLocalProjectRepository.ts 的CollabLocalLanMembershipRecord类型中hostOwnership段仅要求ownsAuthority为布尔值可选autoStart。关键点在于这些字段没有任何一个能标识“哪一台安装实例被允许操作本地 Host 权威”。同一份同步状态可能存在于多台设备上——同属一个 Host Member、持有相同角色和凭据的同步安装实例在本地仍然是普通的 LAN 客户端。要成为本地 Host必须额外通过安装级installation-level的所有权判定也就是本文档 src/app/collab/AGENTS.md 第一条规则的核心membership 回答“你能不能”installation ownership 回答“你在不在这里”。安装实例的唯一标识是InstallationKey定义于 src/core/device/InstallationKey.ts一个形如device- 64 位十六进制的品牌化字符串branded stringparseInstallationKey会对格式不符的输入直接抛出TypeError。2. 所有权状态机absent / hosted-here / hosted-elsewhere / legacy-unbound所有权判定的事实来源是权威目录中的标记文件。在 CollabLocalProjectRepository.ts 中可以看到关键常量const PRIVATE_STATE_DIRECTORY .claudian/collab; const AUTHORITY_OWNERSHIP_MARKER .claudian-authority.json; const LEGACY_AUTHORITY_OWNERSHIP_SCHEMA_VERSION 1 as const; const AUTHORITY_OWNERSHIP_SCHEMA_VERSION 2 as const; const AUTHORITY_OWNERSHIP_MARKER_MAX_BYTES 1_024;每个项目的权威状态存放在vault/.claudian/collab/authorities/projectId/下。#inspectAuthorityInstallationUnlockedCollabLocalProjectRepository.ts把目录状态归一化为四种CollabAuthorityInstallationStatus状态判定条件语义absent目录不存在或目录存在但无标记且内容符合“临时provisional”约束本安装尚无权威可作为新建/迁移目标legacy-unbound标记文件schemaVersion为 1legacy旧版标记未绑定任何安装允许显式认领claimhosted-here标记schemaVersion为 2 且ownerInstallationKey等于当前安装本地 Host 的所有权属于当前安装hosted-elsewhere标记schemaVersion为 2 且ownerInstallationKey为其他安装权威在别处托管本地只是同步客户端此外标记文件的projectId与目录所在项目不一致、目录是符号链接或不是目录都会抛出authority-ownership-marker-mismatch等边界错误而不是静默降级——这与原文档“Marker inspection failure is strict for Host-control operations”的表述一致检查失败对 Host 控制类操作是严格的但只让“可选的本地目标”失去普通 LAN 客户端路由资格项目摘要会把受影响的 Host 投影隔离为 needs-attention而不是让整个项目列表失败。3. HostInstallationBindingService本地 Host 执行的唯一策略所有者HostInstallationBindingService.ts 是原文档点名的策略单点。它把所有本地 Host 权限动作收敛到固定的一组方法上inspect(projectId)只读检查直接透传projects.inspectAuthorityInstallation对应四种状态assertOwned(projectId, purpose)断言当前安装拥有权威。purpose取值为HostAuthorityPurposecleanup | diagnostics | open | recover | retire | start非hosted-here时抛出host-installation-not-owned/host-installation-owner-mismatchcreateOwned(projectId)仅在状态为absent时创建带所有权的权威目录若已存在他人标记报host-installation-owner-mismatch若是 legacy 残留则报host-installation-legacy-claim-required明确把 legacy 路径与新建路径分开removeOwned(projectId)只允许删除自己拥有的权威目录absent时返回false而非报错claimLegacy(projectId)唯一可以处理legacy-unbound状态的方法且被SerialTaskQueue串行化见 SerialTaskQueue.ts——先prepareLegacyRuntime准备旧版运行时再次 inspect 防止状态在准备期间漂移漂移则抛host-installation-legacy-claim-changed最后调用claimLegacyAuthorityDirectory写入 schema 2 标记bindTransferTarget(projectId)Host 迁移目标侧的显式绑定要求目标目录为空absentprepareAuthorityTransferTarget/activateAuthorityTransferTarget/discardAuthorityTransferTarget权威转移authority-transfer目标侧的三件套全部先通过assertRecoveryOwner校验“恢复记录的所有者安装 当前安装”不匹配则抛出durable-progress-recovery-required错误并携带resume/open-diagnostics恢复动作assertOwnedRetirement退役retirement场景下的所有权断言。claimLegacy的实现细节值得注意HostInstallationBindingService.ts认领成功后会立即回调bindEligibleLegacyRecovery为遗留的恢复记录补绑当前安装的所有者。这正是原文档第 12 条“Host admission first reruns idempotent binding for eligible legacy source records before restart guards”的落点——绑定是幂等的且在重启守卫之前执行无所有者的遗留目标记录或终态记录仍然可见但会以“需要恢复recovery-required”的诊断失败只有有效的外来记录与已完成的属主绑定记录才是“惰性的同步证据”。错误模型也集中在这里bindingError统一构造CollabError区分authorization-denied仅open-diagnostics与durable-progress-recovery-required附带resume、open-diagnostics让上层 UI 可以据此给出恢复路径而不是裸报错。4. CollabLocalProjectRepository有边界的文件系统机制与能力令牌原文档规定CollabLocalProjectRepository只负责“有边界的标记与权威目录文件系统机制”权限判定不属于它。源码印证了这一点只读检查inspectAuthorityInstallationCollabLocalProjectRepository.ts不修改任何内容有能力的操作assertOwnedAuthorityDirectory、createOwnedAuthorityDirectory、claimLegacyAuthorityDirectory、removeOwnedAuthorityDirectory、retireOwnedAuthorityDirectory全部要求当前安装为所有者才执行返回的不是目录路径本身而是一个冻结的能力令牌OwnedAuthorityDirectoryCapability{ authorityDirectory, projectId }并被登记进#ownedAuthorityCapabilities这个WeakSetCollabLocalProjectRepository.ts。任何后续移除/退役操作都要先通过#assertIssuedAuthorityCapability验证令牌是本仓库签发过的——即原文档“opening, creating, retiring, or removing authority state requires an owned capability issued for the current installation”的实现形式临时provisional目录prepareProvisionalAuthorityDirectory/recoverProvisionalAuthorityDirectory/bindProvisionalAuthorityDirectory构成一个“先无主、后绑定”的通道。临时目录刻意不写标记文件只有bindProvisionalAuthorityDirectory才写入 schema 2 标记并升级为属主能力。这对应原文档“Cloud-to-LAN keeps the canonical authority directory markerless until relinquishment proof”Cloud-to-LAN 目标在交出证明relinquishment proof之前保持权威目录无标记激活时只接受一个精确、完整的临时数据库与仓库退役retireOwnedAuthorityDirectory通过rename把authorities/projectId移动到.claudian/collab/retired-lan-authorities/projectId/attemptId并对新旧父目录做持久化 syncCollabLocalProjectRepository.ts保证原子性和断电可恢复严格解码所有 JSON 记录走requireExactKeys精确字段校验 正则/长度约束如MEMBER_CREDENTIAL_PATTERN、FINGERPRINT_PATTERN索引与成员记录还带 0/1/2 → 3 的migrateIndex/migrateMembership迁移路径。整体 schema 版本定义在 CollabSchemaVersions.tsCOLLAB_LOCAL_PROJECT_SCHEMA_VERSION 3、COLLAB_AUTHORITY_SCHEMA_VERSION 12。从源码结构看仓库对符号链接做了双重设防lstat后显式拒绝isSymbolicLink()的权威目录且路径解析统一走resolveCollabVaultPath等 CollabFilesystemBoundary.ts 的受控 API配合ensureCollabContainerGuard保证一切操作不逃逸出 vault 根。5. 按安装隔离的运行时状态CA 与进程锁原文档第 8 条规定Host 运行时 CA 与进程锁状态的作用域限定在.claudian/collab/installations/installationKey/之下旧版全局 CA 文件只是“经过显式批准的 legacy claim”期间只读的迁移输入全局 CA 与锁文件永远不是运行时所有权证据。源码中的三处直接证据TLS 身份LanTlsIdentity.ts 将tlsDirectory构造为.claudian/collab/installations/${this.installationKey}/tlsCA 私钥/证书均落在此作用域内Host 进程锁LanHostCoordinator.ts 将锁路径设为.claudian/collab/installations/${installationKey}/lan-host.lock保证同一安装实例不会重复拉起 Host且锁与安装一一对应不与其他设备共享路由可见性与 pinned CA原文档第 14 条说明托管路由hosted route只有在项目“带着作用域到当前安装的 pinned CA 处于 live 状态”后才对外可见每次路由的发布、移除或重绑定都会重置共享 LAN work-session 投影使缓存中的客户端无法保留过期的本地路由。结合第 9 条“同一 Host Member、外来标记的同步安装仍是普通 LAN 客户端”可以推出设计意图本地 Host 的选择、恢复、TLS、加锁、权威访问与删除全部以hosted-here为门槛而成员授权规则继续沿用 membership——两套判定互不替代。6. 哪些记录携带安装所有者哪些只是同步客户端状态原文档第 11 条给出了一个清晰的二分法。只有以下五类记录携带安装所有者installation ownerProject setup项目建立见 CollabProjectSetupService.ts物理 Host-transfer 恢复host-transfer/ 下的恢复记录存储生产 authority-transfer 恢复authority-transfer/ 的持久化记录经由CollabLocalProjectRepository暴露的authorityTransferRecords等存储端口读写私有 Cloud-bootstrap 迁移bootstrap/ 下的过渡记录退役墓碑tombstone记录retirement/。其余——通用 Publish、request、conflict、working-copy、Leave、claimant 以及普通 Member 恢复——一律视为同步客户端状态不含安装归属。第 13 条进一步要求Incoming Host transfer 与 Cloud-to-LAN 目标恢复必须在任何 listener、TLS、staging 或临时权威工作之前先持久化“属主绑定的意图owner-bound intent”即“先落盘意图再动运行时”这是断电恢复能够判定“进度属于我”的前提。7. 重连收敛与每项目串行协调原文档最后两条描述了 LAN 边界的两个协调机制可重连控制失败的收敛第 15 条在共享 work-session 边界合并唯一可信的 discovery持久化 endpoint 与 Git-origin 的轮换重置该会话代次generation并对同一个幂等操作重试一次Publish 与 review 在同一代次内既校验控制面又执行 Git。相关实现位于 reconnect/ 与 CollabProjectWorkSession.tsLanAuthorityProjectionTransitionCoordinator的每项目串行化第 16 条Host start/rebind、reconnect、物理 Host-transfer 引起的 Git-origin 与 membership 投影变更都按 Project 排队在同一“车道”中执行每个写者在轮换 origin 并保存 membership 之前先在该车道内重新校验其预期的 membership 状态。新 Host 的 clone 没有“已停止 Host 的 origin”——第一条可信路由负责建立它而 legacy 哨兵值只作为修复输入。实现见 LanAuthorityProjectionTransitionCoordinator.ts。8. 依赖方向安装键的注入与分层禁区原文档“Dependency direction”一节给出了明确的架构约束源码可以逐条对应安装键只解析一次src/main.ts 中const installationKey getInstallationKey()取得安装键后注入 Collab 组合CollabLocalProjectRepository与HostInstallationBindingService都通过构造参数installationKey接收它后者在构造时即调用parseInstallationKey做格式校验应用与特性模块不直接读取渲染进程持久化消费面收窄Core 与 presentation 层只允许消费“安装状态投影installation-status projection”和“显式的 legacy-claim port”不得 import 绑定服务、本地仓库、TLS 身份或 Host 协调器。从源码结构看这正是HostInstallationBindingServiceOptions以端口接口bindEligibleLegacyRecovery、prepareLegacyRuntime依赖上层能力、而CollabLocalProjectRepository只依赖文件系统与协议常量的原因——策略、机制与展示三者之间没有反向依赖任何一侧的实现演进都不会穿透边界。9. 如何在仓库中验证策略单点通读 src/app/collab/host-installation/HostInstallationBindingService.ts 的全部方法与错误码标记与能力令牌src/app/collab/CollabLocalProjectRepository.ts 中inspect/createOwned/claimLegacy/retireOwned的实现安装隔离路径src/app/collab/lan/LanTlsIdentity.ts 与 src/app/collab/lan/LanHostCoordinator.ts测试基线Collab 域单元测试集中在 tests/unit/app/collab覆盖 host-transfer、bootstrap、reconnect、publish 等与所有权/恢复相关的模块集成测试在 tests/integration/app/collab可以据此验证本文所述状态机与依赖约束的回归情况。小结Claudian Collab 的 Host 安装权限体系可以用三句话概括membership 决定授权.claudian-authority.json标记schema 2绑定 installationKey决定本地 Host 归属.claudian/collab/installations/installationKey/作用域隔离运行时 CA 与进程锁策略全部收口在HostInstallationBindingService文件系统机制全部收口在CollabLocalProjectRepository并以能力令牌约束副作用恢复类记录先落盘属主意图再动运行时而依赖方向保证安装键只解析一次、核心层永不直接触碰 Host 协调器。这套“身份三分 能力令牌 每项目串行车道”的设计是多设备协作插件在崩溃恢复与所有权转移场景下保持可审计性的关键。【免费下载链接】claudianAn Obsidian plugin that embeds Claude Code/Codex as an AI collaborator in your vault项目地址: https://gitcode.com/GitHub_Trending/cl/claudian创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考