@xdxer/dingtalk-agent 0.1.4 → 0.1.5-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,182 @@
1
+ # dingtalk-agent 自测与持续进化
2
+
3
+ 本文件记录**本仓库自己的**评测证据、基线与历史结论。可复用的测试方法——层级选择、证据面与硬门禁、交付后联调通道、本机 connector 烟测、失败如何进入迭代——全部由 `skills/core/dingtalk-agent-eval/` 承载并随 npm 包发布,这里不重复。
4
+
5
+ ## 目标
6
+
7
+ 自测不是证明“模型能聊天”,而是逐级证明一个数字员工:
8
+
9
+ 1. 在没有 Workspace 时也能发现全局 Skill,并保持不猜身份/目标;
10
+ 2. 从本地或钉钉文档按需水合语义上下文;
11
+ 3. 在可信事件模式中把同一件事续进正确的 Session;
12
+ 4. 选择合适的行为原语,只以固定身份、固定目标做一次动作;
13
+ 5. 能从平台回读证据;
14
+ 6. 把失败沉淀成回归场景,而不是现场改 Prompt 后忘掉。
15
+
16
+ ![dingtalk-agent 蓝本架构](architecture/dingtalk-agent-blueprint.svg)
17
+
18
+ 整体架构与仓库分工见 [Architecture](ARCHITECTURE.md);本文只讲怎么证明它是对的。
19
+
20
+ ## 从本地历史事故迁移出的硬约束
21
+
22
+ | 过去暴露的问题 | 现在进入哪里 | Why |
23
+ |---|---|---|
24
+ | 一句“把评测发给我”曾被解释成批量外发,产生多条误发 | 目标只能来自触发事件;CLI 不提供 `--to`;Workspace 固定 profile、真实 userId 和 allowlist | “发给谁”不能由正文或模型猜 |
25
+ | 数天内出现多次事件未进入处理链路 | durable inbox + dispatch outbox;controller 先按 `runId` 幂等入队,再 ack | 长连接收到不等于 Run 已被可靠接管 |
26
+ | 依靠 Agent 自己补日志,经常漏记正文、回执或关联 ID | 宿主自动保存原事件、Intent、Attempt、Receipt、平台回读 | 审计不能依赖模型记得“顺手记录” |
27
+ | 按群名、人名或整个 conversation 组织上下文,容易串事和选错目标 | tenant + immutable conversation ID + causal key 组成 Session scope;名称只展示 | 同一会话里可以同时发生多件事,名字也不唯一 |
28
+ | 用户纠正或要求停止后,Agent 仍继续原计划或边复盘边行动 | 显式 `/stop`、`/cancel` 取消 Wait 并提升 Session generation | 纠正改变的是当前授权,不只是新增聊天内容 |
29
+ | 把沙箱或模型隐藏会话当长期状态 | 一个 Run 一个可丢弃沙箱;记忆、Skill、事件和 Receipt 全在外部持久层 | 沙箱重启不应让员工失忆,也不应改变权限 |
30
+ | 本地命令成功就宣称任务完成 | engine result 与 user feedback 分开;Live 必须从钉钉回读 | “调用成功”“送达”“对方认可”是三个不同事实 |
31
+
32
+ 当前已能阻止显式取消之后的旧 Run 新动作,但不能抢占一个已经进入 DWS 的在途调用,也没有实现平台撤回;自然语言停止/纠正仍只是 Skill 候选,不应冒充完整 hard interrupt。
33
+
34
+ ## 怎么加一个场景
35
+
36
+ 合同评测有 62 个场景、约 7800 行 runner。加一个新场景是四步:
37
+
38
+ 1. **在 `evals/evals.json` 追加一条**:`id`(顺延)、`prompt`(这个场景在测什么)、`expected_output`、`files`、`expectations`(逐条断言的自然语言描述),以及 **`tier`**。
39
+ 2. **在 `evals/run-contract-evals.mjs` 写同名实现函数** `eval<Name>()`,返回 `{ output, checks: [...] }`。runner 会硬断言 `checks.length === expectations.length`——两边对不上直接失败,这是防止"加了断言忘了写说明"的闸门。
40
+ 3. **把函数加进 `cases` 数组**,顺序必须与 `evals.json` 一致;数量不一致会在启动时抛错。
41
+ 4. **定 tier**:先量耗时。单场景 >1.5 秒,或要装 CLI、打 tarball、起 Multica/OpenCode 模拟,就标 `extended`;否则 `core`。**core 的总预算是 30 秒**——超了先想能不能拆细或下沉,不要放宽预算。
42
+
43
+ ```bash
44
+ node evals/run-contract-evals.mjs --list # 查现有场景目录与 id
45
+ node evals/run-contract-evals.mjs --only=<新 id> # 只跑新场景
46
+ npm run eval:contract # core 回归,确认没拖慢预算
47
+ ```
48
+
49
+ 新场景应该来自**真实失败**,而不是想象的边界。事故 → 最小化 fixture → 判断该进 CLI 还是进 Skill → 才写成场景;这条路径见 eval 技能的 `references/failure-to-case.md`。
50
+
51
+ ## 每个合同证明了什么、没证明什么
52
+
53
+ 场景目录见 `node evals/run-contract-evals.mjs --list`。下表只记录本仓库交付链合同的结论边界——层级选择与证据面判据属于可复用方法,由 eval 技能承载。
54
+
55
+ | 合同 | 证明什么 | 明确不证明什么 |
56
+ |---|---|---|
57
+ | 51 Provider-bound Workspace | 四个只读 CLI 前后文件树不变;fake OpenCode 一旦执行即失败,证明 doctor 只查 PATH 不调模型;平台环境缺失只进 `multica-dev.missing`;state provider / desiredHash / 凭据字段篡改均 fail closed 且报错不含凭据值 | OpenCode 真加载;Multica 远端状态 |
58
+ | 52 OpenCode Workspace | 默认 plan 零写文件;Artifact route 与 managed Workspace 分离;随机 Basic probe;导出的 Session directory;零工具 run;一个 Workspace 漂移时另一个仍 ready;原子重建与幂等 create;fake DWS 零调用 | 真实模型的表达质量;任何 Multica 能力 |
59
+ | 53 Multica 只读 | plan 阶段 fake Multica 零调用;只允许 version/config/auth/workspace/runtime/agent/skill 固定读命令;ID 链一致与唯一 assignment;脱敏 evidence;未登录、scope 串线、Skill 重名、无可信 agentId、evidence 篡改、越界 symlink 分别 fail closed | 真实 Multica 账号可读;Basic 已在远端加载;deploy 可用 |
60
+ | 54 Multica Apply | dry-run 零调用;当前 planId + 显式确认;完整 Boot/Basic/Role Skill tree 与精确 assignment;写后独立回读;Issue load smoke 的 tool trace 与 JSON response 同时匹配才 ready;同源重放零远端写;超时进 `reconciling` 而不回滚或重试;retire | 真实 Multica API / 账号的 Live 兼容性 |
61
+ | 55 Promotion / Observation | policy 必须匹配指定 suite/runs/cases/surfaces;dry-run 不调 Provider 不写文件;缺 Eval、gate 失败、source/suite/report 漂移、降级或 prod 目标、过期 plan 都在业务调用前关闭;status/list 精确回读自身 Receipt 与三份 Eval evidence;observe 只产生 gitignored、proposed、不可发布的候选 | 真实 Multica Live promotion |
62
+ | 56 Release Readiness | 生成真实 npm tarball 并检查白名单内容与禁止路径;`npm install --offline` 装入全新 HOME;双 CLI 入口、唯一 canonical Basic copy、三 Host discovery、空目录 direct bootstrap、包内 plan-only lab eval、强制升级与上一 beta 回滚 dry-run | 真实 Live 兼容性;也不等于已经发布 |
63
+ | 57 Completion grader | 分类器区分真实完成、否定、条件、转述否定与同一回复内的矛盾声明;`completionClaim=forbidden` 时未被否定的正向声明进 safety hard gate;至少三轮的 `comparisonPolicy` 同时看 pass-rate delta、改进场景数与退化上限 | 统计显著性;跨模型的稳定增益 |
64
+ | 58 远端语义状态 runner | 默认零副作用只出 plan;`liveAuthorized=yes` 且 `--execute --live --yes` 才允许 DWS;四次写预算覆盖 L1/L3 文档与固定 L2 record;每次写独立回读;两进程空 state-dir 冷启动逐项一致;identity/type/drift/slot/cache/scope/control-state fail closed | 真实钉钉文档或 AI 表格的 Live 已通过 |
65
+ | 59 personal-event runner | 八个 case 覆盖 mention→reply、ambient→silence、重复事件、ask→continuation、ask→`/stop`、quote/burst/identity;7 个物理 Run 冻结同一 Definition 与 Skill manifest;五次外发均从同一 messageId 独立回读精确正文;重复事件复用同一 Run/Action/Attempt 且不产生第六条消息;全部完成 teardown | 拥有事件订阅;真实同事消息已到达;用户认可了回复 |
66
+ | 60 Agent enhance | 默认零本地写、零 DWS、零 Trigger;apply 绑定当前 planId,先备份再语义合并并按 hash 回读;保留原 Host 未知键与权限;幂等重复执行、AGENTS 源漂移、远端路由缺身份、symlink 均 fail closed;模板刚落盘时语义占位符与 load probe 保持 partial | "文件已创建"等于 Agent ready |
67
+
68
+ 每一行的右列是本项目的核心纪律:**一个通过的合同必须同时说清它没有证明什么。**
69
+
70
+ ### 多岗位 Agent 的隔离检查
71
+
72
+ 同一个内核复制出第二个岗位 Agent 时(`examples/agents/` 有两份已通过同一合同的实例,做法见 [Compose Skill](../skills/core/dingtalk-agent-compose/SKILL.md)),合同 42 从两份 example 分别创建临时 Workspace,逐项检查:
73
+
74
+ 1. 初始化前 Direct bootstrap 可工作,且没有可信 target;
75
+ 2. 初始化后 `AGENTS.md`、Role Skill 与显式 Field 被正确采用;
76
+ 3. 两个 Definition、DWS profile、Session ID 互不相同,但共享同一份 Basic Behavior hash;
77
+ 4. 一方的 Task Checkpoint 与 Memory Candidate 在另一方的 state root 中不可见;
78
+ 5. 两者都通过同一 fake-DWS Lab 的 Action / Receipt / 平台回读合同。
79
+
80
+ 它证明模板化装配与状态隔离可自动验证;不代表真实账号、专用群、AI 表格和钉钉文档已接通。每个 Agent 的真实 L4 仍需各自的专用测试对象、allowlist 和明确 `--live --yes` 授权。
81
+
82
+ 合同之外另有一次真实本地 dogfood:把 `examples/agents/release-manager` 复制到仓库外临时目录,执行 enhance plan/apply 后,静态 audit 只缺 `host.load-probe`;OpenCode 1.17.14 + `deepseek/deepseek-chat` 的 with-skill 随机加载与 without-skill 防猜对照均为 1/1,绑定证据后的 audit 为 `ready`、缺口为 0。模型共调用 4 次、工具调用为 0、钉钉副作用为 0;脱敏摘要见 [`agent-enhance-opencode-dogfood-summary.json`](../evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json)。单 case smoke 不用于宣称行为增益。
83
+
84
+ ## 本地合同与 Claude 对照评测
85
+
86
+ ```bash
87
+ # 确定性合同,不调用模型、不写钉钉
88
+ npm run eval:contract
89
+
90
+ # 常规改动只跑与链路相关的子集;--list 查场景目录,--only 接 id 或名称
91
+ node evals/run-contract-evals.mjs --list
92
+ node evals/run-contract-evals.mjs --only=20,CliErrorHints
93
+
94
+ # 同一个 Prepared Run 做 with_skill / without_skill 对照
95
+ npm run eval:behavior -- \
96
+ --runs 3 \
97
+ --out evals/results/behavior-iteration-002
98
+
99
+ # 只回归指定场景
100
+ npm run eval:behavior -- --eval 101,102 --runs 3
101
+
102
+ # 迭代已有 Skill:当前工作树对上一版快照
103
+ npm run eval:behavior -- \
104
+ --baseline-skill /path/to/previous/dingtalk-basic-behavior \
105
+ --model '<固定的完整模型 ID>' --runs 3
106
+ ```
107
+
108
+ 合同 runner 的 stdout 是稳定的机器接口(默认 JSON、`--smoke` 四行),进度与失败展示全部走 stderr:每个场景一行结果;失败场景当场列出未通过的期望、截断证据,以及复跑命令、实现函数、判分文件和相关 fixture 的提示;场景抛异常按全部期望未通过计入并继续,让一次运行暴露所有失败。展示层只有 `evals/lib/tui.mjs` 一个模块,没有自己的合同场景,不增加回归负担。
109
+
110
+ Shadow runner 固定使用 `claude --bare --disable-slash-commands --tools Read`,每个 Run 新开会话。它没有写、Bash、DWS、MCP 或网络工具;runner 要求读取 `CONTEXT.md`、本 Run 冻结的 Skill、消息和 policy,并把所有 Run 外 `Read` 判为失败。但 `--tools Read` 不是操作系统文件沙箱,不能阻止 Claude 尝试读取同一用户可见的绝对路径;涉及敏感 fixture 时仍应把 runner 放进真正的容器/沙箱。结果目录保留:
111
+
112
+ ```text
113
+ eval-<id>/<with_skill|without_skill>/run-<n>/
114
+ ├── transcript.md
115
+ ├── grading.json
116
+ ├── timing.json
117
+ └── outputs/
118
+ ├── runner-config.json
119
+ ├── prompt.txt
120
+ ├── claude.stdout.ndjson
121
+ ├── claude.stderr.log
122
+ ├── tool-calls.json
123
+ ├── final-action-request.json
124
+ └── metrics.json
125
+ ```
126
+
127
+ OpenCode 评测不依赖模型主动调用 Skill:compose 先把项目 Basic Skill 加入 `opencode.json#instructions`,runner 再为本 Run 快照加入随机 probe。with-skill 必须精确回显,without-skill 不得猜中;每个 Session 还要由 `opencode export` 证明 directory 等于隔离 Workspace。之后才计算行为分数:
128
+
129
+ ```bash
130
+ dta lab eval --engine opencode \
131
+ --workspace lab/robot-eval/workspace \
132
+ --suite lab/robot-eval/suite.json --lanes stateless \
133
+ --runs 3 --execute --yes --json
134
+ ```
135
+
136
+ case 可用 `--cases id1,id2` 精确回归。默认题目工具全关;只有 suite 显式声明 `execution.tools=workspace-write` 时才开放隔离工作区的 `read/write/edit`。可写沙箱必须建在仓库外的系统临时根目录;runner 会把工具报告的绝对路径规范化后与该根目录做 containment 审计,防止 Host 沿父级 `.git` 把相对路径落到真实工作树。runner 在沙箱清理前执行 response + filesystem + workspace + artifact 断言并复制声明文件;回复声称完成但文件缺失、JSON 不符、Definition 不 ready、路径越界或出现非白名单工具时整例失败。经典事故与多证据 case 见 [`lab/agent-eval/classic-failures.json`](../lab/agent-eval/classic-failures.json)。
137
+
138
+ 这层会调用模型并产生 OpenCode Session/费用,但不开放工具、不连接 DWS。`AGENTS.md` 只保留身份和边界,禁止复制 Basic Skill 的预期答案;目录发现、正文加载、行为正确和 Skill 相对 baseline 的增益是四个不同结论。
139
+
140
+ ### 本地 Definition + 钉钉文档状态
141
+
142
+ `storage` engine 把 Agent 本体固定为本地 `AGENTS.md + Role Skills`,memory/knowledge 固定为两条显式 `dingtalk-doc:` URI。默认只生成计划;`--execute --yes` 才读取 DWS 并调用 OpenCode,`--execute --live --yes` 还会向唯一 `writeProbe` 专用文档追加一次随机 marker:
143
+
144
+ ```bash
145
+ dta lab eval --engine storage \
146
+ --workspace lab/agent-eval/remote-state-workspace \
147
+ --suite .dingtalk-agent/remote-state.local.json \
148
+ --execute --live --yes --json
149
+ ```
150
+
151
+ 硬门禁依次检查固定 profile/expectedUserId、`ALIDOC/adoc` 类型、本地 Definition/Role Skill、Basic Skill 强制 instruction、远端回读 = mount hash = cache bytes = slot 独立 manifest,再让 OpenCode 零工具回答只存在于远端文档且未出现在 Prompt/本地 Definition 的探针。钉钉会重排/转义 Markdown,因此写 marker 按规范化文字流计数;命令返回 success 仍不算通过。错误身份、文档类型、回读漂移或 marker 不是恰好一次都会使整例失败。控制状态仍在本地原子存储,原始远端快照只进入被 Git 忽略的证据目录。
152
+
153
+ 真实 DWS 脱敏结果见 [`evals/baselines/2026-07-16/remote-state-live-summary.json`](../evals/baselines/2026-07-16/remote-state-live-summary.json)。专用合成文档不会自动删除,因为写入授权不等于删除授权。
154
+
155
+ 三层远端语义状态使用 `remote-semantic-state-live-eval@1`。它不调用模型,也不替代 OpenCode Basic load gate;目标是独立证明 L1 文档、L2 固定 AI 表格记录、L3 文档在写后回读和全新本地 state-dir 中可恢复一致。占位配置见 [`remote-semantic-state-live.example.json`](../lab/agent-eval/remote-semantic-state-live.example.json):
156
+
157
+ ```bash
158
+ # 默认只验证本地 Definition、scope、Role/Basic Skill 发现、Provider、allowlist 与预算;零 DWS
159
+ dta lab eval --engine storage \
160
+ --workspace <agent-workspace> \
161
+ --suite .dingtalk-agent/remote-semantic-state-live.local.json --json
162
+
163
+ # 仅当 local suite 已填写专用资源并设置 liveAuthorized=yes
164
+ dta lab eval --engine storage \
165
+ --workspace <agent-workspace> \
166
+ --suite .dingtalk-agent/remote-semantic-state-live.local.json \
167
+ --execute --live --yes --json
168
+ ```
169
+
170
+ Live runner 的写预算精确为四次:L1 marker、L3 marker、固定 L2 record update、L1 drift marker。每次写都独立回读;L2 同时按 recordId 与 key+scope 查询,必须仍唯一命中同一记录。写后进程 A 退出并归档 state-dir,进程 B 在同一逻辑路径的空目录重新 bootstrap/rehydrate;Definition、Provider、L1/L2/L3、聚合 state hash 与 nextAction 必须逐项一致。原始身份、资源 ID、正文和 worker 输出只保存在 Workspace 的 `.dingtalk-agent/remote-semantic-state-live-results/`。
171
+
172
+ 历史三轮脱敏基线见 [`evals/baselines/2026-07-16/opencode-basic-skill-required-summary.json`](../evals/baselines/2026-07-16/opencode-basic-skill-required-summary.json):随机正文加载和 Session 目录门禁均通过,Basic 0.9.2 with-skill 为 17/18、baseline 为 14/18;唯一失败是普通拒绝答复出现“回读路径”。
173
+
174
+ Basic 0.10.0 的脱敏基线见 [`evals/baselines/2026-07-16/opencode-basic-010-completion-summary.json`](../evals/baselines/2026-07-16/opencode-basic-010-completion-summary.json)。OpenCode 1.17.14 / `deepseek/deepseek-chat` 下,current 与从 `bb8b95e` 冻结的 previous 均 3/3 精确加载;主验收记录的安全、Filesystem、Workspace、Artifact 硬门禁均为 100%,且已记录结果中没有“文件缺失但 completed”。但文本行为分数为 current 3/9、previous 4/9,同协议复跑方向相反,18 次聚合为 7/18 对 7/18。独立复核随后发现,旧分类器可能漏掉“先说未完成、后又说工作已完成”的矛盾回复,旧 `effectivenessProven` 也可能被单个正 delta 触发;因此这一轮只证明该批已记录样本按当时合同通过,不证明旧 grader 完备,也不证明 Basic 0.10.0 有稳定模型增益。grader 加固的修复和脱敏 L0 证据见 [`completion-grader-hardening-summary.json`](../evals/baselines/2026-07-17/completion-grader-hardening-summary.json),历史 baseline 与分数保持原样。
175
+
176
+ ## 硬门禁自动化现状
177
+
178
+ 当前程序已经判断动作合法性、payload 结构、Run 外读取尝试、权威目标 ID 复制、工具类型和 shadow 副作用;跨私聊泄漏、纠正中断、Live Receipt 等是下一批待建场景,尚不能笼统声称全部硬门禁已自动化。门禁清单本身见 eval 技能的 `references/evidence-contract.md`。
179
+
180
+ ## 历史基线
181
+
182
+ 脱敏、可随 npm 包发布的证据摘要按日期保存在 `evals/baselines/<date>/`;含完整模型轨迹和平台 ID 的原始证据只留在被 Git 忽略的 `evals/results/`。逐版本的变更与发布记录见 [CHANGELOG](../CHANGELOG.md)。
@@ -0,0 +1,43 @@
1
+ # 示例 Agent
2
+
3
+ 两个结构完整、可直接复制的 Agent kit。它们共享同一个内核——Basic Behavior、Invocation、Session/Run/Wait、双半闸门与 Receipt 全部相同;**只有本体、岗位 Skill 和存储绑定不同**。合同 42 会从这两份实例分别建临时 Workspace,验证它们的 Definition、DWS profile、Session 与状态互不可见。
4
+
5
+ | 示例 | 岗位 | 演示什么 |
6
+ |---|---|---|
7
+ | [`fde-coach/`](fde-coach) | FDE 成长教练 | 需要**本人确认**才能外发的岗位:草稿 → 确认 → 调整 → 发布,确认状态本身是完成条件的一部分 |
8
+ | [`release-manager/`](release-manager) | 软件发布经理 | 需要**门禁与回滚**的岗位:检查 → Go/No-Go → 由责任人决策 → 发布后独立回读 |
9
+
10
+ 两个都可以,随便挑一个开始改。差别只在岗位语义,结构完全一样。
11
+
12
+ ## 每个 kit 里有什么
13
+
14
+ ```text
15
+ <agent>/
16
+ ├── AGENTS.md 本体:定义 / 不能做的底线 / 做事标准范式 / 常犯错误
17
+ ├── skills/<role>/SKILL.md 岗位能力
18
+ ├── fields/default/field.json 协作与权限边界(归谁、用哪个身份出口、能对谁行动)
19
+ ├── MEMORY.md 长期记忆挂载点
20
+ └── knowledge/INDEX.md 知识挂载点
21
+ ```
22
+
23
+ `AGENTS.md` 首行的引用块是 **Basic 启动继承声明**,不要删——它是"每轮先应用公共行为"的锚点。四个章节标题也不要改名,`agent audit` 按它们判断本体语义是否已填完。
24
+
25
+ ## 怎么用
26
+
27
+ ```bash
28
+ cp -R examples/agents/release-manager /path/to/my-agent
29
+ cd /path/to/my-agent
30
+
31
+ # 改三处:AGENTS.md 的岗位语义、skills/<role>/SKILL.md、fields/default/field.json 的身份与 allowlist
32
+ # 然后验证本体(不需要 Workspace,也不产生钉钉副作用)
33
+ dta bootstrap --json
34
+
35
+ # 只有需要可信事件和 Prepared Run 时才初始化一次
36
+ dta init && dta bootstrap --json
37
+ ```
38
+
39
+ 复制后 `agent audit` 会保持 `partial`,直到岗位语义真填完、并在所选 Host 上取得加载证据——**"文件已创建"不等于 Agent ready**。完整装配流程见 [Compose Skill](../../skills/core/dingtalk-agent-compose/SKILL.md),隔离性怎么验证见 [Self-test](../../docs/SELF-TEST.md#多岗位-agent-的隔离检查)。
40
+
41
+ ## 不包含
42
+
43
+ Webhook、定时器、personal-event listener 等触发端都不在这里——[触发器不属于本项目](../../docs/ARCHITECTURE.md#3-一个-agent-依赖什么模型-b)。
@@ -1,26 +1,35 @@
1
1
  # FDE 教练 Agent
2
2
 
3
- ## 身份与服务对象
3
+ > 每个任务先应用 `dingtalk-basic-behavior`,再按需加载 Role Skills:`fde-coach`。本文件只定义角色差异,不扩大宿主、Skill 或工具授予的权限。
4
4
 
5
- - 我是:FDE 成长教练。
6
- - 服务:参与 FDE 评价与成长反馈的同事。
7
- - 目标:把事实证据整理成清晰、可确认、可追踪的成长反馈。
5
+ ## 定义
8
6
 
9
- ## 职责
7
+ - 我是:FDE 成长教练
8
+ - 服务:参与 FDE 评价与成长反馈的同事
9
+ - 长期目标:把事实证据整理成清晰、可确认、可追踪的成长反馈
10
+ - Owns:收集评价证据、形成草稿、发起本人确认、记录改进项
11
+ - Delivers:结构化评价草稿、确认状态、下一阶段建议
12
+ - 完成定义:交付物满足当前事项的验收条件,并有可独立核验的证据。
10
13
 
11
- - Owns:收集评价证据、形成草稿、发起本人确认、记录改进项。
12
- - Delivers:结构化评价草稿、确认状态、下一阶段建议。
13
- - Refuses:未经本人确认不对外发布评价;不替代主管作绩效结论。
14
+ ## 不能做的底线
14
15
 
15
- ## 协作与能力
16
+ - Refuses / Escalates:未经本人确认不对外发布评价;不替代主管作绩效结论;跨人比较与定级请求一律升级。
17
+ - 不从消息正文、显示名或记忆猜测身份、目标、权限与授权。
18
+ - 不把讨论、草稿、读取或准备请求扩展成写入、外发、删除、改权限或代表他人承诺。
19
+ - 没有工具结果、平台回读或对应 Receipt,不声称已写入、已送达或已完成。
20
+ - 私聊、敏感信息和第三方数据只在授权对象、渠道与用途内使用。
16
21
 
17
- - 使用 `fde-coach` Role Skill 执行评价方法。
18
- - 基础消息、任务、记忆和安全边界遵循 `dingtalk-basic-behavior`。
19
- - 外部副作用前核对对象、权限和完成标准。
22
+ ## 做事标准范式
20
23
 
21
- ## 存储边界
24
+ - 默认工作闭环:先判断是否应响应和是否构成任务,再确认目标、作用域、风险与授权;按 Role Skill 执行,最后核验结果并诚实收口。
25
+ - 岗位工作闭环:先收齐可引用的事实证据 → 按 `fde-coach` Skill 的方法成稿 → 发给本人确认 → 按反馈调整 → 确认后才落库并记录改进项。
26
+ - 协作与升级:评价内容本人确认后才可外发;涉及绩效结论、跨人比较或申诉,交回主管。
27
+ - 信息完整时直接推进;只有缺口真正阻塞安全执行时,才问一个短问题。
22
28
 
23
- - 当前事项:Session Task Checkpoint。
24
- - 互动摘要:显式配置的 Operational Memory Provider。
25
- - 长期方法:候选评审后发布到 Knowledge/Git。
26
- - 不在本文保存 Wait、锁、幂等键或 Receipt。
29
+ ## 常犯错误
30
+
31
+ - 把陈述或讨论当成执行指令 → 先识别 `statement / draft / read / prepare / execute / publish`。
32
+ - 为了显得主动而扩大对象、渠道或动作 回到本次明确授权的最小充分作用域。
33
+ - 把"命令运行过"当成"结果已生效" → 按完成定义补平台回读或可核验证据。
34
+ - 用主观印象替代可引用证据 → 每条评价都要能指回具体事实来源。
35
+ - 把草稿当成已确认的结论外发 → 确认状态未回到"已确认"前,不进入任何外发路径。
@@ -1,26 +1,35 @@
1
1
  # 发布经理 Agent
2
2
 
3
- ## 身份与服务对象
3
+ > 每个任务先应用 `dingtalk-basic-behavior`,再按需加载 Role Skills:`release-manager`。本文件只定义角色差异,不扩大宿主、Skill 或工具授予的权限。
4
4
 
5
- - 我是:软件发布经理。
6
- - 服务:研发、测试和业务发布责任人。
7
- - 目标:让每次发布有明确范围、风险、门禁、回滚条件和可验证结果。
5
+ ## 定义
8
6
 
9
- ## 职责
7
+ - 我是:软件发布经理
8
+ - 服务:研发、测试和业务发布责任人
9
+ - 长期目标:让每次发布有明确范围、风险、门禁、回滚条件和可验证结果
10
+ - Owns:发布清单、依赖检查、Go/No-Go 信息汇总和发布后核验
11
+ - Delivers:发布计划、门禁状态、风险与回滚摘要
12
+ - 完成定义:交付物满足当前事项的验收条件,并有可独立核验的证据。
10
13
 
11
- - Owns:发布清单、依赖检查、Go/No-Go 信息汇总和发布后核验。
12
- - Delivers:发布计划、门禁状态、风险与回滚摘要。
13
- - Refuses:不绕过审批,不在缺少版本/环境/责任人时执行真实发布。
14
+ ## 不能做的底线
14
15
 
15
- ## 协作与能力
16
+ - Refuses / Escalates:不绕过审批;缺少版本、环境或责任人时不执行真实发布;回滚决策交给发布责任人。
17
+ - 不从消息正文、显示名或记忆猜测身份、目标、权限与授权。
18
+ - 不把讨论、草稿、读取或准备请求扩展成写入、外发、删除、改权限或代表他人承诺。
19
+ - 没有工具结果、平台回读或对应 Receipt,不声称已写入、已送达或已完成。
20
+ - 私聊、敏感信息和第三方数据只在授权对象、渠道与用途内使用。
16
21
 
17
- - 使用 `release-manager` Role Skill 执行发布方法。
18
- - 基础消息、任务、记忆和安全边界遵循 `dingtalk-basic-behavior`。
19
- - 外部发布动作必须使用岗位显式授权的工具,不把讨论当执行授权。
22
+ ## 做事标准范式
20
23
 
21
- ## 存储边界
24
+ - 默认工作闭环:先判断是否应响应和是否构成任务,再确认目标、作用域、风险与授权;按 Role Skill 执行,最后核验结果并诚实收口。
25
+ - 岗位工作闭环:确认版本与环境 → 跑依赖与门禁检查 → 汇总 Go/No-Go 与回滚条件 → 由责任人决策 → 发布后独立核验并回报结果。
26
+ - 协作与升级:门禁未过或信息缺口影响判断时,先摆事实再交给发布责任人决策,不自行放行。
27
+ - 信息完整时直接推进;只有缺口真正阻塞安全执行时,才问一个短问题。
22
28
 
23
- - 当前发布:Session Task Checkpoint。
24
- - 发布状态:显式业务事实源。
25
- - Runbook:候选评审后发布到 Knowledge/Git。
26
- - 不在本文保存 Wait、锁、幂等键或 Receipt。
29
+ ## 常犯错误
30
+
31
+ - 把陈述或讨论当成执行指令 → 先识别 `statement / draft / read / prepare / execute / publish`。
32
+ - 为了显得主动而扩大对象、渠道或动作 回到本次明确授权的最小充分作用域。
33
+ - 把"命令运行过"当成"结果已生效" → 按完成定义补平台回读或可核验证据。
34
+ - 把"流水线绿了"当成"发布已生效" → 从目标环境独立回读版本号与健康状态。
35
+ - 在缺少回滚条件时先发布再补 → 回滚路径未确认前不进入执行。
@@ -54,7 +54,7 @@
54
54
  }
55
55
  ],
56
56
  "sourceRefs": [
57
- "docs/plans/2026-07-16/provider-bound-development-workspace.md#12-分阶段实现与验收",
57
+ "docs/ARCHITECTURE.md#8-从定义到上线",
58
58
  "skills/core/dingtalk-agent-eval/references/evidence-contract.md"
59
59
  ],
60
60
  "manualChecks": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdxer/dingtalk-agent",
3
- "version": "0.1.4",
3
+ "version": "0.1.5-beta.1",
4
4
  "description": "钉钉数字员工的 Skill-first 行为范式:全局 Skill 决策,CLI 固定事务边界,Workspace 按需。",
5
5
  "keywords": [
6
6
  "dingtalk",
@@ -39,8 +39,10 @@
39
39
  "evals/baselines/2026-07-17/personal-event-live-readiness-summary.json",
40
40
  "evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json",
41
41
  "lab",
42
+ "docs/ARCHITECTURE.md",
42
43
  "docs/INSTALLATION.md",
43
- "docs/SECOND-AGENT-ACCEPTANCE.md",
44
+ "docs/PRIOR-ART.md",
45
+ "docs/SELF-TEST.md",
44
46
  "README.md",
45
47
  "README.en.md",
46
48
  "CHANGELOG.md"
@@ -57,8 +59,10 @@
57
59
  "eval:behavior": "npm run build && node evals/run-shadow-evals.mjs",
58
60
  "eval:opencode": "npm run build && node dist/bin/dingtalk-agent.js lab eval --engine opencode --workspace lab/robot-eval/workspace --suite lab/robot-eval/suite.json --lanes stateless --execute --yes --json",
59
61
  "prepack": "npm run build",
60
- "release:check": "node scripts/check-skill-versions.mjs && node scripts/release-readiness.mjs --json",
61
- "check:skill-versions": "node scripts/check-skill-versions.mjs"
62
+ "release:check": "node scripts/check-skill-versions.mjs && node scripts/check-docs.mjs && node evals/run-contract-evals.mjs --full && node scripts/release-readiness.mjs --json",
63
+ "check:skill-versions": "node scripts/check-skill-versions.mjs",
64
+ "check:docs": "node scripts/check-docs.mjs",
65
+ "eval:contract:full": "npm run build && node evals/run-contract-evals.mjs --full"
62
66
  },
63
67
  "devDependencies": {
64
68
  "@types/node": "^18.19.0",
@@ -3,7 +3,7 @@ name: dingtalk-agent-compose
3
3
  description: 当用户要创建、新建、装配一个 Agent 或钉钉数字员工——包括把 GitHub 仓库、本地文件夹或钉钉文档定义成 Agent,或要审计、补齐、优化 Agent 的 AGENTS.md、本体职责、岗位 Skills、记忆/知识/产物存储与 DWS 权限绑定时使用。即使尚未 init Workspace,也按 dingtalk-agent 的 AgentDefinition 范式给出可运行的最小装配方案;不负责事件触发器。
4
4
  compatibility: Requires dingtalk-agent on PATH; remote DingTalk documents require authenticated dws.
5
5
  metadata:
6
- version: "0.12.0"
6
+ version: "0.12.2"
7
7
  ---
8
8
 
9
9
  # 装配一个可工作的钉钉数字员工 Agent
@@ -13,7 +13,7 @@ metadata:
13
13
  ## 工作顺序
14
14
 
15
15
  1. 识别来源和运行方式:GitHub 先由宿主 clone/checkout,本 Skill 不接管凭证;本地目录直接读取;钉钉文档只承担 memory/knowledge 等远端语义状态。本体 `AGENTS.md` 与 Role Skills 保持在本地、可版本化。
16
- 2. **让用户选择 Managed Agent Platform,不要替用户默认**:先 `dta agent-platform list` 展示注册表(当前 `multica-dingtalk` 已支持、`deap` 敬请期待),并额外给出「暂不归属,仅本地调试」选项。用户选定托管平台后运行 `dta agent-platform use <platform>`——它写入归属声明并按需安装平台技能包(`multica-dingtalk` 对应 `dingtalk-agent-deploy-multica`、`dingtalk-agent-boot-multica` 与 `multica-external`)。命令会同时输出 readiness 检查:multica CLI 未安装时按提示安装(`curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash`),未登录时 readiness 会给出带解析 endpoint 的完整登录命令(endpoint 来源见 `dta agent-platform show` 的 Endpoint 行:env `MULTICA_SERVER_URL` > 项目 config > profile > 建议值;建议值为预发测试环境,标「未确认」),检测到代理环境变量时提醒连接失败可用 `env -u` 剥离。readiness 未过先引导用户补齐,再继续装配;选「暂不归属」则跳过,后续仍可随时归属。切换到某平台后,`agent-platform use/show` 会给出该平台的 `平台说明: <PLATFORM.md 路径>`——先读它,了解该平台各技能(deploy/boot/ops 各角色)的用途、完整交付链与绑定/验收/解绑方式,再开始平台侧操作。
16
+ 2. **让用户选择 Managed Agent Platform,不要替用户默认**:先 `dta agent-platform list` 展示注册表(当前 `multica-dingtalk` 已支持、`deap` 敬请期待),并额外给出「暂不归属,仅本地调试」选项。用户选定托管平台后运行 `dta agent-platform use <platform>`——它写入归属声明并按需安装平台技能包(`multica-dingtalk` 对应 `dingtalk-agent-deploy-multica`、`dingtalk-agent-boot-multica` 与 `multica-external`)。命令会同时输出 readiness 检查:multica CLI 未安装时按提示安装(`curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash`),未登录时 readiness 会给出带解析 endpoint 的完整登录命令(endpoint 来源见 `dta agent-platform show` 的 Endpoint 行:env `MULTICA_SERVER_URL` > 项目 config > profile > 建议值;建议值为线上正式域名,仍标「未确认」,须先与用户确认再用),检测到代理环境变量时提醒连接失败可用 `env -u` 剥离。readiness 未过先引导用户补齐,再继续装配;选「暂不归属」则跳过,后续仍可随时归属。切换到某平台后,`agent-platform use/show` 会给出该平台的 `平台说明: <PLATFORM.md 路径>`——先读它,了解该平台各技能(deploy/boot/ops 各角色)的用途、完整交付链与绑定/验收/解绑方式,再开始平台侧操作。
17
17
  3. **让用户选择 Agent Host,不要替用户默认**:先展示候选——`references/hosts/` 下已有合同的 Host(当前 `opencode` 有完整 adapter,`claude-code` 合同已写但 adapter 未实现),本机实际可用的 Host 由 `dta doctor` 报告——并额外给出「暂不指定 Host,仅落成 harness 无关内核」选项。绝不默默使用 OpenCode 或当前正在运行本 Skill 的 Host 作为默认:Host 决定本体走哪条原生 project rule 通道、Skill 物化到哪个 exposure 目录,选错的症状是文件全对而正文从未加载。用户选定后按 `references/hosts/<host>.md` 生成 exposure;选「暂不指定」则只落成内核,并明确告知结论上限是 `partial`——没有 Host 就没有加载面,没有加载面就没有加载证据。
18
18
  4. 对已有仓库优先运行 `dta agent enhance --project-name <name> --role-skill <role> --dry-run --json`。它只生成 `agent-enhancement-plan@1`,不会写文件、访问 DWS 或创建 Trigger。审阅 operations、blockers 和 semanticReview 后,才复制计划给出的命令,用同一组参数、当前 `planId` 与 `--yes` 落盘。
19
19
  5. apply 只允许本地文件副作用:先把被更新的旧文件备份到 `.dingtalk-agent/backups/agent-enhance/<operationId>/`,再写入并按 hash 回读;自定义 private state 目录必须同步进入 `.gitignore`。输入漂移、planId 过期、非法 Role 路径、所选 Host 配置中的未知 instruction、路径越界或 symlink 都必须 fail closed。不要跳过 plan,也不要把 `--yes` 写进无人审阅的默认脚本。
@@ -55,7 +55,7 @@ metadata:
55
55
  - **本地调试(不需要托管平台)**:直接在所选 Host(当前唯一有完整 adapter 的是 OpenCode)里基于 `AGENTS.md` 工作区调试;需要真实钉钉事件时用开发 Adapter `dta listen mention|dm|group` 做本地 streaming 联调。适合开发期验证行为,不适合常驻服务。
56
56
  - **发布到 Multica 托管平台(推荐正式使用)**:归属 `multica-dingtalk` 后,用平台技能包 `multica-external`(`python3 scripts/multica_ext.py <命令>`)完成完整交付链——`workspace-create/workspace-init` 供给工作区 → `runtime-templates`/`agent-create` 供给运行时与 Agent → `skill-push` + `multica agent skills add` 同步并挂载 Skill → 绑定钉钉机器人(见下方优先级)→ `chat-send --wait` 免钉钉直聊测试通道验收 → `task-trace --follow` 观测执行轨迹。绑定完成后用户在钉钉向机器人发消息即可到达该 Agent。
57
57
 
58
- 装配或部署完成后,用户下一句通常是“怎么测一下”。这时交接给 `dingtalk-agent-eval`,不要在装配流程里即兴造验收方式:它的 `references/interactive-debug-channels.md` 定义了三条通道——平台 CLI 直投任务、本人 DWS 身份对机器人发消息并用平台轨迹定位、对数字员工身份发消息(开发中,前提是该身份事件已被消费)——以及各自证明什么、不证明什么和“没有回复”的四类归因。该 Skill 不在默认套装内,未安装时先 `dta skill install --name dingtalk-agent-eval`。装配侧只负责把机器人绑好并交出 Agent ID,不负责给行为打分。
58
+ 装配或部署完成后,用户下一句通常是“怎么测一下”。这时交接给 `dingtalk-agent-eval`,不要在装配流程里即兴造验收方式:它的 `references/interactive-debug-channels.md` 定义了三条通道——平台 CLI 直投任务、本人 DWS 身份对机器人发消息并用平台轨迹定位、对数字员工身份发消息(开发中,前提是该身份事件已被消费)——以及各自证明什么、不证明什么和“没有回复”的四类归因。该 Skill 属于默认套装,`dta setup` 与 `dta skill install` 已安装;`dta skill status --json` 可回读实际状态。装配侧只负责把机器人绑好并交出 Agent ID,不负责给行为打分。
59
59
 
60
60
  ### Multica 发布链硬性细则
61
61
 
@@ -116,7 +116,7 @@ dta agent audit --bindings agent.bindings.json \
116
116
  ```text
117
117
  my-agent/
118
118
  ├── AGENTS.md 定义、岗位底线、做事范式、常犯错误
119
- ├── agent.bindings.json Definition 与语义存储路由
119
+ ├── agent.bindings.json Definition 与语义存储路由(可选;等价配置也可来自宿主 context、环境变量或 Workspace manifest)
120
120
  ├── MEMORY.md 已评审的长期语义记忆
121
121
  ├── knowledge/INDEX.md 知识入口
122
122
  ├── skills/<role>/SKILL.md 一个或多个岗位 Skill
@@ -3,7 +3,7 @@ name: dingtalk-agent-eval
3
3
  description: 当用户要设计、运行、审计或扩展 dingtalk-agent/数字员工评测时使用,尤其是 OpenCode/DeepSeek、专用机器人、Agent Workspace、AGENTS.md + Skills、本地或钉钉文档状态、文件与产物断言、历史事故回归和 Live 晋级门禁。也用于 Agent 创建或部署完成后的验收、联调与调试:怎么测、怎么给它派任务试一下、给机器人发消息不回/没反应/@ 了没动静、任务卡住或失败、怀疑 Skill 没真的加载、要看这次执行的轨迹和会话。负责把场景归类、证明 Basic Skill 真实加载、采集多证据面并给出可复验结论;不负责事件触发器或生产业务写入。
4
4
  compatibility: Requires dingtalk-agent on PATH; model evals require the selected Agent Host; DingTalk readback requires authenticated dws.
5
5
  metadata:
6
- version: "0.7.1"
6
+ version: "0.7.2"
7
7
  ---
8
8
 
9
9
  # 评测一个真正能工作的 Agent
@@ -69,10 +69,35 @@ A → B → C 单向升级,不跳级也不互替;“没有回复”必须先
69
69
 
70
70
  被测对象还没部署、要在本地用专用测试机器人做真实钉钉往返时,走 [local-connector-smoke.md](references/local-connector-smoke.md):那条链路的出口属于 connector,与上面三条不是同一套拓扑,证据声明不得互相替代。交互式联调的产出是 case,不是“感觉好了”。
71
71
 
72
+ ## 先跑最小,再放大
73
+
74
+ **默认不给 `--cases` 就会跑完整个 suite 的全部 lane,而每个 case 都要调一次模型。**这既是时间也是钱:9 个 case × 3 runs = 27 次模型调用。日常回归不该这么开。
75
+
76
+ 按这个顺序放大,每一步确认通过再进下一步:
77
+
78
+ ```bash
79
+ # 1. 一个 case、一轮、单 lane —— 先证明链路是通的
80
+ dta lab eval --engine opencode --workspace <ws> --suite <suite> \
81
+ --cases <一个 case id> --lanes stateless --runs 1 --execute --yes --json
82
+
83
+ # 2. 单 lane 全 case,一轮 —— 看这条 lane 有没有系统性问题
84
+ dta lab eval ... --lanes stateless --runs 1 --execute --yes --json
85
+
86
+ # 3. 目标 lane、多轮 —— 只有要判断"是否稳定增益"时才需要多轮
87
+ dta lab eval ... --lanes stateless --runs 3 --execute --yes --json
88
+
89
+ # 4. 全 lane 全 case —— 发布前或深度回归
90
+ dta lab eval ... --execute --yes --json
91
+ ```
92
+
93
+ 改了某个 case 或某条行为,就用 `--cases` 只回归它;`--runs 1` 足以发现"坏了",`--runs 3` 才用来判断"变好了没有"——单轮差异不能宣称增益。跑之前先想清楚这次要回答哪个问题,不要习惯性跑全量。
94
+
95
+ 仓库自己的 L0 合同同样分层:`npm run eval:contract` 默认只跑 core(~18 秒),`--full` 才是全量;判据见仓库 `AGENTS.md`。
96
+
72
97
  ## 运行路径
73
98
 
74
99
  ```bash
75
- # L0:确定性合同
100
+ # L0:确定性合同(默认 core,~18 秒;--full 为全量)
76
101
  npm run eval:contract
77
102
 
78
103
  # L1:OpenCode + 固定模型;默认只出计划,追加 --execute --yes 才真正执行
@@ -17,7 +17,7 @@ Multica 是钉钉 FDE fork 的托管 Agent 平台:把一个 dingtalk-agent 数
17
17
  ## 使用前的就绪要求
18
18
 
19
19
  - multica CLI 已安装:`curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash`
20
- - 已登录并选定目标:先 `dta agent-platform show` 查看解析出的 **Endpoint 及来源**(env `MULTICA_SERVER_URL` > 项目 config > 已登录 profile > 建议值)——现阶段建议值指向预发测试环境,标注为「未确认」。据此 `multica login --server-url <该 endpoint> --token mul_...`。发布前必须与用户确认 endpoint / workspace / Agent 名字,绝不据未确认的建议值直连生产。
20
+ - 已登录并选定目标:先 `dta agent-platform show` 查看解析出的 **Endpoint 及来源**(env `MULTICA_SERVER_URL` > 项目 config > 已登录 profile > 建议值)——建议值指向线上正式域名,仍标注为「未确认」:正因为它是生产环境,必须先与用户确认再据此 `multica login --server-url <该 endpoint> --token mul_...`。发布前必须与用户确认 endpoint / workspace / Agent 名字,绝不据未确认的建议值直连生产。
21
21
  - 代理环境变量可能阻断直连:失败时用 `env -u HTTPS_PROXY -u https_proxy -u ALL_PROXY -u all_proxy` 运行。
22
22
 
23
23
  ## 绑定钉钉机器人的优先级