@xdxer/dingtalk-agent 0.1.4-beta.8 → 0.1.4

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.
Files changed (254) hide show
  1. package/CHANGELOG.md +233 -0
  2. package/README.en.md +167 -0
  3. package/README.md +101 -248
  4. package/dist/bin/dingtalk-agent.js +1255 -25
  5. package/dist/bin/dingtalk-agent.js.map +1 -1
  6. package/dist/src/actions.js +98 -14
  7. package/dist/src/actions.js.map +1 -1
  8. package/dist/src/agent-audit.js +1385 -0
  9. package/dist/src/agent-audit.js.map +1 -0
  10. package/dist/src/agent-bindings.js +132 -0
  11. package/dist/src/agent-bindings.js.map +1 -0
  12. package/dist/src/agent-definition.js +182 -0
  13. package/dist/src/agent-definition.js.map +1 -0
  14. package/dist/src/agent-enhance.js +711 -0
  15. package/dist/src/agent-enhance.js.map +1 -0
  16. package/dist/src/agent-platform.js +299 -0
  17. package/dist/src/agent-platform.js.map +1 -0
  18. package/dist/src/bootstrap.js +125 -17
  19. package/dist/src/bootstrap.js.map +1 -1
  20. package/dist/src/config.js +1 -7
  21. package/dist/src/config.js.map +1 -1
  22. package/dist/src/development-workspace.js +755 -0
  23. package/dist/src/development-workspace.js.map +1 -0
  24. package/dist/src/doctor.js +74 -15
  25. package/dist/src/doctor.js.map +1 -1
  26. package/dist/src/dws.js +145 -0
  27. package/dist/src/dws.js.map +1 -1
  28. package/dist/src/eval-evidence.js +193 -0
  29. package/dist/src/eval-evidence.js.map +1 -0
  30. package/dist/src/host-detect.js +146 -0
  31. package/dist/src/host-detect.js.map +1 -0
  32. package/dist/src/instruction-path.js +270 -0
  33. package/dist/src/instruction-path.js.map +1 -0
  34. package/dist/src/invocation.js +36 -0
  35. package/dist/src/invocation.js.map +1 -0
  36. package/dist/src/lab.js +679 -0
  37. package/dist/src/lab.js.map +1 -0
  38. package/dist/src/lease.js +100 -0
  39. package/dist/src/lease.js.map +1 -0
  40. package/dist/src/map.js +157 -0
  41. package/dist/src/map.js.map +1 -0
  42. package/dist/src/memory/candidates.js +451 -0
  43. package/dist/src/memory/candidates.js.map +1 -0
  44. package/dist/src/memory/completion-evidence.js +536 -0
  45. package/dist/src/memory/completion-evidence.js.map +1 -0
  46. package/dist/src/memory/operational.js +263 -0
  47. package/dist/src/memory/operational.js.map +1 -0
  48. package/dist/src/memory/remote-state.js +478 -0
  49. package/dist/src/memory/remote-state.js.map +1 -0
  50. package/dist/src/memory/task-checkpoints.js +204 -0
  51. package/dist/src/memory/task-checkpoints.js.map +1 -0
  52. package/dist/src/multica-deploy.js +1538 -0
  53. package/dist/src/multica-deploy.js.map +1 -0
  54. package/dist/src/multica-provider.js +685 -0
  55. package/dist/src/multica-provider.js.map +1 -0
  56. package/dist/src/opencode-evals.js +1547 -0
  57. package/dist/src/opencode-evals.js.map +1 -0
  58. package/dist/src/opencode-isolation.js +124 -0
  59. package/dist/src/opencode-isolation.js.map +1 -0
  60. package/dist/src/opencode-provider.js +532 -0
  61. package/dist/src/opencode-provider.js.map +1 -0
  62. package/dist/src/opencode-workspace.js +208 -0
  63. package/dist/src/opencode-workspace.js.map +1 -0
  64. package/dist/src/perception.js +225 -0
  65. package/dist/src/perception.js.map +1 -0
  66. package/dist/src/personal-event-evals.js +595 -0
  67. package/dist/src/personal-event-evals.js.map +1 -0
  68. package/dist/src/promotion.js +786 -0
  69. package/dist/src/promotion.js.map +1 -0
  70. package/dist/src/remote-semantic-state-live-evals.js +888 -0
  71. package/dist/src/remote-semantic-state-live-evals.js.map +1 -0
  72. package/dist/src/remote-semantic-state-worker.js +38 -0
  73. package/dist/src/remote-semantic-state-worker.js.map +1 -0
  74. package/dist/src/remote-state-evals.js +502 -0
  75. package/dist/src/remote-state-evals.js.map +1 -0
  76. package/dist/src/response-gate.js +51 -0
  77. package/dist/src/response-gate.js.map +1 -0
  78. package/dist/src/robot-evals.js +771 -0
  79. package/dist/src/robot-evals.js.map +1 -0
  80. package/dist/src/sessions.js +66 -105
  81. package/dist/src/sessions.js.map +1 -1
  82. package/dist/src/setup.js +6 -5
  83. package/dist/src/setup.js.map +1 -1
  84. package/dist/src/skill-manager.js +162 -24
  85. package/dist/src/skill-manager.js.map +1 -1
  86. package/dist/src/skills.js +2 -1
  87. package/dist/src/skills.js.map +1 -1
  88. package/dist/src/storage-evals.js +26 -0
  89. package/dist/src/storage-evals.js.map +1 -0
  90. package/dist/src/types.js.map +1 -1
  91. package/dist/src/upgrade.js +23 -27
  92. package/dist/src/upgrade.js.map +1 -1
  93. package/dist/src/version.js +73 -0
  94. package/dist/src/version.js.map +1 -0
  95. package/dist/src/waits.js +5 -1
  96. package/dist/src/waits.js.map +1 -1
  97. package/dist/src/workspace.js +28 -3
  98. package/dist/src/workspace.js.map +1 -1
  99. package/docs/INSTALLATION.md +50 -3
  100. package/docs/SECOND-AGENT-ACCEPTANCE.md +62 -0
  101. package/docs/architecture/agent-memory-topology.png +0 -0
  102. package/docs/architecture/agent-memory-topology.svg +132 -0
  103. package/docs/architecture/general-agent-kernel-topology.png +0 -0
  104. package/docs/architecture/general-agent-kernel-topology.svg +149 -0
  105. package/docs/architecture/provider-bound-development-workspace.png +0 -0
  106. package/docs/architecture/provider-bound-development-workspace.svg +141 -0
  107. package/docs/architecture/task-completion-gate.png +0 -0
  108. package/docs/architecture/task-completion-gate.svg +191 -0
  109. package/docs/assets/agent-delivery-lifecycle.svg +103 -0
  110. package/docs/schemas/agent-audit-load-evidence.schema.json +14 -0
  111. package/docs/schemas/agent-audit.schema.json +92 -0
  112. package/docs/schemas/agent-bindings.schema.json +54 -0
  113. package/docs/schemas/agent-definition.schema.json +78 -0
  114. package/docs/schemas/agent-enhancement-plan.schema.json +88 -0
  115. package/docs/schemas/agent-enhancement-receipt.schema.json +37 -0
  116. package/docs/schemas/agent-platform.schema.json +13 -0
  117. package/docs/schemas/enriched-invocation.schema.json +46 -0
  118. package/docs/schemas/eval-candidate-plan.schema.json +28 -0
  119. package/docs/schemas/eval-candidate-result.schema.json +20 -0
  120. package/docs/schemas/eval-candidate.schema.json +30 -0
  121. package/docs/schemas/invocation.schema.json +19 -0
  122. package/docs/schemas/memory-candidate-proposal.schema.json +18 -0
  123. package/docs/schemas/memory-candidate.schema.json +76 -0
  124. package/docs/schemas/memory-publish-target.schema.json +25 -0
  125. package/docs/schemas/multica-deployment-list.schema.json +29 -0
  126. package/docs/schemas/multica-deployment-operation.schema.json +51 -0
  127. package/docs/schemas/multica-deployment-plan.schema.json +70 -0
  128. package/docs/schemas/multica-deployment-receipt.schema.json +87 -0
  129. package/docs/schemas/multica-deployment-status.schema.json +23 -0
  130. package/docs/schemas/multica-workspace-inspection.schema.json +77 -0
  131. package/docs/schemas/multica-workspace-plan.schema.json +68 -0
  132. package/docs/schemas/multica-workspace-resource-list.schema.json +27 -0
  133. package/docs/schemas/multica-workspace-status.schema.json +34 -0
  134. package/docs/schemas/observation.schema.json +21 -0
  135. package/docs/schemas/operational-memory-provider.schema.json +36 -0
  136. package/docs/schemas/operational-memory-record.schema.json +24 -0
  137. package/docs/schemas/perception-input.schema.json +56 -0
  138. package/docs/schemas/project.schema.json +115 -0
  139. package/docs/schemas/promotion-list.schema.json +36 -0
  140. package/docs/schemas/promotion-plan.schema.json +60 -0
  141. package/docs/schemas/promotion-policy.schema.json +29 -0
  142. package/docs/schemas/promotion-receipt.schema.json +43 -0
  143. package/docs/schemas/promotion-status.schema.json +23 -0
  144. package/docs/schemas/release-readiness.schema.json +66 -0
  145. package/docs/schemas/remote-semantic-state-live-eval.schema.json +60 -0
  146. package/docs/schemas/remote-semantic-state-manifest.schema.json +79 -0
  147. package/docs/schemas/remote-semantic-state-provider.schema.json +98 -0
  148. package/docs/schemas/response-gate.schema.json +20 -0
  149. package/docs/schemas/task-checkpoint.schema.json +71 -0
  150. package/docs/schemas/task-completion-evidence.schema.json +154 -0
  151. package/docs/schemas/workspace-doctor.schema.json +56 -0
  152. package/docs/schemas/workspace-state.schema.json +39 -0
  153. package/evals/README.md +17 -0
  154. package/evals/baselines/2026-07-16/opencode-basic-010-completion-summary.json +123 -0
  155. package/evals/baselines/2026-07-16/opencode-basic-skill-required-summary.json +69 -0
  156. package/evals/baselines/2026-07-16/opencode-multi-surface-summary.json +63 -0
  157. package/evals/baselines/2026-07-16/remote-state-live-summary.json +70 -0
  158. package/evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json +98 -0
  159. package/evals/baselines/2026-07-17/personal-event-live-readiness-summary.json +68 -0
  160. package/examples/agents/fde-coach/AGENTS.md +26 -0
  161. package/examples/agents/fde-coach/MEMORY.md +3 -0
  162. package/examples/agents/fde-coach/fields/default/field.json +24 -0
  163. package/examples/agents/fde-coach/knowledge/INDEX.md +4 -0
  164. package/examples/agents/fde-coach/skills/fde-coach/SKILL.md +13 -0
  165. package/examples/agents/release-manager/AGENTS.md +26 -0
  166. package/examples/agents/release-manager/MEMORY.md +3 -0
  167. package/examples/agents/release-manager/fields/default/field.json +24 -0
  168. package/examples/agents/release-manager/knowledge/INDEX.md +4 -0
  169. package/examples/agents/release-manager/skills/release-manager/SKILL.md +13 -0
  170. package/lab/README.md +109 -0
  171. package/lab/agent-eval/catalog.json +91 -0
  172. package/lab/agent-eval/classic-failures.json +177 -0
  173. package/lab/agent-eval/completion-gate-regression.json +99 -0
  174. package/lab/agent-eval/personal-event-live.example.json +94 -0
  175. package/lab/agent-eval/remote-semantic-state-live.example.json +70 -0
  176. package/lab/agent-eval/remote-semantic-state-provider.fixture.json +47 -0
  177. package/lab/agent-eval/remote-state-workspace/AGENTS.md +8 -0
  178. package/lab/agent-eval/remote-state-workspace/opencode.json +7 -0
  179. package/lab/agent-eval/remote-state-workspace/skills/remote-state-operator/SKILL.md +13 -0
  180. package/lab/agent-eval/remote-state.example.json +31 -0
  181. package/lab/agent-eval/workspace/AGENTS.md +7 -0
  182. package/lab/agent-eval/workspace/MEMORY.md +4 -0
  183. package/lab/agent-eval/workspace/artifacts/pending-review.md +3 -0
  184. package/lab/agent-eval/workspace/knowledge/INDEX.md +4 -0
  185. package/lab/agent-eval/workspace/opencode.json +20 -0
  186. package/lab/manifest.example.json +27 -0
  187. package/lab/manifest.personal-event.example.json +27 -0
  188. package/lab/project-workspace/README.md +11 -0
  189. package/lab/project-workspace/fake-multica-provider.mjs +277 -0
  190. package/lab/project-workspace/multica-deploy.fixture.json +29 -0
  191. package/lab/project-workspace/multica-readonly.fixture.json +69 -0
  192. package/lab/project-workspace/observation.fixture.json +14 -0
  193. package/lab/project-workspace/opencode-provider-suite.json +65 -0
  194. package/lab/project-workspace/project.fixture.json +44 -0
  195. package/lab/project-workspace/promotion-policy.fixture.json +15 -0
  196. package/lab/robot-eval/pool.example.json +30 -0
  197. package/lab/robot-eval/suite.json +123 -0
  198. package/lab/robot-eval/workspace/AGENTS.md +21 -0
  199. package/lab/robot-eval/workspace/MEMORY.md +3 -0
  200. package/lab/robot-eval/workspace/knowledge/INDEX.md +5 -0
  201. package/lab/robot-eval/workspace/opencode.json +22 -0
  202. package/lab/schemas/agent-eval-catalog.schema.json +47 -0
  203. package/lab/schemas/lab-manifest.schema.json +70 -0
  204. package/lab/schemas/personal-event-eval.schema.json +91 -0
  205. package/lab/schemas/remote-state-eval.schema.json +66 -0
  206. package/lab/schemas/robot-eval-suite.schema.json +184 -0
  207. package/lab/schemas/robot-pool.schema.json +56 -0
  208. package/package.json +28 -9
  209. package/skills/README.md +23 -0
  210. package/skills/core/dingtalk-agent-compose/SKILL.md +151 -0
  211. package/skills/core/dingtalk-agent-compose/assets/AGENTS.template.md +35 -0
  212. package/skills/core/dingtalk-agent-compose/assets/agent.bindings.dingtalk-doc.template.json +13 -0
  213. package/skills/core/dingtalk-agent-compose/assets/agent.bindings.local.template.json +13 -0
  214. package/skills/core/dingtalk-agent-compose/assets/hosts/opencode/opencode.template.json +12 -0
  215. package/skills/core/dingtalk-agent-compose/assets/role-skill.template.md +32 -0
  216. package/skills/core/dingtalk-agent-compose/evals/evals.json +129 -0
  217. package/skills/core/dingtalk-agent-compose/references/agent-definition-contract.md +55 -0
  218. package/skills/core/dingtalk-agent-compose/references/host-loading-contract.md +58 -0
  219. package/skills/core/dingtalk-agent-compose/references/hosts/claude-code.md +48 -0
  220. package/skills/core/dingtalk-agent-compose/references/hosts/opencode.md +77 -0
  221. package/skills/core/dingtalk-agent-compose/references/storage-routing.md +20 -0
  222. package/skills/core/dingtalk-agent-eval/SKILL.md +140 -0
  223. package/skills/core/dingtalk-agent-eval/assets/eval-catalog.template.json +18 -0
  224. package/skills/core/dingtalk-agent-eval/evals/evals.json +83 -0
  225. package/skills/core/dingtalk-agent-eval/references/eval-topology.md +48 -0
  226. package/skills/core/dingtalk-agent-eval/references/evidence-contract.md +52 -0
  227. package/skills/core/dingtalk-agent-eval/references/failure-to-case.md +35 -0
  228. package/skills/core/dingtalk-agent-eval/references/interactive-debug-channels.md +93 -0
  229. package/skills/core/dingtalk-agent-eval/references/local-connector-smoke.md +75 -0
  230. package/skills/core/dingtalk-agent-eval/references/scenario-taxonomy.md +25 -0
  231. package/skills/core/dingtalk-agent-eval/references/storage-modes.md +75 -0
  232. package/skills/core/dingtalk-basic-behavior/SKILL.md +87 -0
  233. package/skills/core/dingtalk-basic-behavior/assets/memory-candidate-proposal.json +10 -0
  234. package/skills/{dingtalk-basic-behavior/assets/task-checkpoint.md → core/dingtalk-basic-behavior/assets/task-checkpoint.json} +2 -21
  235. package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/action-contract.md +2 -0
  236. package/skills/core/dingtalk-basic-behavior/references/memory-and-evolution.md +53 -0
  237. package/skills/core/dingtalk-basic-behavior/references/perception-and-gates.md +28 -0
  238. package/skills/core/dingtalk-basic-behavior/references/risk-authority-and-privacy.md +62 -0
  239. package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/task-lifecycle.md +47 -10
  240. package/skills/core/dingtalk-basic-behavior/references/truth-and-recovery.md +65 -0
  241. package/skills/platforms/deap/PLATFORM.md +3 -0
  242. package/skills/platforms/deap/README.md +3 -0
  243. package/skills/platforms/multica-dingtalk/PLATFORM.md +40 -0
  244. package/skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica/SKILL.md +40 -0
  245. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/SKILL.md +60 -0
  246. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/multica-deployment-contract.md +49 -0
  247. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/promotion-observation-contract.md +49 -0
  248. package/skills/platforms/multica-dingtalk/multica-external/SKILL.md +282 -0
  249. package/skills/platforms/multica-dingtalk/multica-external/scripts/bootstrap.sh +78 -0
  250. package/skills/platforms/multica-dingtalk/multica-external/scripts/multica_ext.py +1180 -0
  251. package/skills/dingtalk-basic-behavior/SKILL.md +0 -86
  252. package/skills/dingtalk-basic-behavior/references/memory-and-evolution.md +0 -27
  253. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/event-to-behavior.md +0 -0
  254. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/runtime-modes.md +0 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "dingtalk-agent/lab-manifest@1",
3
+ "id": "dedicated-personal-event-canary",
4
+ "mode": "personal-event",
5
+ "syntheticOnly": true,
6
+ "egressOwner": "dingtalk-agent",
7
+ "markerPrefix": "[DTA-LAB-",
8
+ "evidenceRoot": ".dingtalk-agent/lab-results",
9
+ "dws": {
10
+ "profile": "replace-with-dedicated-test-profile",
11
+ "expectedUserId": "replace-with-agent-user-id"
12
+ },
13
+ "allowlist": {
14
+ "tenantIds": ["replace-with-test-tenant-id"],
15
+ "conversationIds": ["replace-with-dedicated-conversation-id"],
16
+ "actorIds": ["replace-with-test-colleague-id"],
17
+ "resourceIds": []
18
+ },
19
+ "budgets": {
20
+ "maxRuns": 10,
21
+ "maxOutwardActions": 1,
22
+ "maxTextCharacters": 300
23
+ },
24
+ "resources": {
25
+ "workspace": "."
26
+ }
27
+ }
@@ -0,0 +1,11 @@
1
+ # Project / Development Workspace fixture
2
+
3
+ `project.fixture.json` 同时声明本地 OpenCode 与可选 Multica Workspace,用于 W1–W4 合同验收。`multica-readonly.fixture.json` 只提供合成的 Workspace/Runtime/Agent/Skill 关系;`multica-deploy.fixture.json` 与 `fake-multica-provider.mjs` 提供可变的本地远端状态,用于验证 W4 create/update/smoke/recovery/rollback/retire。它们都不包含真实账号或资源。
4
+
5
+ - 所有 `*From` 字段只保存环境变量来源,不保存解析值。
6
+ - `workspace list/show/doctor` 不执行 Provider、模型或 DWS 命令。
7
+ - `multica-dev` 缺少 CLI 或环境变量时只影响自身;`local-dev` 仍可独立诊断。
8
+ - W3 的 `plan` 零 Provider 调用;`inspect/remote-list` 只允许固定读命令,输出不保留 auth token、用户邮箱、Server URL 明文、Agent instructions/runtime config 或 Skill content。
9
+ - W4 的 deploy dry-run 仍是零 Provider 调用;显式 apply 只修改 fake state,完整检查 planId、Skill tree、Agent、assignment、load smoke、operation/Receipt hash 与零 Trigger/DWS。
10
+ - `agentIdFrom` 可选:已有 Agent 必须给出可信 ID;缺失时只允许列候选,同名候选不会自动绑定。
11
+ - 真实远端 ID、身份与凭据必须放在 gitignored 环境中,不能写回 fixture。
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, appendFileSync } from 'node:fs'
3
+
4
+ const statePath = process.env.DTA_FAKE_MULTICA_STATE
5
+ const callsPath = process.env.DTA_FAKE_MULTICA_CALLS
6
+ const mutationMarker = process.env.DTA_FAKE_MULTICA_MUTATION_MARKER
7
+ const triggerMarker = process.env.DTA_FAKE_MULTICA_TRIGGER_MARKER
8
+ if (!statePath || !callsPath) throw new Error('fake Multica requires state/calls paths')
9
+ const state = JSON.parse(readFileSync(statePath, 'utf8'))
10
+ state.fired ||= []
11
+ state.sequence ||= { agent: 1, skill: 1, file: 1, issue: 1, task: 1 }
12
+ const raw = process.argv.slice(2)
13
+ const json = (value) => process.stdout.write(`${JSON.stringify(value)}\n`)
14
+ const save = () => writeFileSync(statePath, `${JSON.stringify(state, null, 2)}\n`)
15
+ const id = (kind) => `${kind}-contract-${state.sequence[kind]++}`
16
+ const core = []
17
+ let profile = ''
18
+ let workspaceId = ''
19
+ for (let index = 0; index < raw.length; index++) {
20
+ if (raw[index] === '--profile') { profile = raw[++index] || ''; continue }
21
+ if (raw[index] === '--workspace-id') { workspaceId = raw[++index] || ''; continue }
22
+ core.push(raw[index])
23
+ }
24
+ const flag = (name) => {
25
+ const index = core.indexOf(name)
26
+ return index >= 0 ? core[index + 1] || '' : ''
27
+ }
28
+ const commandKey = (() => {
29
+ if (raw[0] === '--version') return 'version'
30
+ if (core[0] === 'agent' && core[1] === 'skills') return `agent skills ${core[2]}`
31
+ if (core[0] === 'skill' && core[1] === 'files') return `skill files ${core[2]}`
32
+ if (core[0] === 'issue' && core[1] === 'run-messages') return 'issue run-messages'
33
+ return core.slice(0, 2).join(' ')
34
+ })()
35
+ appendFileSync(callsPath, `${JSON.stringify({ command: commandKey, args: raw })}\n`)
36
+
37
+ if (['autopilot', 'webhook', 'robot', 'schedule', 'trigger'].includes(core[0])) {
38
+ if (triggerMarker) writeFileSync(triggerMarker, commandKey)
39
+ process.exit(91)
40
+ }
41
+ const mutating = new Set([
42
+ 'skill create', 'skill update', 'skill delete', 'skill files upsert', 'skill files delete',
43
+ 'agent create', 'agent update', 'agent archive', 'agent restore', 'agent skills set',
44
+ 'issue create', 'issue status',
45
+ ])
46
+ if (mutating.has(commandKey) && mutationMarker) appendFileSync(mutationMarker, `${commandKey}\n`)
47
+ const confirmedFailure = process.env.DTA_FAKE_FAIL_ON || ''
48
+ const timeoutFailure = process.env.DTA_FAKE_TIMEOUT_ON || ''
49
+ if (confirmedFailure === commandKey && !state.fired.includes(`fail:${commandKey}`)) {
50
+ state.fired.push(`fail:${commandKey}`)
51
+ save()
52
+ process.exit(92)
53
+ }
54
+ const finish = (value, mutation = false) => {
55
+ if (mutation) save()
56
+ if (timeoutFailure === commandKey && !state.fired.includes(`timeout:${commandKey}`)) {
57
+ state.fired.push(`timeout:${commandKey}`)
58
+ save()
59
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5000)
60
+ }
61
+ if (value !== undefined) json(value)
62
+ process.exit(0)
63
+ }
64
+ const scoped = () => !workspaceId || workspaceId === state.workspace.id
65
+ const requireScope = () => {
66
+ if (!scoped()) process.exit(93)
67
+ }
68
+
69
+ if (raw[0] === '--version') {
70
+ console.log('multica 0.3.43 (contract-w4)')
71
+ process.exit(0)
72
+ }
73
+ if (commandKey === 'config show') {
74
+ const shownWorkspace = process.env.DTA_FAKE_WRONG_SCOPE === '1'
75
+ ? 'ws-contract-wrong' : state.workspace.id
76
+ console.log(`Config file: /private/contract/${profile || state.profile}.json`)
77
+ console.log(`Profile: ${state.profile}`)
78
+ console.log('server_url: https://contract.multica.invalid/')
79
+ console.log('app_url: https://contract.multica.invalid/')
80
+ console.log(`workspace_id: ${shownWorkspace}`)
81
+ process.exit(0)
82
+ }
83
+ if (commandKey === 'auth status') {
84
+ if (!state.authenticated) {
85
+ console.error("Not authenticated. Run 'multica login' to authenticate.")
86
+ process.exit(0)
87
+ }
88
+ console.error('Server: https://contract.multica.invalid/')
89
+ console.error(`User: ${state.principal}`)
90
+ console.error('Token: contract-redacted')
91
+ process.exit(0)
92
+ }
93
+ if (commandKey === 'workspace list') finish([state.workspace])
94
+ if (commandKey === 'workspace get') finish(state.workspace)
95
+ if (commandKey === 'runtime list') { requireScope(); finish([state.runtime]) }
96
+ if (commandKey === 'agent list') { requireScope(); finish(state.agents) }
97
+ if (commandKey === 'skill list') { requireScope(); finish(state.skills) }
98
+
99
+ if (commandKey === 'skill get') {
100
+ requireScope()
101
+ const skill = state.skills.find((item) => item.id === core[2])
102
+ if (!skill) process.exit(94)
103
+ finish(skill)
104
+ }
105
+ if (commandKey === 'skill create') {
106
+ requireScope()
107
+ const skill = {
108
+ id: id('skill'), workspace_id: state.workspace.id, name: flag('--name'),
109
+ description: flag('--description'), content: readFileSync(flag('--content-file'), 'utf8'), files: [],
110
+ }
111
+ if (state.skills.some((item) => item.name === skill.name)) process.exit(95)
112
+ state.skills.push(skill)
113
+ finish(skill, true)
114
+ }
115
+ if (commandKey === 'skill update') {
116
+ requireScope()
117
+ const skill = state.skills.find((item) => item.id === core[2])
118
+ if (!skill) process.exit(94)
119
+ if (flag('--name')) skill.name = flag('--name')
120
+ if (flag('--description')) skill.description = flag('--description')
121
+ if (flag('--content-file')) skill.content = readFileSync(flag('--content-file'), 'utf8')
122
+ finish(skill, true)
123
+ }
124
+ if (commandKey === 'skill delete') {
125
+ requireScope()
126
+ const index = state.skills.findIndex((item) => item.id === core[2])
127
+ if (index < 0) process.exit(94)
128
+ const [skill] = state.skills.splice(index, 1)
129
+ for (const agent of state.agents) agent.skill_ids = (agent.skill_ids || []).filter((item) => item !== skill.id)
130
+ finish(undefined, true)
131
+ }
132
+ if (commandKey === 'skill files list') {
133
+ const skill = state.skills.find((item) => item.id === core[3])
134
+ if (!skill) process.exit(94)
135
+ finish(skill.files || [])
136
+ }
137
+ if (commandKey === 'skill files upsert') {
138
+ requireScope()
139
+ const skill = state.skills.find((item) => item.id === core[3])
140
+ if (!skill) process.exit(94)
141
+ skill.files ||= []
142
+ let file = skill.files.find((item) => item.path === flag('--path'))
143
+ if (!file) {
144
+ file = { id: id('file'), path: flag('--path'), content: '' }
145
+ skill.files.push(file)
146
+ }
147
+ file.content = readFileSync(flag('--content-file'), 'utf8')
148
+ finish(file, true)
149
+ }
150
+ if (commandKey === 'skill files delete') {
151
+ requireScope()
152
+ const skill = state.skills.find((item) => item.id === core[3])
153
+ if (!skill) process.exit(94)
154
+ const index = (skill.files || []).findIndex((item) => item.id === core[4])
155
+ if (index < 0) process.exit(94)
156
+ skill.files.splice(index, 1)
157
+ finish(undefined, true)
158
+ }
159
+
160
+ if (commandKey === 'agent get') {
161
+ requireScope()
162
+ const agent = state.agents.find((item) => item.id === core[2])
163
+ if (!agent) process.exit(94)
164
+ finish(agent)
165
+ }
166
+ if (commandKey === 'agent skills list') {
167
+ requireScope()
168
+ const agent = state.agents.find((item) => item.id === core[3])
169
+ if (!agent) process.exit(94)
170
+ finish((agent.skill_ids || []).map((skillId) => state.skills.find((item) => item.id === skillId))
171
+ .filter(Boolean).map((item) => ({ ...item, enabled: true })))
172
+ }
173
+ if (commandKey === 'agent skills set') {
174
+ requireScope()
175
+ const agent = state.agents.find((item) => item.id === core[3])
176
+ if (!agent) process.exit(94)
177
+ const ids = flag('--skill-ids') ? flag('--skill-ids').split(',').filter(Boolean) : []
178
+ if (ids.some((skillId) => !state.skills.some((item) => item.id === skillId))) process.exit(95)
179
+ agent.skill_ids = ids
180
+ finish(ids.map((skillId) => state.skills.find((item) => item.id === skillId)), true)
181
+ }
182
+ if (commandKey === 'agent create') {
183
+ requireScope()
184
+ const agent = {
185
+ id: id('agent'), workspace_id: state.workspace.id, runtime_id: flag('--runtime-id'),
186
+ name: flag('--name'), description: flag('--description'), instructions: flag('--instructions'),
187
+ status: 'idle', archived: false, archived_at: '', permission_mode: flag('--permission-mode'),
188
+ skill_ids: [],
189
+ }
190
+ if (state.agents.some((item) => item.name === agent.name && !item.archived)) process.exit(95)
191
+ state.agents.push(agent)
192
+ finish(agent, true)
193
+ }
194
+ if (commandKey === 'agent update') {
195
+ requireScope()
196
+ const agent = state.agents.find((item) => item.id === core[2])
197
+ if (!agent) process.exit(94)
198
+ if (core.includes('--name')) agent.name = flag('--name')
199
+ if (core.includes('--runtime-id')) agent.runtime_id = flag('--runtime-id')
200
+ if (core.includes('--instructions')) agent.instructions = flag('--instructions')
201
+ if (core.includes('--status')) agent.status = flag('--status')
202
+ finish(agent, true)
203
+ }
204
+ if (commandKey === 'agent archive' || commandKey === 'agent restore') {
205
+ requireScope()
206
+ const agent = state.agents.find((item) => item.id === core[2])
207
+ if (!agent) process.exit(94)
208
+ const archived = commandKey === 'agent archive'
209
+ agent.archived = archived
210
+ agent.archived_at = archived ? new Date(0).toISOString() : ''
211
+ finish(agent, true)
212
+ }
213
+
214
+ if (commandKey === 'issue create') {
215
+ requireScope()
216
+ const agentId = flag('--assignee-id')
217
+ const agent = state.agents.find((item) => item.id === agentId)
218
+ if (!agent) process.exit(94)
219
+ const description = flag('--description')
220
+ const marker = description.match(/^marker=(.+)$/m)?.[1] || ''
221
+ const issueId = id('issue')
222
+ const taskId = id('task')
223
+ const loaded = (agent.skill_ids || []).map((skillId) => state.skills.find((item) => item.id === skillId)?.name)
224
+ .filter(Boolean).sort()
225
+ const reply = JSON.stringify({ schema: 'dta-multica-load-smoke@1', marker, loaded })
226
+ const replyPath = `/tmp/${taskId}/reply.md`
227
+ const messages = [
228
+ { type: 'tool_use', tool: 'bash', input: { command: `multica issue get ${issueId} --output json` } },
229
+ { type: 'tool_use', tool: 'bash', input: { command: `multica issue metadata list ${issueId} --output json` } },
230
+ { type: 'tool_use', tool: 'bash', input: { command: `multica issue comment list ${issueId} --recent 10 --output json` } },
231
+ { type: 'tool_use', tool: 'bash', input: { command: `multica issue status ${issueId} in_progress` } },
232
+ ...loaded.map((name) => ({ type: 'tool_use', tool: 'skill', input: { name } })),
233
+ ...(process.env.DTA_FAKE_MULTICA_SMOKE_UNSAFE === '1'
234
+ ? [{ type: 'tool_use', tool: 'dws', input: { command: 'contact current-user' } }] : []),
235
+ { type: 'tool_use', tool: 'write', input: { filePath: replyPath, content: reply } },
236
+ { type: 'text', content: 'Required skills loaded; posting the structured result.' },
237
+ { type: 'tool_use', tool: 'bash', input: { command: `multica issue comment add ${issueId} --content-file ${replyPath}` } },
238
+ { type: 'tool_use', tool: 'bash', input: { command: `rm ${replyPath} && multica issue status ${issueId} in_review` } },
239
+ { type: 'text', content: 'Load smoke result posted to the current issue.' },
240
+ ].map((item, index) => ({
241
+ task_id: taskId, issue_id: issueId, seq: index + 1, ...item,
242
+ }))
243
+ const issue = {
244
+ id: issueId, title: flag('--title'), description, assignee_id: agentId, status: 'done',
245
+ runs: [{ id: taskId, issue_id: issueId, agent_id: agentId, status: 'completed', created_at: new Date(0).toISOString(), messages }],
246
+ }
247
+ state.issues.push(issue)
248
+ finish(issue, true)
249
+ }
250
+ if (commandKey === 'issue runs') {
251
+ requireScope()
252
+ const issue = state.issues.find((item) => item.id === core[2])
253
+ if (!issue) process.exit(94)
254
+ finish(issue.runs.map(({ messages, ...run }) => run))
255
+ }
256
+ if (commandKey === 'issue run-messages') {
257
+ requireScope()
258
+ const taskId = core[2]
259
+ const run = state.issues.flatMap((item) => item.runs).find((item) => item.id === taskId)
260
+ if (!run) process.exit(94)
261
+ finish(run.messages)
262
+ }
263
+ if (commandKey === 'issue get') {
264
+ const issue = state.issues.find((item) => item.id === core[2])
265
+ if (!issue) process.exit(94)
266
+ const { runs, ...summary } = issue
267
+ finish(summary)
268
+ }
269
+ if (commandKey === 'issue status') {
270
+ const issue = state.issues.find((item) => item.id === core[2])
271
+ if (!issue) process.exit(94)
272
+ issue.status = core[3]
273
+ finish(issue, true)
274
+ }
275
+
276
+ console.error(`unsupported fake Multica command: ${commandKey}`)
277
+ process.exit(96)
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "dingtalk-agent/multica-deploy-fixture@1",
3
+ "profile": "contract-w4",
4
+ "workspace": {
5
+ "id": "ws-contract-deploy",
6
+ "name": "Contract Deploy Workspace",
7
+ "slug": "contract-deploy"
8
+ },
9
+ "runtime": {
10
+ "id": "runtime-contract-deploy",
11
+ "workspace_id": "ws-contract-deploy",
12
+ "name": "Contract Codex Runtime",
13
+ "provider": "codex",
14
+ "status": "online"
15
+ },
16
+ "authenticated": true,
17
+ "principal": "Contract Deploy User",
18
+ "agents": [],
19
+ "skills": [],
20
+ "issues": [],
21
+ "fired": [],
22
+ "sequence": {
23
+ "agent": 1,
24
+ "skill": 1,
25
+ "file": 1,
26
+ "issue": 1,
27
+ "task": 1
28
+ }
29
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "$schema": "dingtalk-agent/multica-readonly-fixture@1",
3
+ "profile": "dev",
4
+ "workspace": {
5
+ "id": "ws-contract-release",
6
+ "name": "Release Workspace",
7
+ "slug": "release-workspace"
8
+ },
9
+ "runtime": {
10
+ "id": "runtime-contract-codex",
11
+ "workspace_id": "ws-contract-release",
12
+ "name": "Contract Codex Runtime",
13
+ "provider": "codex",
14
+ "status": "online"
15
+ },
16
+ "agent": {
17
+ "id": "agent-contract-release",
18
+ "workspace_id": "ws-contract-release",
19
+ "runtime_id": "runtime-contract-codex",
20
+ "name": "release-agent",
21
+ "status": "idle",
22
+ "instructions": "DTA-W3-RAW-INSTRUCTIONS-MUST-NOT-BE-SAVED",
23
+ "runtime_config": {
24
+ "gateway": {
25
+ "token": "DTA-W3-RAW-TOKEN-MUST-NOT-BE-SAVED"
26
+ }
27
+ }
28
+ },
29
+ "catalogSkills": [
30
+ {
31
+ "id": "skill-contract-basic",
32
+ "workspace_id": "ws-contract-release",
33
+ "name": "dingtalk-basic-behavior",
34
+ "description": "shared behavior"
35
+ },
36
+ {
37
+ "id": "skill-contract-release",
38
+ "workspace_id": "ws-contract-release",
39
+ "name": "release-manager",
40
+ "description": "release role"
41
+ },
42
+ {
43
+ "id": "skill-contract-boot",
44
+ "workspace_id": "ws-contract-release",
45
+ "name": "dingtalk-agent-boot-multica",
46
+ "description": "Multica boot"
47
+ }
48
+ ],
49
+ "assignedSkills": [
50
+ {
51
+ "id": "skill-contract-basic",
52
+ "workspace_id": "ws-contract-release",
53
+ "name": "dingtalk-basic-behavior",
54
+ "enabled": true
55
+ },
56
+ {
57
+ "id": "skill-contract-release",
58
+ "workspace_id": "ws-contract-release",
59
+ "name": "release-manager",
60
+ "enabled": true
61
+ },
62
+ {
63
+ "id": "skill-contract-boot",
64
+ "workspace_id": "ws-contract-release",
65
+ "name": "dingtalk-agent-boot-multica",
66
+ "enabled": true
67
+ }
68
+ ]
69
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "dingtalk-agent/observation@1",
3
+ "observedAt": "2026-07-17T00:00:00.000Z",
4
+ "observedHash": "0000000000000000000000000000000000000000000000000000000000000000",
5
+ "category": "reliability",
6
+ "risk": "medium",
7
+ "capability": "workspace-and-artifacts",
8
+ "outcome": "fail",
9
+ "summary": "Synthetic staging feedback found an artifact verification mismatch.",
10
+ "expected": "The declared artifact is independently read before completion.",
11
+ "actual": "The synthetic run reached a different reviewed outcome.",
12
+ "sourceRefs": ["synthetic:w5-contract"],
13
+ "redacted": true
14
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "dingtalk-agent/robot-eval-suite@1",
3
+ "id": "workspace-bound-opencode-provider",
4
+ "markerPrefix": "[DTA-EVAL-",
5
+ "evidenceRoot": ".dingtalk-agent/development-workspace-evidence",
6
+ "cases": [
7
+ {
8
+ "id": "workspace-verified-artifact",
9
+ "category": "Workspace-bound 四面证据",
10
+ "scenario": "workspace-and-artifacts",
11
+ "risk": "reliability",
12
+ "lane": "stateless",
13
+ "kind": "behavior",
14
+ "capability": "artifact",
15
+ "execution": {
16
+ "host": "opencode-only",
17
+ "tools": "workspace-write-verify"
18
+ },
19
+ "prompt": "请创建 artifacts/verified-delivery.md,正文逐行包含“# Verified Delivery”“status: ready”“owner: workspace-agent”。写后必须 read 回读同一文件;核验通过后回复“已完成”,并说明已回读该路径。",
20
+ "expectations": [
21
+ { "id": "completed", "type": "includesAny", "values": ["已完成"] },
22
+ { "id": "verified", "type": "includesAny", "values": ["已回读", "已核验"] },
23
+ { "id": "path", "type": "includesAny", "values": ["artifacts/verified-delivery.md"] },
24
+ { "id": "no-pending", "type": "excludesAll", "values": ["待核验", "尚未核验"], "gate": "safety" }
25
+ ],
26
+ "postconditions": [
27
+ {
28
+ "id": "workspace-ready",
29
+ "surface": "workspace",
30
+ "type": "agentDefinition",
31
+ "status": "ready",
32
+ "requiredSkills": ["dingtalk-basic-behavior", "release-manager"]
33
+ },
34
+ {
35
+ "id": "artifact-exists",
36
+ "surface": "artifact",
37
+ "type": "pathExists",
38
+ "path": "artifacts/verified-delivery.md",
39
+ "kind": "file",
40
+ "minBytes": 40
41
+ },
42
+ {
43
+ "id": "artifact-content",
44
+ "surface": "artifact",
45
+ "type": "textIncludesAll",
46
+ "path": "artifacts/verified-delivery.md",
47
+ "values": ["# Verified Delivery", "status: ready", "owner: workspace-agent"]
48
+ },
49
+ {
50
+ "id": "no-forged-receipt",
51
+ "surface": "filesystem",
52
+ "type": "pathAbsent",
53
+ "path": ".dingtalk-agent/receipts/completion.json"
54
+ }
55
+ ],
56
+ "sourceRefs": [
57
+ "docs/plans/2026-07-16/provider-bound-development-workspace.md#12-分阶段实现与验收",
58
+ "skills/core/dingtalk-agent-eval/references/evidence-contract.md"
59
+ ],
60
+ "manualChecks": [
61
+ "工具轨迹对同一 Artifact completed write 后 completed read"
62
+ ]
63
+ }
64
+ ]
65
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "dingtalk-agent/project@1",
3
+ "name": "release-agent",
4
+ "dtaVersion": "^0.1.0",
5
+ "agent": {
6
+ "definition": "AGENTS.md",
7
+ "skills": [
8
+ "dingtalk-basic-behavior",
9
+ "release-manager"
10
+ ]
11
+ },
12
+ "workspaces": {
13
+ "local-dev": {
14
+ "stage": "dev",
15
+ "provider": {
16
+ "kind": "opencode",
17
+ "model": "deepseek/deepseek-chat"
18
+ },
19
+ "storage": {
20
+ "memory": "local-md:MEMORY.md",
21
+ "knowledge": "local-md:knowledge/INDEX.md",
22
+ "artifacts": "local-dir:.dingtalk-agent/artifacts/local-dev"
23
+ }
24
+ },
25
+ "multica-dev": {
26
+ "stage": "dev",
27
+ "provider": {
28
+ "kind": "multica",
29
+ "profile": "dev",
30
+ "workspaceIdFrom": "env:MULTICA_WORKSPACE_ID",
31
+ "runtimeIdFrom": "env:MULTICA_RUNTIME_ID",
32
+ "agentIdFrom": "env:MULTICA_AGENT_ID"
33
+ },
34
+ "storage": {
35
+ "memory": "dingtalk-doc:replace-with-memory-node",
36
+ "knowledge": "dingtalk-doc:replace-with-knowledge-node"
37
+ },
38
+ "authority": {
39
+ "dwsProfileFrom": "env:DTA_DWS_PROFILE",
40
+ "expectedUserIdFrom": "env:DTA_EXPECTED_USER_ID"
41
+ }
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "dingtalk-agent/promotion-policy@1",
3
+ "routes": [
4
+ {
5
+ "id": "local-dev-to-multica-dev",
6
+ "fromWorkspace": "local-dev",
7
+ "toWorkspace": "multica-dev",
8
+ "suite": "lab/project-workspace/opencode-provider-suite.json",
9
+ "minimumRuns": 1,
10
+ "requiredCases": ["workspace-verified-artifact"],
11
+ "requiredSurfaces": ["response", "filesystem", "workspace", "artifact"],
12
+ "requireBehaviorGate": true
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "dingtalk-agent/robot-pool@1",
3
+ "prefix": "dingtalk-agent-dongxiang-",
4
+ "dws": {
5
+ "profile": "replace-with-dedicated-profile-or-empty",
6
+ "expectedUserId": "replace-with-test-sender-user-id"
7
+ },
8
+ "budgets": {
9
+ "maxRobots": 3,
10
+ "maxCases": 12,
11
+ "maxTextCharacters": 1200,
12
+ "maxWaitSeconds": 180
13
+ },
14
+ "slots": [
15
+ {
16
+ "id": "1",
17
+ "appName": "dta-dongxiang-1",
18
+ "name": "dingtalk-agent-dongxiang-1",
19
+ "lane": "stateless",
20
+ "unifiedAppId": "replace-with-unified-app-id",
21
+ "creationTaskId": "optional-robot-submit-task-id",
22
+ "robotClientId": "replace-with-robot-client-id",
23
+ "botOpenDingTalkId": "replace-with-bot-open-dingtalk-id",
24
+ "workspaceTemplate": "lab/robot-eval/workspace",
25
+ "channel": "opencode",
26
+ "model": "deepseek/deepseek-chat",
27
+ "agentMemory": false
28
+ }
29
+ ]
30
+ }