feat: Add LSP plugin unit tests and frontend common initialization library
Some checks failed
CI / Determine matrix (push) Has been cancelled
CI / Sanitizer (ASan+UBSan) / ubuntu-24.04 (push) Has been cancelled
CI / Coverage (gcovr) / ubuntu-24.04 (push) Has been cancelled
CI / ${{ matrix.os }} / ${{ matrix.build_type }} (push) Has been cancelled

- Introduced `dstalk_lsp_plugin_test` for testing LSP plugin functionalities including `lsp_trim`, `lsp_frame_message`, and `lsp_parse_content_length`.
- Created `dstalk_frontend_common` static library to encapsulate shared initialization logic for frontend components (CLI, GUI, Web).
- Implemented configuration file discovery and service querying in `dstalk_frontend_init`.
- Added internal headers for LSP and Anthropic plugins to facilitate unit testing.
- Established a mailroom system for asynchronous message passing between stateless agents, enhancing coordination and context management.
This commit is contained in:
2026-06-01 08:51:40 +08:00
parent 8faa02c3d5
commit c0af9c65c7
17 changed files with 1235 additions and 69 deletions

View File

@@ -1,6 +1,6 @@
# dstalk 实时编制状态
> **最后更新**: 2026-05-27
> **最后更新**: 2026-05-31
> **数据来源**: 由 `scripts/refresh_status.py` 自动扫描全部 16 个 `agents/*/profile.md` + 5 个 `agents/groups/*.md` 生成。
## 表 1员工状态16 人)
@@ -40,7 +40,7 @@
## Wave 进度
**已完成高水位**: W16.5(基于 16 份 profile.md 的 performance_log 聚合
**已完成高水位**: W17由 CEO 直接执行ai_common 模块提取
**已发现 Wave 编号**: W1.1, W2.1, W2.2, W5.1, W6.1, W7, W9.3, W9.4, W9.6, W9.10, W10.1, W10.2, W10.3, W10.4, W11, W11.1, W11.2, W11.3, W11.6, W11.7, W12, W12.1, W12.2, W12.4, W12.5, W12.6, W13.1, W13.2, W13.3, W13.4, W13.5, W13.6, W14.1, W14.2, W14.3, W14.4, W14.5, W15.1, W15.2, W15.3, W15.4, W15.5, W15.6, W15.7, W15.8, W15.9, W16.5
**已发现 Wave 编号**: W1.1, W2.1, W2.2, W5.1, W6.1, W7, W9.3, W9.4, W9.6, W9.10, W10.1, W10.2, W10.3, W10.4, W11, W11.1, W11.2, W11.3, W11.6, W11.7, W12, W12.1, W12.2, W12.4, W12.5, W12.6, W13.1, W13.2, W13.3, W13.4, W13.5, W13.6, W14.1, W14.2, W14.3, W14.4, W14.5, W15.1, W15.2, W15.3, W15.4, W15.5, W15.6, W15.7, W15.8, W15.9, W16.5, W17

249
agents/mailroom/README.md Normal file
View File

@@ -0,0 +1,249 @@
# Mailroom — agents 信箱系统
> **版本**: 1.0 草案 (2026-05-31 设计)
> **状态**: 试运行;格式稳定后由 CEO 决定是否在 WORKFLOW.md §15 正式纳入流程
> **设计目标**: 让无状态的子代理之间能异步传递消息,把进行中的协调状态从 CEO 的隐式上下文搬到磁盘
## 1. 设计动机
子代理是 stateless 的——每次 spawn 都是新会话,看不到其他子代理当前在做什么。现行所有协调依赖 CEO 在 prompt 里手动列禁忌、手动转交依赖、手动追踪谁回了什么。一波 6-9 路子代理并行时CEO 的上下文窗口很快被占满。
信箱让这些消息**显式落盘**
- CEO 派活前可以扫一遍候选执行者的 inbox看有没有未结的 handoff / blocker
- 子代理 spawn 时可以读到自己的待办邮件,了解上下文
- 处理完毕的邮件归档到 `archive/W<n>/`,不丢失追溯,但不打扰当前视图
## 2. 目录结构
```
agents/mailroom/
├── README.md # 本文件
├── inbox/
│ ├── ceo/ # CEO 的收件箱
│ ├── architect-lin/ # 各 agent 的收件箱(按需创建)
│ ├── engineer-zhao/
│ └── ...
└── archive/
├── W17/ # 按 Wave 归档已处理邮件
├── W18/
└── ...
```
- `inbox/<agent-id>/` —— 待处理邮件status: pending / read / in_progress
- `archive/W<n>/` —— 处理完毕邮件status: closed按 Wave 归档保留
- 收件箱目录按需创建,未创建表示该 agent 当前无邮件
## 3. 权限规则
文件系统不强制权限;权限靠子代理 prompt 中的禁忌条款约束。
| 角色 | 自己的 inbox | 别人的 inbox | archive/ |
|------|--------------|--------------|----------|
| 接收者本人 | 读 / 改 status / 移到 archive | 只能投递新邮件write-only | 只读 |
| CEO | 所有权限 | 所有权限(含重投递、强制保留) | 所有权限 |
| 其他子代理 | — | 只能投递新邮件 | 只读 |
派子代理时 prompt 必须显式声明可访问的邮箱范围。新增防御性规则 **R-MAIL-SCOPE**:子代理不得读写超出自身 inbox 之外的他人邮箱内容,仅可投递新邮件。
## 4. 消息文件命名
`<timestamp>-<kind>-<from>-to-<to>.md`
- timestamp: `YYYY-MM-DDTHHmm` 本地时间,分钟级即可区分
- kind: 见 §5
- from / to: agent-idCEO 用 `ceo`,广播用 `all`
示例:`2026-05-31T1430-task-ceo-to-architect-lin.md`
## 5. 五种邮件类型
| kind | 用途 | 投递方 | 接收方 |
|------|------|--------|--------|
| task | CEO 派活prompt 副本,便于事后追溯) | CEO | 执行者 |
| report | 子代理回执done / blocked / aborted | 执行者 | CEO |
| handoff | 子代理之间工作交接(前序产出移交下一棒) | 子代理 A | 子代理 B |
| blocker | 阻塞通知(依赖未满足) | 任何 | CEO必抄送 |
| notice | 广播in-flight 文件锁定 / 流程变更 / 元数据自检失败) | CEO 或系统 | all |
## 6. Frontmatter schema
```yaml
---
id: msg-W17.3-001 # 全局唯一,格式 msg-<Wave>-<序号>
from: ceo
to: architect-lin # 单人用 agent-id广播用 all
wave: W17.3
kind: task # task | report | handoff | blocker | notice
status: pending # pending | read | in_progress | closed
created: 2026-05-31T14:30
closed: # 处理完毕时填写YYYY-MM-DDTHHmm
related: # 关联消息 id 列表(如本报告对应的 task
- msg-W17.3-000
fixes: # 关联 findings-registry 的 finding id如有
- F-13.5-1
---
邮件正文markdown
```
- 必填字段:`id` / `from` / `to` / `wave` / `kind` / `status` / `created`
- 选填字段:`closed` / `related` / `fixes`
- 字符串值不带引号YAML 1.2 标准)
## 7. 生命周期
```
[投递] [归档]
│ │
▼ ▼
inbox/<to>/ pending ──→ read ──→ in_progress ──→ 处理完毕 archive/W<n>/
status: closed
```
操作动作:
| 动作 | 谁执行 | 文件操作 | status 字段 |
|------|--------|----------|--------------|
| 投递 | 任意 agent | 在 `inbox/<to>/` 创建新文件 | pending |
| 阅读 | 接收者 | frontmatter 改 status | read |
| 开工 | 接收者 | frontmatter 改 status | in_progress |
| 完成 | 接收者 | 移动文件到 `archive/W<n>/` + 改 status | closed |
| 重投递 | 仅 CEO | 复制 archive 中的文件到 inbox保留原件 | pending |
接收者**不可物理删除**邮件——只允许移到 archive如需删除由 CEO 手动操作。这是与 R-NO-FORCE-PUSH 同等级的强约束(新增 **R-MAIL-NO-DELETE**)。
## 8. 与现有机制的边界
| 机制 | 职责 | 与 mailroom 的区别 |
|------|------|---------------------|
| `STATUS.md` | 实时编制状态快照 | 由 `scripts/refresh_status.py` 扫 profile.md 生成mailroom 是消息流 |
| `agents/<id>/profile.md` performance_log | 永久任务履历 | 任务粒度事后追加mailroom 是消息粒度,进行中 |
| `agents/audits/findings-registry.md` | 审计发现追踪 | 跨 Wave 持续追踪mailroom 单条消息生命周期短(一波内闭环) |
| `WORKFLOW.md` | 流程规范 | 是规则mailroom 是规则产生的数据 |
**重叠处理原则**:邮件正文 ≠ 履历正文。task 邮件中的 prompt 是 CEO 派活的原始材料report 邮件中的回执是子代理的原始报告;最终摘要仍按现有流程写到 profile.md 的 performance_log 一条短记录。**邮件保留细节profile.md 保留摘要,两者互补不重复**。
审计发现的归宿仍是 findings-registry。blocker 邮件如对应某个 findingfrontmatter 的 `fixes` 字段填写 finding idCEO INSPECT 时按 §14.4 A3 检查关联。
## 9. CEO 派活前 5 步检查
扩展 [PROMPT_TEMPLATE.md](PROMPT_TEMPLATE.md) 的 CEO 派活前 4 步检查,新增第 5 步:
| # | 检查项 | 操作 | 写入模板字段 |
|---|--------|------|--------------|
| 1 | 列 in-flight 工作区 | 查当前有哪些子代理在跑 | 禁忌 |
| 2 | 找前序 Wave 产出 | 从 performance_log 追溯 | 前序成果 |
| 3 | 设定任务范围三档 | 必做 / 可做 / 不做 | 任务范围 |
| 4 | 统一字数上限 | 固定 250 字 | 字数上限 |
| **5** | **扫候选执行者 inbox** | `ls agents/mailroom/inbox/<候选id>/` 看 pending 的 handoff / blocker | 禁忌 / 前序成果 |
若候选执行者 inbox 有未结的 blocker依赖未满足→ 优先让其处理 blocker 再派新活,否则新活也会立即变 blocker。
## 10. 邮件示例
### 10.1 task 邮件
文件:`inbox/architect-lin/2026-05-31T1500-task-ceo-to-architect-lin.md`
```markdown
---
id: msg-W18.1-001
from: ceo
to: architect-lin
wave: W18.1
kind: task
status: pending
created: 2026-05-31T15:00
---
# W18.1 任务: 评审 mailroom 设计
请读 agents/mailroom/README.md 并评估:
- 是否值得正式纳入 WORKFLOW.md §15
- 权限规则在 prompt 层面如何强约束
- 与 findings-registry 的边界是否清晰
字数上限 250。完成后请发 report 邮件回 ceo。
```
### 10.2 report 邮件
文件:`inbox/ceo/2026-05-31T1630-report-architect-lin-to-ceo.md`
```markdown
---
id: msg-W18.1-002
from: architect-lin
to: ceo
wave: W18.1
kind: report
status: pending
created: 2026-05-31T16:30
related:
- msg-W18.1-001
---
# W18.1 评审结论
赞成纳入 §15。建议补充三条边界规则
1. 接收者不可删除别人邮箱里的邮件
2. CEO 重投递时必须复制而非移动,保留 archive 原件
3. blocker 邮件必须抄送 CEO
profile.md 已追加rating: A-。
```
### 10.3 handoff 邮件
文件:`inbox/qa-xu/2026-05-31T1700-handoff-engineer-sun-to-qa-xu.md`
```markdown
---
id: msg-W18.2-003
from: engineer-sun
to: qa-xu
wave: W18.2
kind: handoff
status: pending
created: 2026-05-31T17:00
related:
- msg-W18.2-001
---
# W18.2 LSP 死锁修复完成,请测
修复了 lsp_plugin.cpp:312 的死锁。需要你跑:
- `ctest -R lsp_plugin_test`
- `ctest -R smoke`
测试通过后请新建一封 report 邮件发给 CEO 并抄送我。
```
## 11. 后续路线v1.0 之外)
格式稳定 + CEO 在 2-3 个 Wave 中实战使用后,再考虑:
- 在 WORKFLOW.md §15 加一节正式纳入流程
- 补充 `scripts/mailroom_summary.py` 自动汇总每个 agent 的未读邮件数与最老 pending 邮件年龄
- 在 STATUS.md 增加 邮件待办数 列
- 扩展 `scripts/check_agents_metadata.py` 校验邮件 frontmatter
不在 v1.0 范围。先用 1-2 个 Wave 看实际效果再说。
## 12. 关联文档
- [WORKFLOW.md](../WORKFLOW.md) — 流程主文档mailroom 将来可能并入 §15
- [PROMPT_TEMPLATE.md](../PROMPT_TEMPLATE.md) — 派活模板(影响第 5 步检查)
- [STATUS.md](../STATUS.md) — 实时编制状态
- [findings-registry.md](../audits/findings-registry.md) — 审计发现追踪
- [POSTMORTEM.md](../POSTMORTEM.md) — 防御性规则(新增 R-MAIL-SCOPE / R-MAIL-NO-DELETE
## 13. 变更历史
| 日期 | 版本 | 变更 |
|------|------|------|
| 2026-05-31 | 1.0 草案 | 初始化。CEO 与用户讨论后落地,方案 2归档保留不真删 |