🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

验收标准门禁 cckyros/goal-acceptance

DeepSeek Harnessv0.3.0
cckyros15 天前有提交已提供中文文档扫描:含敏感能力

面向自主 AI Agent 的验收标准驱动目标完成机制。

36.5/100
综合分
2
GitHub 星标
241
npm 周下载
—/5
用户评分

数据截至 2026/10/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @cckyros/goal-acceptance
npm 源 · @cckyros/goal-acceptance 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · tool
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@cckyros/goal-acceptance @ 0.3.0
✓Node 引擎要求 >=18 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/31 07:32:29

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 210 处,展示前 115 条)
  • 读取本地文件
    dist/dsh-plugin.js:70
    const content = readFileSync(absolutePath);
  • 读取本地文件
    dist/dsh-plugin.js:1012
    if (!existsSync(this.path)) return [];
  • 读取本地文件
    dist/dsh-plugin.js:1013
    const raw = await readFileSync2(this.path, "utf-8");
  • 写入本地文件
    dist/dsh-plugin.js:1018
    await writeFileSync(this.path, JSON.stringify(events, null, 2) + "\n");
  • 读取本地文件
    dist/dsh-plugin.js:1021
    if (!existsSync(this.path)) return [];
  • 读取本地文件
    dist/dsh-plugin.js:1022
    const raw = readFileSync2(this.path, "utf-8");
  • 写入本地文件
    dist/dsh-plugin.js:1043
    mkdirSync(lockDir);
  • 读取本地文件
    dist/dsh-plugin.js:1048
    if (Date.now() - statSync(lockDir).mtimeMs > staleMs) {
  • 删除本地文件递归
    dist/dsh-plugin.js:1049
    rmSync(lockDir, { recursive: true, force: true });
  • 删除本地文件递归
    dist/dsh-plugin.js:1063
    rmSync(lockDir, { recursive: true, force: true });
  • 写入本地文件
    dist/dsh-plugin.js:1077
    mkdirSync(this.goalsDir, { recursive: true });
  • 写入本地文件
    dist/dsh-plugin.js:1113
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(updated, null, 2) + "\n");
  • 写入本地文件
    dist/dsh-plugin.js:1145
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    dist/dsh-plugin.js:1146
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(meta, null, 2) + "\n");
  • 删除本地文件
    dist/dsh-plugin.js:1248
    unlinkSync(join(dir, `${id}.json`));
  • 删除本地文件
    dist/dsh-plugin.js:1252
    unlinkSync(join(dir, `${id}.meta.json`));
  • 执行外部命令来自配置/变量
    dist/dsh-plugin.js:2198
    stdout = execSync(command, {
  • 执行外部命令来自配置/变量
    dist/dsh-plugin.js:3174
    stdout = execSync2(command, {
  • 读取本地文件
    dist/cli.js:23
    if (!existsSync(p)) return null;
  • 读取本地文件
    dist/cli.js:25
    const data = JSON.parse(readFileSync(p, "utf8"));
  • 读取本地文件
    dist/cli.js:103
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    dist/cli.js:103
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    dist/cli.js:104
    writeFileSync(p, JSON.stringify(values, null, 2) + "\n", "utf8");
  • 读取本地文件
    dist/cli.js:257
    if (!existsSync2(p)) return null;
  • 读取本地文件
    dist/cli.js:259
    return readFileSync2(p, "utf8");
  • 写入本地文件
    dist/cli.js:265
    mkdirSync2(dirname(p), { recursive: true });
  • 写入本地文件
    dist/cli.js:269
    writeFileSync2(p, content, "utf8");
  • 写入本地文件
    dist/cli.js:274
    copyFileSync(p, bak);
  • 读取本地文件
    dist/cli.js:428
    if (existsSync3(p)) return p;
  • 写入本地文件
    dist/cli.js:2069
    await writeFileSync3(this.path, JSON.stringify(events, null, 2) + "\n");
  • 删除本地文件递归
    dist/cli.js:2100
    rmSync(lockDir, { recursive: true, force: true });
  • 删除本地文件递归
    dist/cli.js:2114
    rmSync(lockDir, { recursive: true, force: true });
  • 删除本地文件
    dist/cli.js:2299
    unlinkSync(join4(dir, `${id}.json`));
  • 删除本地文件
    dist/cli.js:2303
    unlinkSync(join4(dir, `${id}.meta.json`));
  • 执行外部命令来自配置/变量
    dist/cli.js:3193
    stdout = execSync(command, {
  • 删除本地文件
    dist/cli.js:3643
    rmSync2(target, { force: true });
  • 删除本地文件递归
    dist/cli.js:3675
    rmSync2(d, { recursive: true, force: true });
  • 执行外部命令来自配置/变量
    dist/cli.js:4580
    const child = spawn(cmd, argv, {
  • 写入本地文件
    build.mjs:53
    await mkdir(join(root, "dist"), { recursive: true });
  • 删除本地文件递归
    build.mjs:112
    await rm(join(root, "assets"), { recursive: true, force: true });
  • 写入本地文件
    build.mjs:120
    await mkdir(skillDir, { recursive: true });
  • 读取本地文件
    build.mjs:121
    const skillBody = fillTemplate(await readFile(join(root, "src/assets/SKILL.md"), "utf8"), vars);
  • 写入本地文件
    build.mjs:122
    await writeFile(join(skillDir, "SKILL.md"), skillBody, "utf8");
  • 读取本地文件
    build.mjs:126
    if (existsSync(join(root, "src/assets/skill-references"))) {
  • 写入本地文件
    build.mjs:127
    await mkdir(join(skillDir, "references"), { recursive: true });
  • 读取本地文件
    build.mjs:134
    if (existsSync(companionSkills)) {
  • 读取本地文件
    build.mjs:135
    for (const entry of await readdir(companionSkills, { withFileTypes: true })) {
  • 读取本地文件
    build.mjs:138
    if (!existsSync(srcSkill)) continue;
  • 写入本地文件
    build.mjs:140
    await mkdir(dstDir, { recursive: true });
  • 读取本地文件
    build.mjs:141
    const body = fillTemplate(await readFile(srcSkill, "utf8"), vars);
  • 写入本地文件
    build.mjs:142
    await writeFile(join(dstDir, "SKILL.md"), body, "utf8");
  • 读取本地文件
    dist/openclaw-plugin.js:4477
    const content = readFileSync(absolutePath);
  • 读取本地文件
    dist/openclaw-plugin.js:5422
    if (!existsSync(this.path)) return [];
  • 读取本地文件
    dist/openclaw-plugin.js:5423
    const raw = await readFileSync2(this.path, "utf-8");
  • 写入本地文件
    dist/openclaw-plugin.js:5428
    await writeFileSync(this.path, JSON.stringify(events, null, 2) + "\n");
  • 读取本地文件
    dist/openclaw-plugin.js:5431
    if (!existsSync(this.path)) return [];
  • 读取本地文件
    dist/openclaw-plugin.js:5432
    const raw = readFileSync2(this.path, "utf-8");
  • 写入本地文件
    dist/openclaw-plugin.js:5453
    mkdirSync(lockDir);
  • 读取本地文件
    dist/openclaw-plugin.js:5458
    if (Date.now() - statSync(lockDir).mtimeMs > staleMs) {
  • 删除本地文件递归
    dist/openclaw-plugin.js:5459
    rmSync(lockDir, { recursive: true, force: true });
  • 删除本地文件递归
    dist/openclaw-plugin.js:5473
    rmSync(lockDir, { recursive: true, force: true });
  • 写入本地文件
    dist/openclaw-plugin.js:5487
    mkdirSync(this.goalsDir, { recursive: true });
  • 写入本地文件
    dist/openclaw-plugin.js:5523
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(updated, null, 2) + "\n");
  • 写入本地文件
    dist/openclaw-plugin.js:5555
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    dist/openclaw-plugin.js:5556
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(meta, null, 2) + "\n");
  • 删除本地文件
    dist/openclaw-plugin.js:5658
    unlinkSync(join(dir, `${id}.json`));
  • 删除本地文件
    dist/openclaw-plugin.js:5662
    unlinkSync(join(dir, `${id}.meta.json`));
  • 执行外部命令来自配置/变量
    dist/openclaw-plugin.js:6222
    stdout = execSync(command, {
  • 读取本地文件
    openclaw-dist/openclaw-plugin.js:4477
    const content = readFileSync(absolutePath);
  • 读取本地文件
    openclaw-dist/openclaw-plugin.js:5422
    if (!existsSync(this.path)) return [];
  • 读取本地文件
    openclaw-dist/openclaw-plugin.js:5423
    const raw = await readFileSync2(this.path, "utf-8");
  • 写入本地文件
    openclaw-dist/openclaw-plugin.js:5428
    await writeFileSync(this.path, JSON.stringify(events, null, 2) + "\n");
  • 读取本地文件
    openclaw-dist/openclaw-plugin.js:5431
    if (!existsSync(this.path)) return [];
  • 读取本地文件
    openclaw-dist/openclaw-plugin.js:5432
    const raw = readFileSync2(this.path, "utf-8");
  • 写入本地文件
    openclaw-dist/openclaw-plugin.js:5453
    mkdirSync(lockDir);
  • 读取本地文件
    openclaw-dist/openclaw-plugin.js:5458
    if (Date.now() - statSync(lockDir).mtimeMs > staleMs) {
  • 删除本地文件递归
    openclaw-dist/openclaw-plugin.js:5459
    rmSync(lockDir, { recursive: true, force: true });
  • 删除本地文件递归
    openclaw-dist/openclaw-plugin.js:5473
    rmSync(lockDir, { recursive: true, force: true });
  • 写入本地文件
    openclaw-dist/openclaw-plugin.js:5487
    mkdirSync(this.goalsDir, { recursive: true });
  • 写入本地文件
    openclaw-dist/openclaw-plugin.js:5523
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(updated, null, 2) + "\n");
  • 写入本地文件
    openclaw-dist/openclaw-plugin.js:5555
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    openclaw-dist/openclaw-plugin.js:5556
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(meta, null, 2) + "\n");
  • 删除本地文件
    openclaw-dist/openclaw-plugin.js:5658
    unlinkSync(join(dir, `${id}.json`));
  • 删除本地文件
    openclaw-dist/openclaw-plugin.js:5662
    unlinkSync(join(dir, `${id}.meta.json`));
  • 执行外部命令来自配置/变量
    openclaw-dist/openclaw-plugin.js:6222
    stdout = execSync(command, {
  • 读取本地文件
    src/framework/config.ts:35
    if (!existsSync(p)) return null;
  • 读取本地文件
    src/framework/config.ts:37
    const data = JSON.parse(readFileSync(p, "utf8"));
  • 读取本地文件
    src/framework/config.ts:137
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/framework/config.ts:137
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/framework/config.ts:138
    writeFileSync(p, JSON.stringify(values, null, 2) + "\n", "utf8");
  • 读取本地文件
    src/framework/registry.ts:87
    if (existsSync(p)) return p;
  • 读取本地文件
    src/framework/safe-fs.ts:20
    if (!existsSync(p)) return null;
  • 读取本地文件
    src/framework/safe-fs.ts:22
    return readFileSync(p, "utf8");
  • 写入本地文件
    src/framework/safe-fs.ts:29
    mkdirSync(dirname(p), { recursive: true });
  • 写入本地文件
    src/framework/safe-fs.ts:34
    writeFileSync(p, content, "utf8");
  • 写入本地文件
    src/framework/safe-fs.ts:41
    copyFileSync(p, bak);
  • 执行外部命令来自配置/变量
    src/plugin/dsh-plugin.ts:805
    stdout = execSync(command, {
  • 读取本地文件
    src/plugin/goal-manager.ts:40
    if (!existsSync(this.path)) return []
  • 读取本地文件
    src/plugin/goal-manager.ts:41
    const raw = await readFileSync(this.path, 'utf-8')
  • 写入本地文件
    src/plugin/goal-manager.ts:47
    await writeFileSync(this.path, JSON.stringify(events, null, 2) + '\n')
  • 读取本地文件
    src/plugin/goal-manager.ts:52
    if (!existsSync(this.path)) return []
  • 读取本地文件
    src/plugin/goal-manager.ts:53
    const raw = readFileSync(this.path, 'utf-8')
  • 写入本地文件
    src/plugin/goal-manager.ts:76
    mkdirSync(lockDir)
  • 读取本地文件
    src/plugin/goal-manager.ts:81
    if (Date.now() - statSync(lockDir).mtimeMs > staleMs) {
  • 删除本地文件递归
    src/plugin/goal-manager.ts:82
    rmSync(lockDir, { recursive: true, force: true })
  • 删除本地文件递归
    src/plugin/goal-manager.ts:97
    rmSync(lockDir, { recursive: true, force: true })
  • 写入本地文件
    src/plugin/goal-manager.ts:133
    mkdirSync(this.goalsDir, { recursive: true })
  • 写入本地文件
    src/plugin/goal-manager.ts:173
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(updated, null, 2) + '\n')
  • 写入本地文件
    src/plugin/goal-manager.ts:208
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/plugin/goal-manager.ts:209
    writeFileSync(join(dir, `${id}.meta.json`), JSON.stringify(meta, null, 2) + '\n')
  • 读取本地文件
    src/plugin/goal-manager.ts:233
    if (existsSync(f)) {
  • 删除本地文件
    src/plugin/goal-manager.ts:320
    try { unlinkSync(join(dir, `${id}.json`)) } catch { }
  • 删除本地文件
    src/plugin/goal-manager.ts:321
    try { unlinkSync(join(dir, `${id}.meta.json`)) } catch { }
  • 执行外部命令来自配置/变量
    src/plugin/openclaw-plugin.ts:564
    stdout = execSync(command, {
  • 执行外部命令来自配置/变量
    src/plugin/tools.ts:876
    stdout = execSync(command, {
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-invariants@deepseek-ai/dsh-llm@deepseek-ai/dsh-scope@deepseek-ai/dsh-session@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-timeout@deepseek-ai/dsh-tools@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

1 张 · 点击查看大图

功能亮点

  • 锁定验收标准
  • 未达标阻止收工

验收标准驱动的自主智能体目标达成——核心库、MCP 服务器和 Cordis 插件

v0.2.82026-10-13
智能体市场发现清单:.claude-plugin/(Claude Code)、.agents/plugins/ + .codex-plugin/(Codex/ChatGPT)、.cursor-plugin/(Cursor),dsh.plugin.json 由清单重新生成(此前冻结在 0.2.0),server.json 供官方 MCP 注册表使用。仓库现在是一个自托管的插件市场:claude/codex plugin marketplace add cckyros/goal-acceptance。
v0.2.72026-10-13
编排任务节点 + 无头门禁,供外部循环使用(例如 ralph-orchestrator)。 任务编排(工具从 16 个增至 18 个) · claim_task — 派发节点:领取下一个依赖就绪的任务,返回任务及其关联的验收标准,作为工作契约 · review_task — 验收节点:由独立评审者给出单层正式判定;驳回则任务保持 in_progress,并返回 blockingCriteria 作为返工反馈(返工 → 重审循环);通过则完成任务并解锁依赖任务 · 新增 byReviewer 验收标准语义 + 4 个错误码 供编排器钩子使用的无头命令行 · goal-acceptance check — 仅当 can_complete_goal 允许时退出码为 0;与 ralph 的 pre.loop.complete + on_error: block 搭配使用(见 examples/ralph/ralph.yml) · goal-acceptance status — 输出 JSON 摘要,供脚本和仪表盘使用 · 与 MCP 服务器共用 PLUGIN_DATA
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
goal-acceptance goal-acceptance 面向自主 AI Agent 的验收标准驱动目标完成机制。 在 Agent 开始工作前锁定不可变的验收标准,在执行过程中记录带证据的验证状态,将标准关联到任务进度并校验任务依赖,最后阻止 Agent 在必需标准未正式通过时提前宣布完成。 优势 1. 跨平台兼容 单一包、四种运行时、22 个安装目标: | 平台 | 接入方式 | 停止时强制能力 | | Claude Code | MCP stdio server(cli mcp) | 模型主动调用工具 | | Cursor | MCP stdio server(cli mcp) | 模型主动调用工具 | | Devin | MCP stdio server(cli mcp) | 模型主动调用工具 | | OpenClaw | 原生插件(openclaw-dist/,进程内、无 stdio) | 模型主动调用工具 | | DeepSeek Harness | Cordis 插件(dist/dsh-plugin.js) | agent.steer() 强制继续 | | 任意 MCP 客户端 | stdio MCP server(cli mcp) | 模型主动调用工具 |
展开完整文档(README 剩余 1 节)
goal-acceptance

goal-acceptance

面向自主 AI Agent 的验收标准驱动目标完成机制。

在 Agent 开始工作前锁定不可变的验收标准,在执行过程中记录带证据的验证状态,将标准关联到任务进度并校验任务依赖,最后阻止 Agent 在必需标准未正式通过时提前宣布完成。

优势

1. 跨平台兼容

单一包、四种运行时、22 个安装目标:

| 平台 | 接入方式 | 停止时强制能力 |
| Claude Code | MCP stdio server(cli mcp) | 模型主动调用工具 |
| Cursor | MCP stdio server(cli mcp) | 模型主动调用工具 |
| Devin | MCP stdio server(cli mcp) | 模型主动调用工具 |
| OpenClaw | 原生插件(openclaw-dist/,进程内、无 stdio) | 模型主动调用工具 |
| DeepSeek Harness | Cordis 插件(dist/dsh-plugin.js) | agent.steer() 强制继续 |
| 任意 MCP 客户端 | stdio MCP server(cli mcp) | 模型主动调用工具 |
| 任意 Agent Plugins 客户端 | plugin.json + mcp.json + skills | 模型主动调用工具 |
| 任意 JS/TS 运行时 | 核心引擎(src/plugin/engine/,已打入 CLI) | 由程序控制 |

核心状态机零依赖。cli mcp server、dsh Cordis 插件、OpenClaw 原生插件全部调用同一套共享引擎与目标管理器——一份实现,四个出口。

2. 一条命令安装 22 个平台

dist/cli.js install --target <name> 为 22 个客户端注册本插件:

- 原生 MCP(8):claude、codex、opencode、qwen、reasonix、kilo、workbuddy、devin
- Skill 目标(4):trae、pi、omp、dsh
- Agent Plugins(10):copilot、cursor、kiro、openclaw、hermes、vscode、chatgpt-codex、grok、nanoclaw、other

每个适配器都从同一份生成好的便携包(plugin.json / mcp.json / .mcp.json / skills/ / openclaw.plugin.json / openclaw-dist/)写入客户端原生配置。

3. MCP server 提供 19 个工具

MCP server 覆盖完整的目标验收生命周期:

- 标准管理:set_acceptance_criteria、get_acceptance_criteria、amend_acceptance_criteria
- 任务计划:set_task_plan、get_task_plan
- 验证:validate_criterion、confirm_criterion
- 进度跟踪:update_task_status
- 完成门禁:can_complete_goal
- 多目标管理:start_goal、create_goal、list_goals、switch_goal、reset_goal
- 快速开始:quick_start_goal(一步完成开始/切换目标、锁定标准、可选设置任务计划)
- 运行并验证:run_and_validate(执行 shell 命令并一步完成标准验证)

完整列表见下文 MCP 工具。

多目标隔离

每个目标都拥有独立的事件文件 ${PLUGIN_DATA}/goals/{goalId}.json,多个项目和窗口可以共享同一个 server:

- set_acceptance_criteria 在没有活动目标时自动创建目标
- start_goal 开始一个全新的独立目标
- switch_goal 在目标之间切换,list_goals 列出所有目标及状态
- reset_goal 删除当前目标及其数据
- 活动目标会在 server 重启后通过 current-goal.txt 恢复

4. 独立复核,避免自我评分

set_acceptance_criteria 的 role 参数支持 agent、reviewer 和 dual。
默认角色是 agent:Agent 调用 validate_criterion 通过标准后,会标记为 selfClaimed=true。只有独立 reviewer 使用新证据调用 confirm_criterion 后,该标准才算正式通过,can_complete_goal 才会允许完成目标。

5. 类型化证据

validate_criterion 支持 command、file、url 和 text 四种证据类型。
对于命令标准,应实际运行命令并提交真实输出;对于文件和 URL 标准,应提交实际检查结果。
confirm_criterion 只接受高可信度的 command、file 或 url 证据,不接受纯文本判断。

6. 任务分解与依赖校验

set_task_plan 将目标拆分为带具体交付物的原子任务。引擎会校验任务 ID 唯一、描述明确、交付物非空、依赖存在,并拒绝直接或间接依赖环。

7. 事件源持久化与精简响应

所有状态变化都以追加事件保存,读取时重放事件,从而支持持久化、重启恢复和完整审计轨迹。
MCP 工具默认返回精简摘要;传入 verbose=true 可获取完整摘要。

架构

src/
├── framework/ # 零依赖脚手架(manifest、registry、CLI、wizard、 │ # mcp-runtime、hook-runtime、安装器) ├── plugin/ │ ├── engine/ # 事件源状态机(core) │ ├── goal-manager.ts # 多目标管理器(所有通路共享) │ ├── tools.ts # 19 个 ToolDef(manifest.tools 数据源) │ ├── manifest.ts # 身份唯一来源 │ ├── dsh-plugin.ts # DeepSeek Harness Cordis 插件 │ ├── openclaw-plugin.ts # OpenClaw 原生插件(typebox、进程内) │ ├── openclaw-session-sync.ts # 将活动目标同步到 OpenClaw SessionEntry.goal │ ├── prompt.ts # dsh 系统提示指引 │ ├── invariant.ts # dsh session 不变量伴生插件 │ └── targets/ # 22 个安装适配器 └── assets/ # SKILL.md + 8 个配套技能({{占位符}})

build.mjs → dist/cli.js(CLI + MCP)+ dist/hook.cjs + dist/dsh-plugin.js
+ dist/openclaw-plugin.js → openclaw-dist/
+ plugin.json / mcp.json / .mcp.json / marketplace.json
/ cordis.patch.yml / openclaw.plugin.json / skills/

所有身份文件都在构建时由 src/plugin/manifest.ts 生成并提交,仓库本身就是所有客户端的合法安装源。

快速开始

安装(一条命令,22 个平台)

node dist/cli.js install # 交互式向导
node dist/cli.js install --target claude
node dist/cli.js install --target openclaw
node dist/cli.js list-targets # 查看全部 22 个

插件市场

本仓库自身即插件市场 —— 插件源为 ./(仓库根目录),添加仓库即可发现插件:

Claude Code(读取 .claude-plugin/marketplace.json) claude plugin marketplace add cckyros/goal-acceptance 然后:/plugin install goal-acceptance@cckyros

Codex CLI / ChatGPT(读取 .agents/plugins/marketplace.json) codex plugin marketplace add cckyros/goal-acceptance 然后:codex plugin add goal-acceptance@cckyros

Cursor(读取 .cursor-plugin/marketplace.json):在 Settings → Plugins 中添加本仓库为插件市场

仓库还带有 server.json —— 官方 MCP registry 的描述文件(mcp-publisher login github 后执行 mcp-publisher publish,命名空间 io.github.cckyros/goal-acceptance)。

MCP server(任意 MCP 客户端)

{
"mcpServers": {
"@cckyros/goal-acceptance": {
"type": "stdio",
"command": "node",
"args": ["/path/to/goal-acceptance/dist/cli.js", "mcp"],
"env": { "PLUGIN_DATA": "/path/to/persistent/data" }
}
}
}

独立运行:

内存模式(重启后丢失)
node dist/cli.js mcp

持久化模式
PLUGIN_DATA=/path/to/data node dist/cli.js mcp

未设置 PLUGIN_DATA 时状态仅存于内存(重启丢失)。

典型工作流

1. 设定标准 — set_acceptance_criteria,role=reviewer(你验证)或 role=agent(Agent 自评,稍后确认)
2. 设定任务计划 — set_task_plan 将目标拆分为带交付物和依赖的原子任务
3. 执行 — 任务推进时调用 update_task_status(pending — in_progress — completed)
4. 验证 — validate_criterion 使用 evidence_type=command 提交高可信度证据。默认 role=agent:通过的标准标记为自评
5. 确认 — confirm_criterion(仅限独立 reviewer)使用全新的 command/file/url 证据,将自评转为正式通过
6. 检查 — can_complete_goal 确认所有必需标准均已正式通过

编排式任务循环(worker + reviewer 子 agent,单层验收):

1. 分配 — claim_task 将下一个依赖就绪任务标记 in_progress,返回任务及其关联 criteria(任务粒度的验收契约)
2. 验收 — 独立 reviewer 子 agent 调 review_task 逐条给出判定。判定为正式结果:单层验收,不走自评+确认两跳
3. 轮回 — 不通过则任务保持 in_progress,blockingCriteria 即打回反馈;改完再 review_task。全部通过则任务完成,nextTask 返回下一个可认领任务
4. 门禁 — can_complete_goal(或 goal-acceptance check)仍把守整个 goal 的完成

OpenClaw 原生插件

openclaw-dist/ 携带进程内插件(bundle + 带 openclaw.extensions 契约的最小 package.json),openclaw.plugin.json 声明 19 个工具契约:

openclaw plugins install @cckyros/goal-acceptance
或本地构建: openclaw plugins install /path/to/goal-acceptance/openclaw-dist openclaw gateway restart openclaw plugins list # goal-acceptance: loaded

19 个工具可在 OpenClaw 会话中使用。Shape: non-capability 对工具插件是正常的——工具经 defineToolPlugin 注册,不经过 capability 系统。

每次会改变目标状态的工具调用后(start_goal、set_acceptance_criteria、 validate_criterion、confirm_criterion、amend_acceptance_criteria、 update_task_status、set_task_plan、run_and_validate、quick_start_goal、 switch_goal、reset_goal),插件都会把当前 acceptance 目标镜像到 OpenClaw 的 SessionEntry.goal 槽。这样 OpenClaw 内置的 get_goal 和 update_goal 就能看到这个活动目标。update_goal 直接修改 SessionEntry.goal 后,如果后续再调用插件工具,插件会按自身事件源状态重新同步该槽。

DeepSeek Harness(Cordis 插件)

dist/dsh-plugin.js 是唯一能强制 Agent 继续工作的变体:它拦截 agent/turn-stopping,按依赖感知的优先级把 Agent 拉回未完成工作。

cordis.patch.yml(自动生成)
- insert:
- id: @cckyros/goal-acceptance
name: @cckyros/goal-acceptance
config: {}

该插件:

- 注册与 MCP 适配器相同的 19 个模型工具
- 注入 policy:goal-acceptance 系统提示段落,给出任务进度与 next-actionable 排序
- 拦截 agent/turn-stopping,按依赖感知优先级把 Agent 拉回待办工作,以及等待 reviewer 确认的自评标准

注意:dsh 插件需要 DeepSeek Harness 宿主包作为 peer 依赖(@deepseek-ai/),由 dsh profile 在运行时注入。@deepseek-ai/ 在本仓库仅是 devDependencies(类型用途)。

核心引擎(任意 JS/TS 运行时)

零依赖状态机位于 src/plugin/engine/,已打入 CLI。可从此仓库直接使用,或将目录复制到你的项目:

import { GoalAcceptanceEngine, InMemoryAcceptanceStore } from './src/plugin/engine/index.ts'

const engine = new GoalAcceptanceEngine(new InMemoryAcceptanceStore())

// 开始工作前锁定验收标准 await engine.setCriteria([ { id: 'api-200', description: 'GET /health returns 200', required: true, method: 'test', taskIds: ['task-1', 'task-2'] }, { id: 'docs', description: 'README updated', required: false, method: 'manual', dependsOn: ['api-200'] }, ])

// 随进度更新任务状态 await engine.updateTaskStatus({ taskId: 'task-1', status: 'completed' }) await engine.updateTaskStatus({ taskId: 'task-2', status: 'completed' })

// 关联任务全部完成后,标准进入 "ready to validate" const summary = engine.summarize()
console.log(summary.readyToValidate.map(c => c.id)) // ['api-200']

// 记录带证据的验证 await engine.validateCriterion({ criterionId: 'api-200', status: 'passed', evidence: 'curl /health -> HTTP 200 OK', })

// 检查目标是否可以完成
const { allowed, reason } = engine.canComplete()
console.log(allowed, reason)
// true, undefined

面向编排器的无头门禁

check 和 status 不走 MCP 即可暴露完成判定,让外部循环驱动器(ralph-orchestrator 的 hooks、CI 门禁、shell 脚本)把 can_complete_goal 当硬性 backpressure 门禁用。两者与 MCP server 用完全相同的方式解析数据目录(PLUGIN_DATA 环境变量 / pluginData 配置)——编排器和 agent 侧的 MCP server 要指向同一个目录。

goal-acceptance check # 目标可完成时退出码 0;否则退出码 1,并在 stderr 打印阻塞的 criteria 列表 goal-acceptance status # JSON 摘要:goalId、allowed、criteria、计数

ralph-orchestrator

把 check 接进 ralph 的 pre.loop.complete hook 并设 on_error: block: agent 在循环里通过 goal-acceptance MCP server 维护 criteria 并攒证据,任何 criteria 不支持的 LOOP_COMPLETE 声明都会被驳回,循环继续磨到目标真正达标。现成配置见 examples/ralph/ralph.yml:

hooks:
enabled: true
events:
pre.loop.complete:
- name: goal-acceptance-gate
command: ["goal-acceptance", "check"]
on_error: block

MCP 工具

| 工具 | 说明 |
| set_acceptance_criteria | 锁定验收标准列表。每个标准可关联任务 ID 并声明依赖。可选 role 参数(agent/reviewer/dual,默认 agent)控制自评行为。实现前必须先调用。 |
| get_acceptance_criteria | 读取当前标准、任务进度、摘要、任务计划、待验证列表与 next-actionable 排序。可选 verbose(默认 true;false 仅返回精简摘要)。 |
| set_task_plan | 设定并锁定任务分解计划。每个任务须有唯一 ID、明确的描述与具体交付物。拒绝依赖环。要求标准已锁定。 |
| get_task_plan | 读取当前任务分解计划及实时任务状态。 |
| validate_criterion | 记录状态(pending/in_progress/passed/failed/blocked/not_run)与证据。passed 和 failed 必须附带证据。可选 evidence_type(command/file/url/text,默认 text)。默认 role=agent 时 passed 标记为自评。可选 verbose(默认 false)。 |
| confirm_criterion | 仅限 reviewer。 使用独立复核证据确认自评通过的标准。要求 evidence_type 为 command/file/url(拒绝 text)。将自评转为正式通过,解除 can_complete_goal 阻塞。必须由独立 reviewer 调用,而非执行工作的 Agent。 |
| update_task_status | 更新关联任务的状态(pending/in_progress/completed/failed)。任务全部完成的标准进入待验证。可选 verbose(默认 false)。 |
| claim_task | 任务分配节点:为 worker 认领下一个依赖就绪的任务(或指定 task_id)——标记 in_progress 并返回任务 + 关联 criteria,即任务粒度的验收契约。 |
| review_task | 任务验收节点:独立 reviewer 对该任务关联 criteria 记录正式判定(单层验收,不产生 self-claimed)。全部 required 正式通过 → 任务完成并解锁依赖任务(返回 nextTask);否则 blockingCriteria 为下一轮的打回反馈。 |
| amend_acceptance_criteria | 初次锁定后追加新标准。必须提供 reason。已有标准不会被修改。 |
| update_criterion | 修补已有标准的声明(description/required/method/verify_command/artifacts),必须提供审计 reason。对已 passed 的标准改 artifacts 或 verify_command 会重置为 pending(强制复验)。verify_command: null 清除钉死。 |
| can_complete_goal | 检查所有必需标准是否已正式通过(自评不计)。返回 { allowed: boolean, reason?: string }。 |
| start_goal | 以全新状态开始新的独立目标(可选 title)。新目标成为活动目标。当前目标已锁定且需要新任务时使用。 |
| create_goal | 创建命名目标(name 必填,description 可选)并设为活动目标。始终开启新目标;元数据会显示在 list_goals 中。 |
| list_goals | 列出所有目标:ID、标题、标准计数与活动标记。 |
| switch_goal | 按 ID 切换活动目标。 |
| quick_start_goal | 便捷快速路径:一步完成开始/切换目标、锁定验收标准,并可选同时设置任务计划。 |
| run_and_validate | 执行 shell 命令并一步完成标准验证。捕获 stdout/stderr/exitCode 作为 evidence_type=command 证据。 |
| reset_goal | 永久删除当前目标及其全部数据。 |

技能(Skills)

插件附带 9 个技能(构建时从 src/assets/ 填充占位符生成):

skills/
├── goal-acceptance/SKILL.md # 主技能:工作流 + 配套技能索引 ├── goal-planning/ # 先分解为覆盖完整的标准 ├── set-acceptance-criteria/ # 锁定标准(标准质量规则) ├── amend-acceptance-criteria/ # 需求扩展时追加标准 ├── get-acceptance-criteria/ # 读取当前标准与进度 ├── update-task-status/ # 跟踪关联任务状态 ├── validate-criterion/ # 记录状态 + 真实执行证据 ├── confirm-criterion/ # 独立 reviewer 确认(全新证据) └── can-complete-goal/ # 完成门禁;自评标准阻塞

标准状态生命周期

pending -> in_progress -> passed
+-> failed +-> selfClaimed -> confirm_criterion -> formal pass

+-> blocked
+-> not_run(仅非必需标准)

| 状态 | 含义 | 是否需要证据 |
| pending | 尚未开始 | 否 |
| in_progress | 正在处理 | 否 |
| passed | 验证成功 | 是 |
| failed | 验证失败 | 是 |
| blocked | 当前环境无法验证 | 否 |
| not_run | 显式跳过(仅非必需) | 否 |

完成门禁

canComplete() 返回 { allowed: boolean, reason?: string }:

- 允许:所有必需标准均已正式 passed(非自评),或尚未锁定任何标准。
- 不允许:任一必需标准处于 pending、in_progress、failed、blocked 或 not_run。
- 不允许(自评):所有必需标准均已 passed,但部分为 selfClaimed=true (由 Agent 设定、尚未经 reviewer 确认)。reason 会指出有多少条等待 reviewer 确认。

事件溯源

引擎是事件源的。store 持有追加式事件列表:

- goal-acceptance/set — 锁定标准列表(含 role)
- goal-acceptance/task-plan — 锁定任务分解计划
- goal-acceptance/validate — 更新单条标准状态(含证据类型、自评标记)
- goal-acceptance/task-update — 更新关联任务状态
- goal-acceptance/amend — 初次锁定后追加标准

每次读取时引擎从 store 重放事件,从而实现:

- 持久化(文件、数据库、会话日志)
- 精确的状态恢复
- 全量决策审计轨迹

自定义 Store

为你的持久化后端实现 GoalAcceptanceStore:

import type { GoalAcceptanceStore, GoalAcceptanceEvent } from './src/plugin/engine/index.ts'

class MyDbStore implements GoalAcceptanceStore {
get events(): readonly GoalAcceptanceEvent[] {
// 按追加顺序返回所有事件 }

async append(event: GoalAcceptanceEvent): Promise<void> {
// 持久化事件 } }

四通路兼容性

| 能力 | dsh Cordis 插件 | CLI MCP server | Agent Plugin | OpenClaw 原生 |
| 模型工具 | 19 个(见 MCP 工具) | 19 个(见 MCP 工具) | 与 MCP 相同 | 与 MCP 相同(进程内) |
| 系统提示 / 技能 | policy:goal-acceptance | skills/ | skills/ | skills/ |
| 停止时强制 | 是(agent.steer(),依赖感知) | 否 | 否 | 否 |
| 跨客户端便携 | 否(仅 Harness) | 是(任意 MCP 客户端) | 是(任意 Agent Plugins 客户端) | 否(仅 OpenClaw) |
| 持久化状态 | dsh-session 日志 | $PLUGIN_DATA/goals/ | 与 MCP 相同 | 与 MCP 相同 |
| 双角色验证 | 是(role 参数) | 是(role 参数) | 是 | 是 |
| 类型化证据 | 是(evidence_type 参数) | 是(evidence_type 参数) | 是 | 是 |
| 任务分解计划 | 是(set_task_plan / get_task_plan) | 是(set_task_plan / get_task_plan) | 是 | 是 |
| 精简响应 | 否 | 是(verbose 参数) | 是 | 是 |
| 进程内调用(无 stdio) | 是 | 否 | 否 | 是 |

dsh Cordis 插件是唯一能强制 Agent 继续工作的变体。MCP、Agent Plugin 与
OpenClaw 原生变体依赖模型主动调用工具并遵循技能指引。

仓库布局

src/
├── cli-entry.ts # CLI 入口(打包为 dist/cli.js) ├── hook-entry.ts # Read hook(打包为 dist/hook.cjs) ├── framework/ # 脚手架框架(manifest、registry、CLI、wizard、 │ # mcp-runtime、hook-runtime、paths、cache) ├── plugin/ │ ├── manifest.ts # 身份唯一来源(name、tools、markers、config) │ ├── engine/ # 事件源状态机(零依赖) │ ├── goal-manager.ts # 多目标管理器 + store(所有通路共享) │ ├── tools.ts # 19 个 ToolDef │ ├── dsh-plugin.ts # Cordis 插件(service、tools、steer、prompt) │ ├── openclaw-plugin.ts # OpenClaw 原生插件 │ ├── openclaw-session-sync.ts # 将活动目标同步到 OpenClaw SessionEntry.goal │ ├── prompt.ts # dsh 系统提示指引 │ ├── invariant.ts # dsh session 不变量 │ └── targets/ # 22 个安装适配器 └── assets/ # SKILL.md + 8 个配套技能 + 封面图 tests/ # node --test 套件(engine、mcp、dsh、targets...) build.mjs # esbuild 打包 + 身份文件生成 dist/ # cli.js + hook.cjs + dsh-plugin.js(已提交) openclaw-dist/ # openclaw-plugin.js + package.json(已提交)

构建与测试

pnpm install
npm run verify # build → typecheck → node --test
node dist/cli.js --help

License

MIT
预览分享卡片长什么样 ↓cckyros/goal-acceptance
分享 · DeepSeek Harness Hub
cckyros/goal-acceptance

面向自主 AI Agent 的验收标准驱动目标完成机制。

这是你的仓库?认领条目

回到顶部