Skip to content

Edge Contracts and Skills zh

pawaca edited this page Aug 30, 2026 · 1 revision

Edge 契约与技能

改编上游代码的强制规则和 AI 辅助工作流——源自 AGENTS.md。

来源:AGENTS.md — 所有仓库规则的唯一事实来源。

概述

dsh-edge 封装已发布的 @deepseek-ai/dsh-* 包。上游迭代快,Edge 无法影响上游决策,Cloudflare Workers 有硬性平台限制。分层配置系统管理人类和 AI agent 如何使用此代码库:

  • CLAUDE.md — 单行指针,引导 Claude Code 读取 AGENTS.md。避免规则重复。
  • AGENTS.md — 唯一事实来源:所有权边界、命令、运行时不变量、变更纪律、审查工作流、发布流程和 git 规范。
  • .agents/skills/ — 三个专用技能文件,编码推送前检查、代码审查和审查循环工作流。

文件结构

.
├── CLAUDE.md                              # 指针 → AGENTS.md
├── AGENTS.md                              # 仓库规则(事实来源)
├── .claude/
│   └── settings.json                      # Claude Code 权限
└── .agents/
    └── skills/
        ├── codex-review-loop/
        │   ├── SKILL.md                   # 审查循环技能
        │   ├── scripts/codex-state.sh     # PR 状态传感器
        │   ├── tests/codex-state.test.sh  # 传感器测试
        │   └── agents/openai.yaml         # Codex agent 配置
        ├── dsh-code-review/
        │   └── SKILL.md                   # 代码审查技能
        └── dsh-pre-push-checks/
            ├── SKILL.md                   # 推送前检查技能
            └── agents/openai.yaml         # Codex agent 配置

契约总览

契约的存在是为了最小化合并冲突、最大化上游利用、保护持久状态和保障凭据安全。违反总是阻塞的。

# 类别 规则
R1 [上游] 单一上游版本
R2 [上游] 双模式对齐
R3 [上游] Durable Object 稳定性
R4 [性能] 禁止无界 SQL 扫描
R5 [安全] 凭据安全
R6 [Cordis] 注册后 provide
R7 [发布] Gzip 预算 + 预构建测试
R8 [发布] 补丁纪律
R9 [发布] 版本身份

上游耦合

R1 — 单一上游版本

规则: 所有 @deepseek-ai/dsh-* standalone 依赖锁定同一精确上游版本。仅在专门的 upstream-baseline PR 中升级。

原因: 混合版本会在原本一起设计和测试的包之间产生隐性不兼容。

合规standalone/package.json 中 30+ 个包全部锁定 0.1.1-rc.2。7 个补丁全部版本绑定。

违规:单独升级 dsh-tools0.1.2,而其他包保持 0.1.1-rc.2

R2 — 双模式对齐

规则: 保持 Direct 和 Dynamic Loader 模式行为对齐,仅命令执行后端和 Cloudflare plan 要求不同。

原因: 如果两种模式在 session 行为或 API 响应上分歧,bug 就变成 plan 相关的且无法在单一模式下测试。

合规:集成测试覆盖两种模式。Session 创建、事件格式和 projection 广播完全一致。

违规:添加仅在 Dynamic 模式下工作的文件上传功能,Direct 模式下没有 stub 或优雅降级。

R3 — Durable Object 稳定性

规则: 保留 DO 类名、bindings、session/event 格式、workspace/VFS 状态、owner 认证和公共 HTTP/WebSocket 行为。

原因: 重命名类或更改 binding 会失去所有已有状态的访问权。破坏 session event 格式意味着用户丢失对话。

合规DshEdgeInstance 类名和 DSH_EDGE binding 自 v0.1.0 以来保持稳定。5 个 SQL 表仅增量迁移。

违规:将 DshEdgeInstance 重命名为 EdgeDurableObject——所有现有 DO 实例变得不可访问。

性能

R4 — 禁止无界 SQL 扫描

规则: 请求路径上的 DO SQL 查询不得使用关联子查询或对无界表的逐行扫描。在写入时用物化表原子维护读密集型聚合。

原因: DO SQL 在 Worker 请求处理器内运行,全表扫描阻塞整个请求。DO 没有查询优化器。

合规dsh_session_summaries 是由 syncSummaries() 在写入时维护的物化表。Session 列表从此表读取。

违规SELECT s.id, (SELECT MAX(seq) FROM dsh_session_events e WHERE e.session_id = s.id) FROM dsh_sessions s

安全

R5 — 凭据安全

规则: 绝不记录 DSH_EDGE_ACCESS_KEY、bearer token 或 owner cookie。解析后的值保持请求范围内,绝不记录、跨请求缓存或写入 session event。

原因: Worker 日志可通过 Cloudflare dashboard 访问。Session event 通过 WebSocket 传输——嵌入凭据会广播给每个连接的客户端。

合规EdgeCredentialProvider.describe() 返回 { configured, source, writable } 但不包含 value。认证失败记录 'The access key is not valid.',绝不记录提交的密钥。

违规console.log('API key resolved:', credential.value)。或将 resolvedApiKey 存储在 DO 实例上跨请求持久化。

Cordis 框架

R6 — 注册后 Provide

规则: 注册 cordis 子注册表条目时,如果另一个插件使用 ctx.inject([key]) 等待它,必须调用 ctx.provide(key, value)。子注册表 register() 仅更新内部 Map,不触发 inject 解析。使用 ctx.effect() 配对并在 dispose 时清理。

原因: 没有配对的 provide,下游插件如 StorageDomain 永远不会启动,session store 在启动时静默挂起。

合规:在 session-store.ts 中:

ctx.effect(() => {
  const dispose = ctx.storage.backend.register('durable-object', storageBackend)
  ctx.provide('storage.backend.durable-object', true)
  return () => { dispose(); ctx.provide('storage.backend.durable-object', undefined) }
})

违规ctx.storage.backend.register('durable-object', storageBackend) 但不调用 ctx.provide()

发布

R7 — Gzip 预算 + 预构建测试

规则: Direct 模式必须低于 gzip 预算。发布测试必须启动预构建产物,而非源码入口。

原因: Workers 免费方案有 10 MiB 压缩限制。测试预构建产物能捕获仅在生产构建中出现的 bundler 回归。

合规bundle-size.mjs 超出 gzip 预算时抛出异常。快照测试运行在打包输出上。

违规:通过 Vite dev server 对 src/index.ts 运行集成测试而非预构建 Worker。

R8 — 补丁纪律

规则: 每个保留的上游补丁需要:版本绑定的文件名、无补丁则失败的检查、理由和移除条件。

原因: 没有版本绑定文件名,补丁会静默超出其用途。没有无补丁则失败的测试,补丁变成空操作。

合规:7 个补丁文件名包含上游版本:@deepseek-ai__dsh-sandbox@0.1.1-rc.2.patch

违规:名为 fix-llm-streaming.patch 的补丁,没有版本绑定、没有测试、没有移除条件。

R9 — 版本身份

规则: npm 包、tag、GitHub Release、部署身份和文档必须报告相同的 dsh-edge 版本。apps/dsh-edge/package.json 是唯一的发布版本来源。

原因: npm、GitHub 和部署之间的版本漂移会造成混淆。

合规repository-metadata.spec.ts 断言只有 apps/dsh-edge/package.json 有版本号。快照测试从此单一来源派生期望值。

违规:在根 package.json 中添加 "version": "0.7.1"

技能

技能是结构化指令文件(SKILL.md),AI agent 在执行特定工作流前加载。三个技能形成流水线:

┌─────────────────────┐
│  codex-review-loop   │  驱动整个 PR 生命周期
│                     │  (分类 → 修复 → 推送 → 审查 → CI)
└──────┬──────┬───────┘
       │      │
       ▼      ▼
┌──────────┐ ┌──────────────────┐
│ dsh-code │ │ dsh-pre-push     │
│ -review  │ │ -checks          │
└──────────┘ └──────────────────┘
  判断         选择和运行
  发现         推送前检查
技能 目的 使用时机
dsh-pre-push-checks 选择并运行推送前的最小充分检查 任何推送或 PR ready 转换前
dsh-code-review 按 Edge 特定正确性审查 PR(8 项阻塞检查) 判断审查发现;决定是否可合并
codex-review-loop 驱动 PR 通过有界的审查和 CI 收敛 开启/更新 PR 后

dsh-pre-push-checks

按拥有面分类变更文件,选择所需的最小证据:

  • 运行时/存储/认证 → 聚焦单元测试 + 受影响的集成路径
  • Edge 客户端/UI → 聚焦测试 + 浏览器/运行时快照套件
  • Standalone 依赖/补丁/打包 → standalone 构建 + 验证器 + 提升预构建产物
  • 安装器/发布 → pack + workspace 外的 pack:verify
  • 文档/治理pnpm run doc-sync + 手动双语对比
  • 跨领域 → 全套:check、两种构建、集成、快照、包验证

dsh-code-review

dsh-edge PR 的八项阻塞检查:

  1. 从精确已发布包进行上游组合(禁止复制源码)
  2. Direct/Dynamic 产物对等
  3. Durable Object 兼容性
  4. 凭据安全(永远不在持久状态、日志、fixture 中)
  5. Direct 模式 gzip 预算
  6. 补丁纪律(版本绑定、有理由、有测试、可移除)
  7. 安装器/发布跨平台和密钥安全
  8. 产品/法律文本——独立项目,非 DeepSeek 附属

codex-review-loop

驱动 PR 通过迭代审查轮次的状态机:

  • 每次调用一个 tick — 读取快照、分类所有发现、做一批修复、推送、请求审查。
  • 发现分类 — 每个发现恰好得到一个处置:fixedrebutteduser-decision
  • 收敛执行 — 第 2 次 → 通用修复;第 3 次 → 策略重置;每 2 轮可行动 → 检查点。
  • 完成契约 — 可合并要求稳定 HEAD、所有项目已处理、审查通过、CI 绿色。永远不自动合并。

开发者工作流

首次变更前

  1. 阅读 AGENTS.md — 理解所有权边界和以上 9 条契约。
  2. 为你的分支创建 worktree(永远不在 main 上直接工作)。
  3. 运行 pnpm installpnpm --dir apps/dsh-edge/standalone install --frozen-lockfile

每次推送前

  1. 按面分类你的变更(运行时、客户端、standalone、安装器、文档、跨领域)。
  2. 运行该面的最小检查(如 dsh-pre-push-checks 定义)。
  3. 仅提交已检查的路径 — 禁止盲目 git add -A

PR 审查期间

  1. 审查发现是主张,不是命令 — 在行动前验证每个发现的前提。
  2. 为每个发现分配处置:fixedrebutteduser-decision
  3. 跟踪问题族 — 如果同一族出现两次,停止局部补丁,写一个通用修复。
  4. 永远不自己合并 PR — 报告就绪状态,让维护者决定。

发布检查清单

  1. 编写双语发布说明 + i18n 配对 → pnpm run doc-pairs -- --write
  2. 合并发布 PR 到 main(squash merge)
  3. 打标签:git tag dsh-edge-v<version> && git push origin dsh-edge-v<version>
  4. 验证:npm view dsh-edge@<version>gh release view dsh-edge-v<version>

契约 vs. 惯例。 这些规则不是风格偏好——它们是保护持久状态、凭据安全和升级路径的不变量。底层原则是最大化利用上游能力:原样使用已发布的包,编写最小可能的适配层,确保该适配器能在无需重写的情况下吸收上游变更。

English

中文

Clone this wiki locally