关于 oneshot
oneshot 是用于小型、边界明确变更的轻量工作流技能,包含简短规划、实现和验证。它默认直接提交,也可按策略或请求转入 PR 流程。
主要功能
- 01四阶段轻量工作流
- 02创建一页计划并在会话中实现
- 03按变更风险调整验证
- 04默认直接提交,可选择 PR
- 05通过事件记录可重放的流程决策
适用场景
- 01修复文档拼写或单处空值问题
- 02更新依赖版本或配置键
- 03实现无需子 Agent 的小型改动
MCP 相关
技能使用 Exarchos MCP 工作流与编排操作管理流程;选择 PR 路径时,通过 MCP 操作创建 PR,并自动检测和路由至 VCS 提供方。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lvlup-sw/ exarchos --skill oneshot安装后在 Claude Code 中输入/oneshot确认已加载。
附带文件references/choice-state.md
详细介绍
Oneshot 工作流技能
VCS 提供方
采取 synthesize 路径时,此技能会通过 Exarchos MCP 操作(create_pr、merge_pr 等)执行 VCS 操作。
这些操作会自动检测并路由到正确的 VCS 提供方(GitHub、GitLab、Azure DevOps)。
无需使用 gh/glab/az 命令——MCP 服务会处理提供方分派。
一种精简的四阶段工作流类型,适用于改动太小、不值得采用完整 feature 流程(plan → plan-review → delegate → review → synthesize → completed),但仍需要事件溯源审计能力和规划步骤的情况。该工作流默认直接提交,也可选择启用 PR 路径;两者之间的选择会在 implementing 结束时通过纯事件溯源守卫确定,而非启发式判断。
**如果你从未运行过 oneshot,请先阅读此处:**该工作流在
implementing结束时有一个选择状态。你最终进入completed(直接提交),还是转入synthesize(PR),取决于两个输入:初始化时设置的synthesisPolicy,以及用户是否在 implementing 期间发出了synthesize.requested事件。这两个输入都会持久化,决策可安全重放。
何时使用 oneshot
只有在以下条件全部满足时,才使用 oneshot:
- 改动范围明确——通常只涉及单个文件,或一组紧密关联的 2-3 个文件
- 无需派发子 Agent——工作可以轻松地在单次会话内完成实现和验证
- 无需设计文档——任务描述已清楚说明目标,一页计划足以提供必要支撑
- 无需两阶段审查——要么改动足够简单,可以直接提交;要么一次 PR 审查就足够
适合使用 oneshot 的具体示例:
- 修复 README 中的拼写错误
- 更新依赖版本
- 在一个函数中添加缺失的 null 检查
- 调整 CI 工作流 YAML
- 重命名所有引用到的配置键
- 添加一次性辅助脚本
- 可能保留也可能不保留的探索性试验
何时不要使用 oneshot
以下情况不要使用 oneshot——请改用完整的 feature 工作流(ideate):
- 涉及多个文件或模块的跨领域重构
- 适合通过子 Agent 分解来完成的多文件功能
- 需要探索设计或权衡多种方案的任何工作
- 需要 spec-review + quality-review(两阶段审查)的任何工作
- 需要与另一个 Agent 团队协调的任何工作
- 应分阶段合并的改动(堆叠式 PR)
- 任何你希望日后能查阅书面设计文档的工作
如果你开始使用 oneshot 后发现改动比预期更大,正确的做法是执行 cancel,然后使用 ideate 重新开始。
不要试图在过程中把 oneshot 扩展成 feature 工作流;两种工作手册的结构不同,你会与状态机周旋。
Synthesis 策略 — 三种选项
oneshot 工作流上的 synthesisPolicy 字段用于预先声明用户是否希望将变更转为 PR。它有三个可选值,并会持久化到 state.oneshot.synthesisPolicy:
| 策略 | 行为 | 适用场景 |
|---|---|---|
always | finalize 时始终从 implementing → synthesize 转换,不受事件影响。始终会创建 PR。 | 用户希望此工作流中的每项变更都有记录可查并经过审查,即使是小改动。 |
never | finalize 时始终从 implementing → completed 转换,不受事件影响。不会创建 PR——提交会直接进入当前分支。 | 用户正在迭代个人或临时项目,并明确选择不创建 PR。 |
on-request (默认) | 默认直接提交。用户可以在 implementing 阶段通过调用 request_synthesize 选择创建 PR;如果 finalize 时流中存在任何 synthesize.requested 事件,工作流就会转到 synthesize,而不是 completed。 | 常见情况:默认直接提交,但如果用户看到差异后改变主意,仍可选择创建 PR。 |
默认值为 on-request,因为它最不容易让人意外:用户可以先走轻量流程,直到明确要求更繁重的流程。
策略优先于事件。 如果设置了 synthesisPolicy: 'never',而流中又出现了 synthesize.requested 事件(例如,用户以为工作流的策略是 on-request,于是调用了该操作),守卫仍会将工作流导向 completed。策略是用户声明的意图,优先于运行时信号。
生命周期
plan ──────► implementing ──┬── [synthesisOptedOut] ──► completed
│
└── [synthesisOptedIn] ──► synthesize ──► completed
共有四个阶段。implementing 之后的分支是 UML 选择状态,由两个互斥的 HSM 转换实现,守卫条件是纯函数,仅取决于 state.oneshot.synthesisPolicy 和 synthesize.requested 事件的数量。
| 阶段 | 执行内容 | 退出条件 |
|---|---|---|
plan | 制定轻量的一页计划:目标、方法、需要修改的文件、需要添加的测试。不编写设计文档。不分派子 Agent。 | 设置 artifacts.plan → 转到 implementing |
implementing | 在会话中循环推进,根据风险调整验证力度。默认采用低级别验证(静态分析即可);影响范围更大的变更会在 check_test_adequacy 终止探测的约束下,添加覆盖变更行为的测试(先实现后测试)。随做随提交。 | 测试通过 + 类型检查无误 + 调用 finalize_oneshot |
synthesize | 仅当 synthesisOptedIn 为 true 时才会进入。交由现有的 synthesis 流程处理——参见 @skills/synthesize/SKILL.md。通过 exarchos_orchestrate({ action: "create_pr" }) 创建 PR,启用自动合并,并遵循 CI 门禁。 | PR 合并 → completed |
completed | 终态。对于直接提交流程,提交已在分支上——无需进一步操作。对于 synthesize 流程,PR 合并事件会终止工作流。 | — |
与其他所有工作流类型一样,也可以通过通用取消转换,从任意阶段进入 cancelled。
分步说明
步骤 1 — 初始化
调用 exarchos_workflow,参数为 action: 'init'、workflowType: 'oneshot',以及可选的 synthesisPolicy:
exarchos:exarchos_workflow({
action: "init",
featureId: "fix-readme-typo",
workflowType: "oneshot",
synthesisPolicy: "on-request" // optional — defaults to 'on-request'
})
如果用户已明确表示(“我要为此创建一个 PR”),则传入 synthesisPolicy: "always"。如果用户已明确表示(“不要创建 PR,直接提交就好”),则传入 synthesisPolicy: "never"。否则,省略该字段并使用默认值 on-request——之后在 implementing 阶段随时可以升级。
init 会返回新的工作流状态;工作流会进入 plan 阶段。
第 2 步——规划阶段
编写一页计划。保持轻量——不需要设计文档、并行化分析,也不需要将工作拆分为 N 个任务。计划应在每项 5-10 行内回答以下四个问题:
- 目标——用户想要完成什么?
- 方法——用一句话说明实现策略。
- 文件——会修改哪些文件?(通常为 1-5 个)
- 测试——会添加哪些测试用例?(只列名称,不作描述)
保存计划,然后转入 implementing。字段修改与阶段修改是分开的操作:update 用于写入计划产物(phase 是 update 无法触碰的保留字段),然后由 transition 推进阶段——守卫会读取最新状态,因此 oneshot-plan-set 守卫评估前,计划会先保存:
exarchos:exarchos_workflow({
action: "update",
featureId: "fix-readme-typo",
updates: {
"artifacts.plan": "<plan text>",
"oneshot.planSummary": "<one-line summary>"
}
})
exarchos:exarchos_workflow({
action: "transition",
featureId: "fix-readme-typo",
target: "implementing"
})
计划应放在 artifacts.plan 中,以与 feature 工作流保持一致;供人阅读的单行摘要应放在 oneshot.planSummary 中,以便在流水线视图中显示。只有 artifacts.plan 会由 oneshot-plan-set 守卫强制检查——planSummary 是可选的流水线视图标签,不能替代真正的计划产物。
第 3 步——实施阶段
在会话中循环执行,根据变更的风险程度选择相应的验证方式(参见 @skills/_shared/references/verification.md 中的分级)。oneshot 默认采用低级别——对于简单修复,静态分析就足够了。如果变更涉及影响范围较大的部分(schema/type/API/共享契约),或跨越 I/O 边界,则属于更高级别的任务:通过测试覆盖新增或变更的行为(先实现再补测试也可以),并预期 check_test_adequacy 杀手探针会拒绝那些实际无法失败的测试。
对于计划中的每项高级别行为:
- 实现该行为。
- 添加该级别要求的测试(针对变更范围的测试;高级别还需在边界处添加集成测试),测试名称采用
Method_Scenario_Outcome格式。 - 在测试保持通过的前提下进行重构。
可选择启用逐项行为的红绿测试流程,但这只是明确选择的选项,不是要求。
将每项逻辑变更作为一个独立的原子提交。不要把多个互不相关的变更合并到一次提交中——保持提交原子性尤为重要,oneshot 中没有单独的审查阶段来发现捆绑的变更。
oneshot 中不会派发子 Agent。主 Agent 会直接完成工作。没有单独的审查阶段。质量由按级别进行的验证来保障(静态分析;高于低级别时还会使用 check_test_adequacy 杀手探针),以及(如果用户选择启用)综合 PR 审查。
工作流中途:选择创建 PR
如果用户在 plan 或 implementing 阶段的任何时候决定还是想要 PR(策略为 on-request,即默认值),可以调用 request_synthesize 编排操作来选择创建 PR:
exarchos:exarchos_orchestrate({
action: "request_synthesize",
featureId: "fix-readme-typo",
reason: "user requested review of the parser changes"
})
触发条件取决于对话,而不是某个神奇的关键词。 留意以下表达:
- “其实,我们还是为这个创建一个 PR 吧”
- “合并之前我想先让人审查一下”
- “把这个做成 PR”
- “让大家都看看”
- “综合处理这个”
听到上述任何表达时,立即调用 request_synthesize。处理程序会向工作流的事件流追加一个 synthesize.requested 事件;synthesisOptedIn 守卫会在 finalize 时读取该事件流,并据此路由。
request_synthesize 在 plan 和 implementing 阶段都可调用——一旦确定想走 PR 路径,就可以随时调用,即使 implementing 尚未开始。终止阶段(synthesize、completed、cancelled)不接受此操作。
重复调用在路由方面幂等,但在事件方面不幂等:每次调用都会追加一个新的 synthesize.requested 事件,但守卫会将任何大于等于 1 的数量视为“已选择”,因此无论调用一次还是五次,路由决策都相同。事件流会保留每个重复事件以供审计。
调用 request_synthesize 不会转换阶段。工作流会保持在当前阶段。只有在第 4 步调用 finalize_oneshot 时,才会执行此决策。
第 4 步 — Finalize(决策点)
当实现循环结束后——测试通过、类型检查无误、所有提交均已完成——调用 finalize_oneshot 以确定选择结果:
exarchos:exarchos_orchestrate({
action: "finalize_oneshot",
featureId: "fix-readme-typo"
})
处理程序会:
- 读取当前状态,并验证
workflowType === 'oneshot'且phase === 'implementing'。 - 从事件存储中填充
_events,确保守卫看到的视图与 HSM 在实际转换期间看到的视图一致。 - 根据状态评估
guards.synthesisOptedIn。该守卫会检查state.oneshot.synthesisPolicy和_events数组。 - 调用
handleSet,并传入解析后的目标阶段(synthesize或completed)。HSM 会在转换边界重新评估守卫,因此可以安全地捕获读取与转换之间的任何竞争情况。
可能的结果:
synthesisPolicy | 是否存在 synthesize.requested 事件? | 解析后的目标阶段 | 路径 |
|---|---|---|---|
always | (任意) | synthesize | PR 路径 |
never | (任意) | completed | 直接提交路径 |
on-request(默认) | 是 | synthesize | PR 路径 |
on-request(默认) | 否 | completed | 直接提交路径 |
第 5a 步 — 直接提交路径(终止)
如果 finalize 解析出的目标阶段是 completed,则流程已完成。实现期间所做的提交已经位于当前分支上。如果尚未推送,请推送这些提交:
git push
工作流现在处于 completed 阶段,不会显示在默认流水线视图中。报告完成情况:
## Oneshot Complete (direct-commit)
Workflow: <featureId>
Plan: <one-line summary>
Tests added: N
Commits: <hash list>
Path: direct-commit
第 5b 步 — Synthesize 路径
如果 finalize 解析出的目标阶段是 synthesize,则交接给标准的综合流程——参见 @skills/synthesize/SKILL.md。此流程适用与 feature 工作流相同的 prepare_synthesis / validate_pr_body / create_pr 机制,其中包括 prepare_synthesis 必需的 repoRoot:传入你进行提交的仓库的绝对路径,因为每个就绪检查环节都会在该路径下运行,而不是在服务自身的工作目录中运行。PR 合并后,工作流会通过现有的 mergeVerified 守卫从 synthesize 转换到 completed,与其他所有工作流类型相同。
选择在 oneshot 工作流中进行 synthesize 时,无需运行 delegate 或 review。oneshot 操作手册中不存在这些阶段。PR 审查就是唯一的审查。报告完成情况:
## Oneshot Complete (synthesize)
Workflow: <featureId>
PR: <url>
Tests: X pass | Build: 0 errors
Path: synthesize → PR review → merge
调用示例
示例 A — 直接提交(默认 on-request 策略,未选择创建 PR)
User: "Quick fix — there's a typo in the README, 'recieve' should be 'receive'.
Use oneshot."
Agent:
1. exarchos_workflow init { featureId: "fix-readme-typo", workflowType: "oneshot" }
→ workflow created in 'plan' phase, synthesisPolicy defaults to 'on-request'
2. Produces a 4-line plan: goal=fix typo, approach=sed, files=[README.md],
tests=[readme has no occurrence of 'recieve']
3. exarchos_workflow update {
featureId: "fix-readme-typo",
phase: "implementing", // top-level
updates: {
"artifacts.plan": "...",
"oneshot.planSummary": "..."
}
}
4. edits README, fixes typo (low tier — a docs one-liner; static analysis
suffices, no test-first ceremony)
5. verifies: greps README for 'recieve' → 0 matches
6. git commit -m "docs: fix 'recieve' typo in README"
7. exarchos_orchestrate finalize_oneshot { featureId: "fix-readme-typo" }
→ guard sees policy='on-request' + no synthesize.requested event
→ resolves to 'completed'
8. git push
"Done. Workflow completed via direct-commit path."
示例 B — 实现过程中选择创建 PR(on-request → 用户改变主意)
User: "Add input validation to the parseConfig helper. Oneshot."
Agent:
1. exarchos_workflow init { workflowType: "oneshot" }
→ 'plan' phase, default 'on-request'
2. plans (goal: validate input, files: [parser.ts, parser.test.ts])
3. transitions to 'implementing'
4. adds the null-input validation to parseConfig
5. adds a test for the null-input case (test-after)
6. refactors: extracts validateInput helper (tests stay green)
7. commits
User: "Actually, this is touching the parser — I want a review on it before
it lands."
Agent:
8. exarchos_orchestrate request_synthesize {
featureId, reason: "user requested review of parser changes"
}
→ appends synthesize.requested event
9. exarchos_orchestrate finalize_oneshot { featureId }
→ guard sees policy='on-request' + 1 synthesize.requested event
→ resolves to 'synthesize'
10. hands off to @skills/synthesize/SKILL.md → prepare_synthesis →
validate_pr_body → create_pr → merge
示例 C — synthesisPolicy: 'always'(必须创建 PR)
User: "I want a PR for any change to the auth module, even small ones.
Use oneshot but always make a PR."
Agent:
1. exarchos_workflow init {
workflowType: "oneshot",
synthesisPolicy: "always"
}
2-7. plan + implement + verify + commits, identical to Example A
8. exarchos_orchestrate finalize_oneshot { featureId }
→ guard sees policy='always' (short-circuits — no event check needed)
→ resolves to 'synthesize'
9. synthesis flow → PR
状态管理
在工作流状态的 oneshot 键下跟踪 oneshot 专属状态:
exarchos:exarchos_workflow({
action: "update",
featureId: "<id>",
updates: {
"oneshot": {
"synthesisPolicy": "on-request",
"planSummary": "Fix off-by-one in pagination helper"
}
}
})
synthesisPolicy 字段为可选项,根据 servers/exarchos-mcp/src/workflow/schemas.ts 中的架构,默认值为 'on-request'。如果用户已表达偏好,建议显式设置该字段。
阶段转换与守卫条件
oneshot 的完整转换表请参阅
@skills/checkpoint/references/phase-transitions.md。
**注意:**引擎的
exarchos_workflow describe playbook="oneshot"输出以及hsm-definitions.ts中的 HSM 定义,是转换行为的 权威来源。phase-transitions.md是可能存在偏差的 文字说明参考——出现差异时,以引擎的describe输出为准。
oneshot 快速参考:
| From | To | Guard |
|---|---|---|
plan | implementing | oneshotPlanSet(要求 artifacts.plan 非空) |
implementing | synthesize | synthesisOptedIn |
implementing | completed | synthesisOptedOut |
synthesize | completed | mergeVerified |
| (any) | cancelled | 通用——始终允许 |
synthesisOptedIn 和 synthesisOptedOut 是由
state.oneshot.synthesisPolicy 和 state._events 决定的纯函数。在所有 4 种有意义的组合中,它们互斥——always 和 never
各自对应一种结果(忽略事件标志),而 on-request 则根据是否存在
synthesize.requested 事件分支。任意时刻都恰有一个守卫条件返回 true。
架构发现
使用 exarchos_workflow({ action: "describe", actions: ["init", "update"] })
查询参数架构(包括 synthesisPolicy 枚举),并使用
exarchos_workflow({ action: "describe", playbook: "oneshot" }) 查询
阶段转换、守卫名称和 playbook 说明。使用
exarchos_orchestrate({ action: "describe", actions: ["request_synthesize", "finalize_oneshot"] })
查询 orchestrate 操作架构。
验证程度应与风险相匹配
@skills/_shared/references/verification.md 中的验证阶梯适用于
oneshot。oneshot 默认采用低成本(低)级别——一行修复或配置
调整通常只需静态分析(类型检查 + lint),无需先写测试的流程——除非
风险信号另有提示。具体而言:
- 低风险更改(仅文档/配置/重命名,影响范围几乎为零)只需 通过静态分析;仅当行为不明显时才添加有针对性的测试。
- 如果更改涉及影响范围较大的部分(架构/类型/API/共享契约,
或跨越 I/O 边界),则不属于低级别任务:应通过测试覆盖
新增或更改的行为(先写测试也可以),并预期
check_test_adequacy杀手探针会标记出实际上无法失败的测试。 - 提交应保持原子性——每个提交只包含一个逻辑更改,无论级别如何。
oneshot 的一个常见误区是认为所有内容都“只改一行”,从而完全跳过 验证。对于超出低级别的任务,应避免这样做。oneshot 的意义在于以 恰当的成本确保可审计性——既不是零验证,也不是为微小编辑走完整的功能开发流程。
反模式
| 不要 | 应该这样做 |
|---|---|
| 跳过计划阶段(“这很明显”) | 仍然写下四行计划——这是未来的你会查阅的记录 |
| 对简单的一行改动也走完整的红-绿-重构流程 | 根据风险选择验证方式:低风险层级依靠静态分析;影响范围更大的改动还要添加覆盖变更行为的测试 |
| 因为“这是一次性操作”而完全跳过验证 | 即使是低风险层级,也必须通过静态分析;影响范围更大的改动仍需添加覆盖变更行为的测试 |
用 oneshot 处理涉及多个文件的重构 | 使用 ideate 和完整的功能工作流 |
| 尝试在过程中把一次性操作扩展成功能工作流 | 取消并使用 ideate 重新开始 |
不先了解用户的意图就调用 request_synthesize | 等用户提出创建 PR 后再调用 |
| 因为“这是一次性操作”,就在一个提交中捆绑无关改动 | 保持提交原子性——没有评审阶段来发现捆绑的改动 |
忘记在最后调用 finalize_oneshot | 否则工作流会一直停留在 implementing 状态——请明确调用 |
完成标准
- 已调用
exarchos_workflow init,并设置workflowType: "oneshot" - 一页计划已保存到
artifacts.plan - 阶段已切换到
implementing - 所有计划中的行为都已实现,并按照对应风险层级完成验证,且使用原子提交
- 已调用
finalize_oneshot,并解析为completed或synthesize - 如果采用直接提交路径:提交已推送
- 如果采用合成路径:已通过
@skills/synthesize/SKILL.md创建并合并 PR