# AGENTS.md

你在协助维护 **dsh-pentester/**：一个基于 DeepSeek Harness（DSH）的 out-of-tree 插件，实现最小化 Root-Orchestrator PTES 渗透测试流程。

你的任务是和仓库主人一起把插件做出来。

核心原则：

```text
优先复用 Harness
优先复用现有代码
优先保持结构简单
优先保证人类容易理解、协作和维护
```

你不应该：

* fork DeepSeek Harness
* 重新实现 Harness 已有的 Agent / Session / Tool Runtime
* 另造一套与仓库文档冲突的架构
* 在当前任务之外顺手扩展功能
* 根据“看起来合理”自行发明 Harness API
* 为了“架构优雅”引入没有实际价值的层级、抽象或目录
* 在已有模块能清晰承载职责时无意义拆文件
* 把一个简单流程拆成多层 service / manager / adapter / handler
* 把代码塞进泛化的 `utils/`、`common/`、`core/`、`services/` 垃圾桶目录

---

# 1. 权威事实来源

架构与实现以以下顺序为准：

```text
1. docs/plan.md
   └── Wave 7 最小化 Root-Orchestrator 架构
   └── 当前唯一架构计划

2. CONTEXT.md
   └── canonical 领域术语
   └── PentestRun / AgentProfile / Delegation / task_prompt 等

3. docs/adr/0007
   └── 当前架构决策
   └── supersede 旧 0001 / 0002 / 0004

4. docs/architecture.md
   docs/workspace.md
   └── 当前代码布局与磁盘布局

5. docs/deepseek-harness/
   └── DSH 官方文档

6. 当前代码
   └── 当前真实实现状态
```

其中：

```text
docs/plan.md
=
架构决策的最高依据

CONTEXT.md
=
术语依据

当前代码
=
判断实际行为、已有 helper、已有 seam 和真实结构的依据
```

除上述文档外，其余历史设计文档不得自动视为当前事实。

---

# 2. DSH 外部事实来源

涉及以下内容时：

* DSH API
* Cordis 扩展点
* Plugin contract
* Tool contract
* Agent / Session 生命周期
* Tool restriction
* Context / prompt injection
* Native Agent Registry
* Harness runtime 行为

必须先查证，不得自行推测。

查阅顺序：

```text
1. docs/deepseek-harness/
   └── 官方源码仓库的本地只读 clone
   └── 优先阅读 docs/
   └── 必要时继续读源码

2. node_modules/
   └── 当前安装版本的 .d.ts / package exports
```

规则：

* 不发明 Harness API
* 不猜测 method 名称
* 不猜测 lifecycle hook
* 不猜测 Cordis service contract
* 不把官方仓库代码复制进 `src/`
* 不修改 `docs/deepseek-harness/`

如果需要使用一个当前仓库从未用过的 DSH API，必须先找到明确依据再实现。

---

# 3. 当前架构边界

必须保持与 `docs/plan.md` 一致。

```text
Root Agent
→ DSH 会话 + pentester persona preset
→ 唯一 Orchestrator
→ 判断信息缺口
→ 创建 / 取消 Delegation
→ 判断 Stage 是否推进

Root 工具只有：
→ pentester_run
→ pentester_delegate
→ pentester_cancel_delegation
→ pentester_advance_stage
→ pentester_rollback_stage
→ ask_user_question
→ send_message / interrupt_agent / list_agents
（正向 allow-list：ROOT_ALLOW —— 未列出的工具（container_exec、skill、
全部 mcp__*、未来新增 global tools）对 Root 不可见）
```

```text
Delegation
→ 一次委托 = 一个 DSH child session
→ task_prompt 是不可变 snapshot
→ Delegation 可并行
```

```text
Worker
→ prompt =
   baseline
   + AgentProfile.systemPrompt
   + trusted metadata
   + task_prompt

→ 工具（per-Delegation toolFilter allow-list）：
   pentester_container_exec
   + 官方 skill
   + profile.mcps 分配的 mcp__<serverName>__* 工具（第一轮即可用）
   （MCP 由 Host 经官方 @deepseek-ai/dsh-mcp-client 加载共享实例；
   见 docs/mcp.md）

→ 不能创建 Delegation
→ 编排树只有：

Root
 ├── Worker
 ├── Worker
 └── Worker
```

```text
Deliverable
→ 普通文件
→ 位于 Workspace 约定目录
→ 不存在 Artifact / Evidence / Finding store 实体
```

```text
持久化
→ 每 Project 单一 .dsh-pentester/run.json
→ snapshot 模型
→ 无事件回放
```

禁止重新引入已经删除的概念：

```text
Task
AgentRun
PTAP
ToolBroker
criteria engine
ContextBundle
Artifact entity
Evidence entity
Finding entity
```

除非仓库主人明确要求重新设计。

---

# 4. 修改前必须先审查目录与代码结构

这是强制步骤。

开始修改前，必须先理解当前仓库结构，而不是直接创建新文件。

至少执行：

```bash
git status --short
git diff --stat
```

并查看与当前任务相关的目录结构。

推荐：

```bash
find src -maxdepth 3 -type f | sort
```

或者：

```bash
tree -L 3 src
```

同时查看当前任务直接相关的：

* 类型定义
* 入口文件
* 相邻模块
* 测试
* 文档
* exports
* package scripts

---

## 4.1 写代码前必须回答这些问题

在决定创建文件或目录前，先判断：

```text
1. 当前功能已经属于哪个现有模块？
2. 是否可以直接扩展现有文件？
3. 是否已有 helper / type / seam 可以复用？
4. 新建文件是否真的形成了独立职责？
5. 新建目录是否真的包含一组相关模块？
6. 新增抽象是否减少了复杂度，而不是增加跳转？
7. 人类维护者以后能否快速找到这段代码？
```

如果答案倾向于：

```text
“现有模块就能清楚承载”
```

则不要新建文件。

如果只是：

```text
一个 20 行 helper
一个 schema
一个简单 wrapper
```

通常优先与直接消费者放在一起。

---

# 5. 目录结构原则

目标不是“最标准的架构”，而是：

> **最容易理解、最容易修改、最少跳转、最适合人类协作维护。**

---

## 5.1 优先浅层结构

优先：

```text
src/
├── index.ts
├── tools.ts
├── delegations.ts
├── store.ts
├── dsh.ts
└── docker/
    ├── runtime.ts
    ├── host.ts
    └── images.ts
```

而不是：

```text
src/
└── application/
    └── services/
        └── orchestration/
            └── delegation/
                └── handlers/
                    └── delegate-handler.ts
```

合理嵌套是允许的，但每一级目录必须有明确用途。

---

## 5.2 什么时候可以新建目录

只有当某个领域已经自然形成多个相关文件时才新建目录。

例如：

```text
docker/
├── runtime.ts
├── host.ts
├── connection.ts
└── images.ts
```

这是合理的。

但不要因为只有：

```text
workspace.ts
```

就提前创建：

```text
workspace/
├── index.ts
├── service.ts
├── types.ts
└── utils.ts
```

---

## 5.3 避免“架构占位目录”

不要提前创建：

```text
services/
repositories/
managers/
handlers/
controllers/
domain/
application/
infrastructure/
common/
shared/
core/
utils/
```

除非当前代码真的需要这些边界。

---

## 5.4 避免过度拆文件

不要追求：

```text
一个 class 一个文件
一个 function 一个文件
一个 schema 一个文件
一个 type 一个文件
```

优先按“人类理解单元”组织。

例如：

```text
delegations.ts
```

可以合理包含：

```text
DelegationService
delegation lifecycle helpers
与 delegation 强绑定的小类型
```

不必强拆成：

```text
delegation-service.ts
delegation-spawn.ts
delegation-settle.ts
delegation-cancel.ts
delegation-types.ts
```

除非文件已经明显失去可读性。

---

# 6. 代码组织原则

优先：

```text
small
typed
explicit
local
boring
testable
```

这里的 `boring` 是优点。

---

## 6.1 优先直接代码

优先：

```ts
const run = loadRun(projectDir)
saveRun(projectDir, run)
```

而不是：

```ts
runRepository
  .forProject(projectDir)
  .getStore()
  .loadCurrent()
```

除非这种抽象确实解决已有问题。

---

## 6.2 控制间接层数

一个简单功能不应该需要连续跳转很多文件才能理解：

```text
tool
→ handler
→ service
→ manager
→ adapter
→ repository
→ helper
```

优先：

```text
tool
→ domain/service
→ store/runtime
```

---

## 6.3 抽象必须有收益

新增 abstraction 前必须能说明至少一个明确收益：

```text
消除真实重复
形成清晰边界
便于测试
封装外部 API
隔离副作用
```

如果只是：

```text
以后可能会扩展
看起来更规范
架构更漂亮
```

则不要引入。

---

## 6.4 不创建泛化垃圾桶

避免：

```text
utils.ts
helpers.ts
common.ts
misc.ts
types.ts
```

逐渐变成无边界集合。

优先：

```text
docker/connection.ts
settings-store.ts
delegations.ts
```

也就是名字直接表达职责。

---

## 6.5 导出面尽量小

模块只暴露真正需要被其他模块使用的内容。

不要为了测试或“以后可能用”把内部 helper 全部 export。

---

# 7. 人类协作优先

代码必须优先考虑：

```text
另一个维护者第一次打开仓库时能否快速理解
```

因此：

* 文件名要表达职责
* 函数名要表达行为
* 少用隐式 magic
* 少用全局状态
* 少用过度 generic abstraction
* 少用无意义 wrapper
* 重要行为显式写出来
* 关键 contract 靠 type + test，而不是复杂设计模式

注释重点解释：

```text
WHY
```

而不是重复代码已经表达的：

```text
WHAT
```

---

# 8. 安全边界

当前安全模型是显式让步后的版本。

保留：

```text
镜像白名单
→ 仅项目 Dockerfile 构建的 Toolbox

容器 HostConfig 硬化
→ 禁 privileged
→ 禁 host network
→ 禁 host pid
→ 禁 host ipc
→ capAdd 白名单
→ 禁 docker.sock

caller 校验
→ Root / Worker 工具面隔离

PentestRun 开始前
→ ask_user 预授权门

RoE / Scope
→ 作为数据注入 prompt
```

当前 deferred：

```text
程序化 approval 流
scope 参数级检查
```

未经明确要求：

* 不重新实现 approval
* 不实现 scope enforcement engine
* 不在 prompt / tool 内另造安全政策

---

# 9. 范围纪律

只修改当前任务必须修改的内容。

禁止：

```text
顺手重构
顺手统一命名
顺手迁目录
顺手升级依赖
顺手优化无关模块
顺手增加未来能力
```

当前 PLAN 明确不做的内容也不要提前实现：

```text
approval 流
数据面板 UI
HTML / PDF 报告
多 PentestRun 并发
stage 跳跃 override
Worker 二级委派
```

发现范围外问题：

```text
记录
汇报
停止扩展
```

---

# 10. 依赖纪律

引入新依赖之前先检查：

```text
1. Node 标准库是否足够
2. DSH / Cordis 是否已有能力
3. 当前仓库是否已有依赖可以完成
```

只有确有必要才新增依赖。

新增依赖必须在最终汇报说明：

```text
为什么需要
用于什么
为什么现有能力不够
```

---

# 11. 测试纪律

完成修改后必须运行：

```bash
pnpm run check
pnpm test
```

其中：

```text
pnpm run check
=
tsc --noEmit
+
build
```

同时：

```bash
git diff --check
git status --short
```

不要：

* 替换测试框架
* 为了让测试通过删除有效断言
* 静默忽略失败
* 把非基线失败说成成功

---

# 12. 修改后再次审查结构

代码完成后，不只看测试。

还必须重新检查：

```bash
git diff --stat
git status --short
```

并审查新增 / 修改的目录结构。

必须确认：

```text
[ ] 是否新增了不必要的文件
[ ] 是否新增了只有一个文件的无意义目录
[ ] 是否出现过深嵌套
[ ] 是否存在职责重复模块
[ ] 是否引入了无意义 abstraction
[ ] 是否有 helper 更适合放回调用者附近
[ ] 是否让代码比修改前更难导航
[ ] 是否保持了人类容易理解的结构
```

如果一个修改：

```text
功能只增加一点
但文件和层级明显增加很多
```

必须重新评估设计。

---

# 13. 文档同步

如果本次修改改变：

* 代码行为
* runtime contract
* workspace contract
* tool contract
* Agent lifecycle
* Delegation lifecycle
* 持久化格式

则同一轮修改相关文档。

文档必须回到与 `docs/plan.md` 一致的状态。

不要更新与当前任务无关的历史文档。

---

# 14. 完成前检查

```text
[ ] 与 docs/plan.md 一致
[ ] 使用 CONTEXT.md canonical terminology
[ ] 没有重新引入已删除概念
[ ] 没有重新实现 Harness 已有能力
[ ] DSH API 已有明确依据
[ ] 修改范围只覆盖当前任务
[ ] 已先审查目录与代码结构
[ ] 没有无意义新增目录
[ ] 没有过度拆文件
[ ] 没有过度抽象
[ ] 代码结构仍然容易导航
[ ] 设计以实用和人类维护为优先
[ ] 文档与代码同步
[ ] pnpm run check 已运行
[ ] pnpm test 已运行
[ ] git diff --check 已运行
[ ] git status --short 已检查
```

---

# 15. 最终汇报

最终汇报固定包含：

```text
1. 完成内容

2. 创建 / 修改文件

3. 目录与代码结构审查
   - 是否新增目录
   - 是否新增文件
   - 为什么需要
   - 是否复用已有模块
   - 是否存在更简单方案
   - 最终为什么选择当前结构

4. 关键设计或行为变化

5. 测试 / 检查命令与结果

6. 新增依赖
   - 无
   - 或列出并解释原因

7. 与 PLAN 的偏差
   - 无
   - 或说明

8. 发现但未处理的问题

9. git diff --stat

10. 是否可以进入下一阶段
    YES / NO
```

完成当前任务后停止。

不要自动开始下一阶段。

---

# 16. 遇到冲突时

以下情况优先停止并报告：

```text
与 docs/plan.md 冲突

需要 fork / patch Harness

需要新增执行 backend

需要绕过现有安全边界

需要发明未确认的 DSH API

需要明显扩大当前任务范围

需要大规模迁移目录才能完成一个小功能

需要引入复杂架构才能完成简单行为

测试出现无法解释的非基线失败
```

---

# 17. Conventional Commits

本仓库使用 [Release Please](https://github.com/googleapis/release-please-action) 自动化版本管理。

PR 合并到 `main` 时使用 **Squash and merge**，最终 squash commit title 必须采用 Conventional Commits 格式。

```text
feat: 新增功能描述
fix: 修复问题描述
perf: 性能优化描述
refactor: 重构描述
revert: 回滚描述
```

Breaking Change：

```text
feat!: 破坏性变更描述
```

或在 commit body 中包含：

```text
BREAKING CHANGE: 变更说明
```

以下类型不会触发版本升级（隐藏于 changelog）：

```text
docs    - 文档变更
test    - 测试变更
build   - 构建系统变更
ci      - CI/CD 变更
chore   - 杂项维护
style   - 代码风格
```

版本规则：

```text
fix:      2.2.0 → 2.2.1 (patch)
feat:     2.2.0 → 2.3.0 (minor)
feat!:    2.2.0 → 3.0.0 (major)
```
