-
Notifications
You must be signed in to change notification settings - Fork 1
Edge Contracts and Skills
Mandatory adaptation rules and AI-assisted workflows — from AGENTS.md.
Source: AGENTS.md — the single source of truth for all repository rules.
dsh-edge wraps published @deepseek-ai/dsh-* packages. Upstream ships fast, Edge has no influence over upstream decisions, and Cloudflare Workers impose hard platform constraints. A layered configuration system governs how both humans and AI agents work with this codebase:
-
CLAUDE.md— a one-line pointer that tells Claude Code to readAGENTS.md. Avoids rule duplication. -
AGENTS.md— the single source of truth: ownership boundaries, commands, runtime invariants, change discipline, review workflow, release procedure, and git hygiene. -
.agents/skills/— three specialized skill files that encode the pre-push, code review, and review-loop workflows as structured instructions.
.
├── CLAUDE.md # Pointer → AGENTS.md
├── AGENTS.md # Repository rules (source of truth)
├── .claude/
│ └── settings.json # Claude Code permissions
└── .agents/
└── skills/
├── codex-review-loop/
│ ├── SKILL.md # Review loop skill
│ ├── scripts/codex-state.sh # PR state sensor
│ ├── tests/codex-state.test.sh # Sensor tests
│ └── agents/openai.yaml # Codex agent config
├── dsh-code-review/
│ └── SKILL.md # Code review skill
└── dsh-pre-push-checks/
├── SKILL.md # Pre-push skill
└── agents/openai.yaml # Codex agent config
The contracts exist to minimize merge conflicts, maximize upstream leverage, protect durable state, and enforce credential safety. Violations are always blocking.
| # | Category | Rule |
|---|---|---|
| R1 | [Upstream] | Single upstream version |
| R2 | [Upstream] | Dual-mode alignment |
| R3 | [Upstream] | Durable Object stability |
| R4 | [Perf] | No unbounded SQL scans |
| R5 | [Security] | Credential safety |
| R6 | [Cordis] | Provide after register |
| R7 | [Release] | Gzip budget + prebuilt tests |
| R8 | [Release] | Patch discipline |
| R9 | [Release] | Version identity |
Rule: Keep every @deepseek-ai/dsh-* standalone dependency on one exact upstream version. Upgrade only in an explicit upstream-baseline PR.
Why: Mixed versions create invisible incompatibilities between packages designed and tested together.
✅ Compliance: All 30+
@deepseek-ai/dsh-*packages instandalone/package.jsonpin to0.1.1-rc.2. All 7 patches are version-bound.
❌ Violation: Upgrading
dsh-toolsto0.1.2alone while leaving everything else at0.1.1-rc.2.
Rule: Keep Direct and Dynamic Loader modes behaviorally aligned except for their command-execution backend and Cloudflare plan requirement.
Why: If the two modes diverge in session behavior or API responses, bugs become plan-specific and untestable in one mode.
✅ Compliance: Integration tests run against both modes. Session creation, event format, and projection broadcast are identical.
❌ Violation: Adding a file-upload feature that only works in Dynamic mode without a stub or graceful degradation in Direct mode.
Rule: Preserve DO class names, bindings, session/event formats, workspace/VFS state, owner authentication, and public HTTP/WebSocket behavior.
Why: Renaming a DO class or changing a binding loses access to all existing state. Breaking session event formats means users lose their conversations.
✅ Compliance:
DshEdgeInstanceclass name andDSH_EDGEbinding stable since v0.1.0. The 5 SQL tables use additive migrations only.
❌ Violation: Renaming
DshEdgeInstancetoEdgeDurableObject— all existing DO instances become unreachable.
Rule: DO SQL queries on request-serving paths must not use correlated subqueries or per-row scans against unbounded tables. Pre-compute in a materialized table maintained atomically at write time.
Why: DO SQL runs inside the Worker request handler. A full table scan blocks the entire request. DO has no query optimizer.
✅ Compliance:
dsh_session_summariesis a materialized table maintained bysyncSummaries()at write time. Session listing reads from this table instead of scanningdsh_session_events.
❌ Violation:
SELECT s.id, (SELECT MAX(seq) FROM dsh_session_events e WHERE e.session_id = s.id) FROM dsh_sessions s
Rule: Never log DSH_EDGE_ACCESS_KEY, bearer tokens, or owner cookies. Resolved values remain request-scoped and are never logged, cached across requests, or written to session events.
Why: Worker logs are accessible via Cloudflare dashboard. Session events are transmitted over WebSocket — embedding credentials broadcasts them to every connected client.
✅ Compliance:
EdgeCredentialProvider.describe()returns{ configured, source, writable }without the value. Auth failure logs'The access key is not valid.', never the submitted key.
❌ Violation:
console.log('API key resolved:', credential.value). Or storingresolvedApiKeyon the DO instance across requests.
Rule: When registering a cordis sub-registry entry, call ctx.provide(key, value) if another plugin uses ctx.inject([key]). Sub-registry register() only updates internal Maps; it does not trigger inject resolution. Use ctx.effect() to pair registration with provide and clean up on disposal.
Why: Without the paired provide, downstream plugins like StorageDomain never start, and the session store silently hangs on boot.
✅ Compliance: In
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) } })
❌ Violation:
ctx.storage.backend.register('durable-object', storageBackend)without callingctx.provide().
Rule: Direct mode must stay below the repository gzip budget. Release tests must start the promoted prebuilt artifacts, not source entrypoints.
Why: Workers have a hard 10 MiB compressed limit. Testing prebuilt artifacts catches bundler regressions that only manifest in the production build.
✅ Compliance:
bundle-size.mjsthrows if gzip budget exceeded. Snapshot tests run against bundled output.
❌ Violation: Running integration tests against
src/index.tsvia Vite dev server instead of the promoted prebuilt Worker.
Rule: Every retained upstream patch needs a version-bound filename, a failing-without-the-patch check, a rationale, and a removal condition.
Why: Without a version-bound filename, patches silently outlive their purpose. Without a failing-without test, patches become no-ops.
✅ Compliance: All 7 patches include the upstream version in their filename:
@deepseek-ai__dsh-sandbox@0.1.1-rc.2.patch.
❌ Violation: A patch named
fix-llm-streaming.patchwith no version binding, no test, no removal condition.
Rule: The npm package, tag, GitHub Release, deployment identity, and documentation must report the same dsh-edge version. apps/dsh-edge/package.json is the only release-version source.
Why: Version drift between npm, GitHub, and deployment creates confusion about what's actually running.
✅ Compliance:
repository-metadata.spec.tsasserts onlyapps/dsh-edge/package.jsonhas a version. Snapshot tests derive the expected version from this single source.
❌ Violation: Adding
"version": "0.7.1"to the rootpackage.json.
Skills are structured instruction files (SKILL.md) that AI agents load before performing specific workflows. The three skills form a pipeline:
┌─────────────────────┐
│ codex-review-loop │ Drives the overall PR lifecycle
│ │ (triage → fix → push → review → CI)
└──────┬──────┬───────┘
│ │
▼ ▼
┌──────────┐ ┌──────────────────┐
│ dsh-code │ │ dsh-pre-push │
│ -review │ │ -checks │
└──────────┘ └──────────────────┘
Judges Selects and runs
findings checks before push
| Skill | Purpose | When Used |
|---|---|---|
dsh-pre-push-checks |
Select and run minimum-sufficient checks before pushing | Before any push or PR-ready transition |
dsh-code-review |
Review PRs for Edge-specific correctness (8 blocking checks) | Judging review findings; deciding merge-readiness |
codex-review-loop |
Drive PR through bounded review and CI convergence | After opening/updating a PR |
Classifies changed files by owned surface and selects the minimum evidence needed:
- Runtime/storage/auth → focused unit test + affected integration path
- Edge client/UI → focused test + browser/runtime snapshot suite
- Standalone deps/patches/bundle → standalone build + verifier + promote prebuilt artifacts
-
Installer/release → pack +
pack:verifyoutside workspace -
Docs/governance →
pnpm run doc-sync+ manual bilingual comparison - Cross-cutting → full suite: check, both builds, integration, snapshots, package verify
Eight blocking checks specific to dsh-edge PRs:
- Upstream composition from exact published packages (no copied source)
- Direct/Dynamic artifact parity
- Durable Object compatibility
- Credential safety (never in durable state, logs, fixtures)
- Direct mode gzip budget
- Patch discipline (version-bound, justified, tested, removable)
- Installer/release cross-platform and secret safety
- Product/legal prose — independent project, not DeepSeek-affiliated
A state machine that drives PRs through iterative review rounds:
- One tick per invocation — read snapshot, triage all findings, make one fix batch, push, request review.
-
Finding triage — each finding gets exactly one of:
fixed,rebutted, oruser-decision. - Convergence enforcement — 2nd occurrence → general repair; 3rd → strategy reset; every 2 actionable rounds → checkpoint.
- Completion contract — ready-to-merge requires stable HEAD, all items handled, review passed, CI green. Never merges automatically.
- Read
AGENTS.md— understand ownership boundaries and the 9 contracts above. - Create a worktree for your branch (never work directly on main).
- Run
pnpm installandpnpm --dir apps/dsh-edge/standalone install --frozen-lockfile.
- Classify your changes by surface (runtime, client, standalone, installer, docs, cross-cutting).
- Run the minimum checks for that surface (as defined in
dsh-pre-push-checks). - Commit only inspected paths — no blind
git add -A.
- Review findings are claims, not commands — verify each one's premise before acting.
- Assign each finding:
fixed,rebutted, oruser-decision. - Track problem families — if the same family appears twice, stop patching and write one general repair.
- Never merge the PR yourself — report readiness and let the maintainer decide.
- Write bilingual release notes + i18n pairing →
pnpm run doc-pairs -- --write - Merge release PR to main (squash merge)
- Tag:
git tag dsh-edge-v<version> && git push origin dsh-edge-v<version> - Verify:
npm view dsh-edge@<version>andgh release view dsh-edge-v<version>
Contracts vs. conventions. These rules are not style preferences — they are invariants that protect durable state, credential safety, and upgrade paths. The underlying principle is maximize upstream capability leverage: use published packages as-is, write the smallest possible adapter layer, and ensure that adapter can absorb upstream changes without rewriting.
- Home
- Architecture
- Core & Scope
- Session & Persistence
- Model & Context
-
Execution & Tools
- Tools
- Bash
- Subprocess 🚫
- PTY Session 🚫
- Background Jobs 🚫
- Filesystem
- LSP Navigation 🚫
- Code Runtime 🚫
-
Web Access
⚠️ -
Skills
⚠️ - Workflow 🚫
- Subagent 🚫
-
Policy & Interaction
- Goal
- Approval 🚫
- Permission Presets 🚫
-
Sandbox
⚠️ - Plan Mode 🚫
- User Interaction 🚫
- Commands 🚫
- Schedule 🚫
- Message Feedback 🚫
- Platform & Access
- Development
- 首页
- 架构
- 核心与作用域
- 会话与持久化
- 模型与上下文
- 执行与工具
- 策略与交互
- 平台与接入
- 开发