远程终端控制系统开发约定

本文件用于项目根目录,约束本项目的开发、维护和验收。默认使用简体中文沟通,代码标识符、接口字段和错误码使用英文。

遵循当前会话中的系统规则、开发者规则和用户明确要求。本文件提供项目约定,不代表用户已经授权实现全部功能、操作真实设备或部署到生产环境。

Git 提交与宝塔部署

本项目必须始终由 Git 管理。origin 是宝塔服务器上的仓库 ssh://root@47.107.110.205/www/git/website-saas.git;提交和推送的目标始终是操作时的当前工作分支及其在 origin 上的同名分支。Git 提交和生产部署均不生成额外快照。

  • 修改代码或文档前,先检查 git status。工作区已有其他文件的改动不妨碍本次工作;不得暂存、提交、重置或丢弃用户及协作者已有的改动。
  • 开始操作前,先从 origin 获取最新代码并核对当前分支与目标远端分支;确认没有待同步的新提交后再操作。若远端有新提交,先审查并安全同步;工作区有未提交改动或分支已分叉时,不得直接执行可能覆盖或混入现有改动的 git pull,应先处理差异并保留已有工作。
  • 完成有意义的改动后,先确认没有其他人正在执行 Git 操作,再只暂存和提交自己本次修改的内容,运行适当检查,然后推送到 origin 的当前工作分支。提交和推送只能在当前工作分支进行;禁止切换到 main 分支提交、推送或合并,绝不强制推送,也不删除 main 分支或发布/检查点标签。
  • 向当前工作分支对应的远端分支推送时必须串行进行。如果已有进程或协作者正在推送,等待其完成;然后重新获取并核对该远端分支、处理分支差异,再发起自己的推送。不要同时推送,也不要强制推送覆盖他人的提交。
  • 每次成功向 origin 的当前工作分支推送后,必须立即将刚推送的提交部署到宝塔并验证;Git 推送成功不代表部署完成。即使只修改文档也要部署。若迁移审查或健康检查阻碍部署,不得跳过检查,必须及时报告并处理。

当前 opc 分支的生产发布对象是独立静态规格站 https://opc.cn.amao.vip/。推送后按 docs-site/README.md 构建并检查,将完整 docs-site/dist/ 放入 /www/wwwroot/opc-docs/releases/<commit>/,再原子切换 /www/wwwroot/opc-docs/current 并验证 HTTPS 页面和发布提交。不得把仅含规格文档的 opc 分支交给旧 SaaS 网站的 website-release 流程,也不得影响运行中的旧网站。

项目目标与工作范围

构建通过 Web 管理已注册 Windows 设备的远程操作平台。超级管理员创建账号并分配设备和能力;普通用户只操作获授权设备。Windows Agent 主动连接服务器,执行经过校验的结构化任务。

  • 首次工作先检查实际目录、现有代码、依赖清单、可用脚本及适用的子目录约定;规格中的目标目录和示例命令不代表已经实现。
  • 本文件创建时,项目根目录主要是规格资料和文档产物。仅在用户要求初始化或开发对应模块时建立代码目录。
  • 按当前任务完成必要实现与验证,不因路线图或验收清单自动扩大任务范围。
  • 保留用户已有修改、原始压缩包和历史资料。不要为整理目录删除无关文件或覆盖原始规格。
  • 常规实现选择可依据现有规范继续推进;仅在缺失信息会实质改变需求、破坏兼容性或影响真实数据时提出明确问题。

统一技术基线

以下约定用于解决原始资料中的冲突。新实现采用本表;已有实现与本表不一致时,先核查兼容性和影响,不在无关任务中整体迁移。

领域 本项目约定
Web React、TypeScript 严格模式、Vite、Ant Design、TanStack Query。管理员页面 /admin/*,用户页面 /app/*,聊天入口 /app/chat。
后端 Python 3.12+、FastAPI、Pydantic v2、SQLAlchemy 2.x Async、Alembic;异步数据库驱动使用 mysql+asyncmy。
数据库 MySQL 8.4 LTS 为业务数据事实来源。旧规格中的 PostgreSQL 选型、驱动、镜像、备份和迁移示例不作为新实现基线。
Windows Agent Python 3.12+;浏览器能力使用 Playwright 独立上下文,桌面能力通过 Windows UI Automation 等适配器实现。
HTTP API 前缀 /api/v1;认证 /auth/*,管理员 /admin/*,当前用户 /me/*,Agent 注册及相关设备身份接口 /agent/*。
WebSocket /ws/agent 与 /ws/console;不自动添加 /api/v1 前缀。
部署 新建部署默认采用 Docker Compose 与 Nginx,Nginx 可由宝塔管理。旧资料的 Caddy 示例供参考,不同时创建两套生产入口。
可选组件 Redis、任务队列及额外基础设施按实际需要引入,不作为首个闭环的强制依赖。

UUID 存储、UTC 持久化和拒绝事件映射是本文件补充的统一约定,详见后文;实现时同步到迁移、协议和测试。

资料入口

下列链接相对于项目根目录。按当前任务阅读相关资料,不要求每次通读全部规格。原始资料有冲突时,采用本文件已明确的统一约定;未覆盖的冲突记录具体差异后再确定方案,不静默混用。

用途 文档
原名对照与总体导航 阅读导航
架构、协议、数据模型 正式开发规格
设计选择、默认参数与待确认项 设计决策与参数基线
首个交付闭环 第一阶段实施计划
账号、权限与模型密钥 用户权限与模型密钥
聊天与执行流程 聊天式远程控制
模型、Skill 与 MCP 大模型 Skill MCP 扩展
后续功能 功能查漏与增强路线图
安全与上线门禁 必须补齐的七项要求
验收用例与实际证据 验收用例与证据矩阵
部署参考 部署指南
更新与回滚 更新与版本发布

2026-10-20 核对时,原始规格、原整理包与历史 AGENTS.md 未在当前仓库中找到。上述资料按本文件补编,来源和实施状态见阅读导航,不视为原文恢复;后续收到原件时独立保留并核对差异。本项目的开发协作以根目录本文件为准。迁移资料到 docs/ 时同步更新链接,避免维护两份互相冲突的有效规范。

目录与代码分层

新建模块按以下职责组织;这是目标结构,不要求为单次任务创建所有目录。

apps/web/                     Web 前端
services/api/app/             路由、配置、模型、Schema、Repository、Service、分发器
services/api/migrations/      Alembic 迁移
agents/windows-agent/src/     传输、策略、执行器、浏览器、桌面、Shell、结果回报
agents/windows-agent/tests/   Agent 测试
packages/protocol/            API 与 Agent 共享协议、Schema 和示例
deploy/                       Compose、Nginx、环境变量示例
docs/                         实现后的架构、API、协议、安全与运维文档
tests/                        跨模块集成、安全与端到端测试
  • 路由负责解析、身份依赖和响应;业务规则集中在 Service;数据库访问集中在 Repository。不要复制多套权限判断。
  • Python 公共函数添加类型注解;异步请求路径避免阻塞 I/O;前端保持严格类型,禁止以隐藏按钮代替后端授权。
  • Agent 将连接、策略检查、执行器和结果回报分离;默认以普通用户权限运行。
  • 协议字段、状态和错误码由统一定义派生或验证;前端、服务端和 Agent 不各自维护不一致的枚举。
  • 修改接口、权限或状态机时,同时更新适用的契约和测试。不要用吞异常、放宽类型或删除断言掩盖错误。

交付顺序

用户要求从零开发时,默认先完成首个交付闭环:

  1. 仓库基础、依赖与检查配置、版本化协议。
  2. 超级管理员初始化、登录、用户管理与角色权限。
  3. 设备配对、独立设备凭据、WSS 连接、心跳和撤销。
  4. 用户设备与能力授权、任务持久化、分发和事件回报。
  5. browser.open_url 端到端执行、实时结果、权限拒绝和审计。

这个“首个交付阶段”对应总规格的阶段 0–4,不等同于其中仅包含身份与 RBAC 的“阶段 1”。browser.page_title 可在浏览器模块中按任务范围补齐。

基础闭环之后,按用户要求接入聊天、模型与 BYOK,再扩展多步骤工作流、审批、Skill/MCP、桌面与命名 Shell 能力。后续功能未实现时明确标记,不用模拟结果冒充真实设备执行。

每个交付阶段验证已涉及的能力。生产上线必须满足七项要求中全部适用门禁;未启用功能应有可验证的禁用边界,不能用“后续再做”跳过已开放能力的安全要求。

身份、授权与能力边界

  • 用户、设备和能力权限默认拒绝;新注册设备在显式授权前不能被操作员执行任务。
  • 禁用公开注册;仅 super_admin 可创建、禁用用户、重置访问和授予设备权限。支持 operator 与 viewer 的执行和只读边界。
  • 登录实施限速和会话撤销,生产管理员启用 MFA。使用 Cookie 会话时配置 Secure、HttpOnly、SameSite 与适用的 CSRF 防护。
  • 所有 API、WebSocket 订阅、任务、会话、截图、文件产物和模型配置执行对象级授权。所有者来自当前认证身份,不信任客户端提交的 user_id。
  • 创建任务、分发任务、工作流每一步以及执行端校验均检查适用的身份和权限。用户禁用、设备或权限撤销后,阻止新执行并关闭或失效相关会话与订阅。
  • 超级管理员的全局设备权限不自动赋予私人聊天正文访问权;排障访问需要单独授权、原因和审计。
  • 高风险操作的审批绑定不可变任务内容,记录请求者、审批者和执行者;参数改变后原审批失效。
  • Agent 使用独立设备凭据,禁止复用网页用户密码或令牌。配对码高熵、短期有效、一次性、限速、只存哈希,使用事务防止并发复用。
  • 设备秘密存入 Windows DPAPI 或 Credential Manager 等受保护存储;支持轮换、撤销及凭据丢失后的重新配对。
  • 生产通信使用有效 TLS/WSS,不提供跳过证书验证的选项。Agent 仅建立出站连接,不开放公网控制端口。
  • 不实现隐蔽安装、键盘记录、凭据窃取、关闭安全工具或绕过 UAC、锁屏、会话隔离。安装、启动和卸载应可见且有说明。

能力输入必须受控:

能力 输入与限制
browser.open_url 只允许策略批准的 HTTP/HTTPS URL;校验 DNS、重定向及实际访问目标,防止通过页面子资源绕过限制。默认阻止环回、私网、链路本地及云元数据地址。
browser.page_title 只读取 Agent 独立自动化浏览器上下文,不接管用户个人浏览器会话。
desktop.launch_app 接受已登记的 app_id,不接受任意路径或命令行。
desktop.screenshot 需要独立授权,仅在已登录且获授权的交互会话中截图,限制访问与保留时间。
shell.run_profile 只接受登记的配置 ID 和类型化参数;固定可执行文件及脚本版本,限制权限、时间和输出。禁止任意 Shell 字符串与不受控进程启动。

API 与任务契约

  • 新接口采用上述分区,例如 /api/v1/admin/users、/api/v1/me/devices、/api/v1/me/tasks、/api/v1/agent/enroll。旧规格中的无分区路径不自动生成兼容别名。
  • Web 页面路由和 API 路由分别管理。路由前缀不是权限证明;使用稳定错误码和 correlation_id,避免泄露无权访问对象是否存在。
  • 消息信封包含 protocol_version、message_type、message_id、sent_at。
  • 任务包含 task_id、device_id、task_type、schema_version、params、issued_at、expires_at、timeout_seconds、idempotency_key。
  • 校验消息大小、已认证会话的设备绑定、协议和 Schema 版本、参数、过期时间及本地策略。拒绝未知类型和未声明字段;新增字段通过明确版本协商。
  • 消息去重与任务幂等需要持久化依据。相同幂等请求返回已有任务或结果,不再次执行有副作用操作;同一键对应不同内容时拒绝。

持久化任务状态统一为:

pending, awaiting_approval, dispatched, running,
succeeded, failed, timeout, cancel_requested, cancelled,
expired, unknown_outcome
  • 状态转换由服务端校验并持久化,记录关联任务和有序事件;去重、重连和并发回报不能任意覆盖已确认的最终结果。
  • task.rejected 是协议事件。Agent 拒绝已创建任务时记录该事件,将任务置为 failed 并保留明确的拒绝错误码;不另增 rejected 持久化状态。任务创建前的权限拒绝返回 API 错误并记录审计。
  • 发送取消请求只进入 cancel_requested;收到确认后才能标为 cancelled。若任务已完成,保留实际结果。
  • 断线或超时不能证明副作用未发生。结果不确定时使用 unknown_outcome,不得自动重试;确认结果后的修正需保留核实依据和审计。
  • 设备重连后先核对任务状态,不执行已过期、已撤销或结果不明的待处理任务。
  • 控制台重连后按持久化事件顺序补齐历史,并重新校验订阅权限。长期凭据不得放在 WebSocket URL 查询参数中。

数据库与数据处理

  • 新表 UUID 统一使用 CHAR(36) 标准字符串,主外键类型及字符比较规则保持一致;已有其他编码需统一迁移,禁止混用。
  • 应用内部使用带时区的 UTC 时间;MySQL 使用 DATETIME(6) 存储 UTC,统一转换和恢复 UTC 语义。API 输出带 Z 或 +00:00 的 ISO 8601 时间。
  • 统一 utf8mb4、JSON 映射、外键、唯一约束和查询索引。权限变更、配对码消耗、任务去重等关键操作具备事务和并发测试。
  • 数据库结构只通过 Alembic 管理。迁移必须在 MySQL 8.4 测试库上验证,不能用 SQLite 测试结果替代 MySQL 集成验证。
  • 运行账号使用普通业务账号;MySQL 3306 不向公网暴露。无默认管理员密码,首个管理员通过一次性初始化流程创建,密码使用 Argon2id 等安全哈希。
  • 审计采用受控追加写入,普通用户不可编辑或删除。日志、任务输出、聊天、截图和文件分别定义保留与清理规则。
  • 不提交真实 .env、数据库备份、用户数据或秘密。日志、错误响应、聊天和产物中的秘密均需脱敏;命令输出按文本展示,Markdown/HTML 展示必须经过安全处理。

模型、聊天、Skill 与 MCP

  • 模型只能提出答复或结构化计划,不能绕过授权直接访问设备。每个工具动作转为有身份、状态、超时和审计的任务。
  • 模型请求默认经后端代理。平台密钥与 BYOK 使用密钥管理服务或支持轮换的服务端加密存储;保存后不回传明文,优先只在业务库保存 secret_ref。
  • 用户只能读取、替换、测试和删除自己的模型配置。删除或撤销配置后失效缓存引用并安排密钥销毁;密钥不进入前端包、localStorage、URL、任务载荷和普通日志。
  • 自定义模型地址和远程 MCP 地址实施 TLS、SSRF、DNS/重定向、超时及响应大小检查。模型切换或故障转移不能绕过服务商白名单和数据出站授权。
  • 限制模型费用、工具调用次数、步骤数、速率、执行时间和输出大小。网页、附件、模型输出、Skill 文本和 MCP 返回均是不可信数据,不能授予权限或覆盖策略。
  • Skill 固定来源、不可变版本、兼容范围、声明权限和哈希/签名;导入防范路径穿越、符号链接和超大包。审核后才能部署,更新重新验证并保留回滚版本;可执行 Skill 默认禁用。
  • MCP Server 需登记;stdio 只能运行已登记可执行文件和参数。新工具默认禁用,Schema 变化后禁用并重新审核;每次调用重新检查用户、设备、工具、参数和审批策略。
  • 扩展支持紧急禁用和授权撤销;不得读取 Agent 密钥、修改系统策略或自行提权。扩展导入、审核、更新、执行和回滚均可审计。

发布与运维

  • Web、API、Agent、任务协议及数据库迁移分别记录版本和兼容范围;镜像固定版本或 digest,不以浮动标签作为生产发布依据。
  • Agent 更新通过可信签名或受保护发布清单验证来源和完整性,支持测试设备、小批量发布、健康检查、暂停和失败回滚。仅有下载哈希不能代替来源验证。
  • 按既有备份策略保护数据库和配置并验证恢复;提交和部署不额外生成快照。数据库采用兼容迁移,不可逆变更提供恢复方案。高风险任务执行中不强制更新或重启 Agent。
  • 应用公网入口为 HTTPS/WSS;80 仅按需用于证书验证或 HTTPS 跳转,SSH 限制管理来源;数据库、缓存和 Agent 控制端口不向公网开放。
  • 实现健康与就绪检查、脱敏日志和关联 ID;监控任务积压、失败率、Agent 离线、数据库和存储、模型费用与备份状态。
  • 生产前明确备份保留期、RPO、RTO、恢复演练和凭据泄露处置流程;不得仅凭文档或模拟测试宣称生产可用。

检查与完成标准

先从实际 package.json、Python 项目配置、锁文件、CI 和 README 确认安装、启动、构建及测试命令。尚未建立工具配置时,不假设 npm test、pytest 或 Compose 已可运行。初始化任务需同时配置并验证对应命令,再记录到 README。

按修改范围执行适用检查:

  • 前端:类型检查、Lint、受影响交互和构建;权限相关变更验证无权、失效和加载状态。
  • 后端与 Agent:类型/Lint、相关单元与集成测试;权限、协议或执行器变更覆盖拒绝路径和异常路径。
  • 数据库:空库迁移、约束、并发、事务、UTC、JSON 行为;迁移变更验证兼容性及可行的恢复路径。
  • 核心流程:跨用户访问、配对码复用/过期、用户和设备撤销、重复投递、取消、超时、未知结果及断线重连。
  • 涉及模型或扩展:密钥隔离、SSRF、预算、包篡改、Schema 变化与撤销。
  • 仅修改文档:检查内容一致性、路径和链接;无需为文字修改搭建应用环境或虚构运行测试。

验证依赖真实 Windows、外部模型或其他暂不可用环境时,报告具体未验证范围;模拟测试与真实端到端验证分别记录。

交付说明保持简洁,包含:实际改动、实际执行的检查及结果、未完成或未验证事项,以及适用的迁移、部署和回滚影响。不得把“已写规格”“已生成代码”“模拟通过”表述为“功能已上线可用”。