oneshot-workflow
Original:🇺🇸 English
Translated
Lightweight workflow for straightforward changes — plan → implement → optional PR. Direct-commit by default; synthesize is opt-in via synthesisPolicy or a runtime request_synthesize event. Use for trivial fixes, config tweaks, single-file changes, or exploratory work that doesn't warrant subagent dispatch or two-stage review. Triggers: 'oneshot', 'quick fix', 'small change', or /oneshot.
13installs
Sourcelvlup-sw/exarchos
Added on
NPX Install
npx skill4agent add lvlup-sw/exarchos oneshot-workflowTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Oneshot Workflow Skill
VCS Provider
This skill uses VCS operations through Exarchos MCP actions (, , etc.) when the synthesize path is taken.
These actions automatically detect and route to the correct VCS provider (GitHub, GitLab, Azure DevOps).
No // commands needed — the MCP server handles provider dispatch.
create_prmerge_prghglabazA lean, four-phase workflow type for changes that are too small to justify the
full flow ()
but still deserve event-sourced auditability and a planning step. The workflow is
direct-commit by default with an opt-in PR path; the choice between the
two is resolved at the end of via a pure event-sourced guard,
not a heuristic.
featureideate → plan → plan-review → delegate → review → synthesize → completedimplementingRead this first if you have never run a oneshot: the workflow has a choice state at the end of. Whether you land onimplementing(direct commit) or transition throughcompleted(PR) is decided by two inputs: thesynthesizeset at init, and whether the user emitted asynthesisPolicyevent during implementing. Both inputs are persisted; the decision is replay-safe.synthesize.requested
When to use oneshot
Reach for oneshot when all of the following are true:
- The change is bounded — typically a single file, or a tightly-coupled cluster of 2-3 files
- No subagent dispatch is needed — the work fits comfortably in one TDD loop in a single session
- No design document is required — the goal is obvious from the task description, and a one-page plan is enough scaffolding
- No two-stage review is required — either the change is trivial enough that direct-commit is acceptable, or a single PR review will suffice
Concrete examples that fit oneshot:
- Fixing a typo in a README
- Bumping a dependency version
- Adding a missing null-check in one function
- Tweaking a CI workflow YAML
- Renaming a config key everywhere it's referenced
- Adding a one-off helper script
- Exploratory spikes that may or may not be kept
When NOT to use oneshot
Do not use oneshot for any of the following — use the full
workflow instead ():
feature/ideate- Cross-cutting refactors that touch many files or modules
- Multi-file features that benefit from subagent decomposition
- Anything that needs design exploration or competing approaches weighed
- Anything that needs spec-review + quality-review (two-stage)
- Anything that needs to coordinate with another agent team
- Changes that should land in stages (stacked PRs)
- Anything where you'd want a written design doc to look back at
If you start a oneshot and discover the change is bigger than expected, the
right move is and restart with .
Don't try to grow a oneshot into a feature workflow mid-stream; the
playbooks have different shapes and you'll fight the state machine.
/cancel/ideateSynthesis policy — three options
The field on a oneshot workflow declares the user's
intent up front about whether the change should be turned into a PR. It
takes one of three values, persisted on :
synthesisPolicystate.oneshot.synthesisPolicy| Policy | Behavior | When to use |
|---|---|---|
| Always transition | The user wants a paper trail / review for every change in this workflow, even small ones. |
| Always transition | The user is iterating on personal/scratch work and explicitly opts out of PRs. |
| Direct-commit by default. The user can opt in to a PR mid-implementing by calling | The common case: start with the assumption of direct-commit, but leave the door open for the user to change their mind once they see the diff. |
The default is because it's the least surprising: the user
gets the lightweight path until they explicitly ask for the heavy one.
on-requestPolicy wins over event. If is set and a
event is somehow on the stream (e.g. the user
called the action on a workflow they thought was ), the
guard still routes to . Policy is the user's declared intent
and overrides runtime signal.
synthesisPolicy: 'never'synthesize.requestedon-requestcompletedLifecycle
text
plan ──────► implementing ──┬── [synthesisOptedOut] ──► completed
│
└── [synthesisOptedIn] ──► synthesize ──► completedFour phases. The fork after is a UML choice state,
implemented via two mutually-exclusive HSM transitions whose guards are
pure functions of and the
event count.
implementingstate.oneshot.synthesisPolicysynthesize.requested| Phase | What happens | Exit criteria |
|---|---|---|
| Lightweight one-page plan: goal, approach, files to touch, tests to add. No design doc. No subagent dispatch. | |
| In-session TDD loop. Write a failing test, make it pass, refactor. Commit as you go. The TDD iron law applies — no production code without a failing test first. | Tests pass + typecheck clean + finalize_oneshot called |
| Reached only when | PR merged → |
| Terminal. For direct-commit path, commits are already on the branch — there's nothing more to do. For synthesize path, the PR merge event terminates the workflow. | — |
cancelledStep-by-step
Step 1 — Init
Call with , ,
and an optional :
exarchos_workflowaction: 'init'workflowType: 'oneshot'synthesisPolicytypescript
mcp__exarchos__exarchos_workflow({
action: "init",
featureId: "fix-readme-typo",
workflowType: "oneshot",
synthesisPolicy: "on-request" // optional — defaults to 'on-request'
})If the user has been clear up front ("I want a PR for this"), pass
. If they've been clear ("don't open a PR,
just commit it"), pass . Otherwise, omit the
field and rely on the default — you can always escalate
later in the implementing phase.
synthesisPolicy: "always"synthesisPolicy: "never"on-requestThe init returns the new workflow state; the workflow lands in .
planStep 2 — Plan phase
Produce a one-page plan. This is intentionally lightweight — no design
doc, no parallelization analysis, no decomposition into N tasks. The
plan should answer four questions in 5-10 lines each:
- Goal — what is the user trying to accomplish?
- Approach — what's the one-line implementation strategy?
- Files — which files will be touched? (1-5 typically)
- Tests — which test cases will be added? (named, not described)
Persist the plan and transition to in a single set call.
is a top-level argument of , not a field inside :
implementingphasesetupdatestypescript
mcp__exarchos__exarchos_workflow({
action: "set",
featureId: "fix-readme-typo",
phase: "implementing",
updates: {
"artifacts.plan": "<plan text>",
"oneshot.planSummary": "<one-line summary>"
}
})The plan goes on for parity with the workflow;
the human-readable one-liner goes on for the
pipeline view. Only is enforced by the
guard — is an optional pipeline-view
label and is not a substitute for a real plan artifact.
artifacts.planfeatureoneshot.planSummaryartifacts.planoneshot-plan-setplanSummaryStep 3 — Implementing phase
Run an in-session TDD loop. Same iron law as every other workflow:
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
For each behavior in the plan:
- [RED] Write a failing test. Run the test. Confirm it fails for the right reason.
- [GREEN] Write the minimum production code to make the test pass. Run the test. Confirm it passes.
- [REFACTOR] Clean up while keeping the test green.
Commit each red-green-refactor cycle as a single commit. Do not batch
multiple unrelated changes into one commit — keeping commits atomic
matters even more in oneshot, where there's no separate review phase
to catch bundled changes.
There is no subagent dispatch in oneshot. The main agent does the
work directly. There is no separate review phase. Quality is
maintained by the TDD loop and (if the user opts in) the synthesize PR
review.
Mid-workflow: opting in to a PR
If at any point during or the user decides they
want a PR after all (policy is , default), they can opt in
by calling the orchestrate action:
planimplementingon-requestrequest_synthesizetypescript
mcp__exarchos__exarchos_orchestrate({
action: "request_synthesize",
featureId: "fix-readme-typo",
reason: "user requested review of the parser changes"
})The trigger for this is conversational, not a magic keyword. Listen
for phrases like:
- "actually, let's open a PR for this"
- "I want a review on this before it lands"
- "make this a PR"
- "let's get eyes on this"
- "synthesize this"
When you hear any of those, call immediately. The
handler appends a event to the workflow's event
stream; the guard reads the stream at finalize and
routes accordingly.
request_synthesizesynthesize.requestedsynthesisOptedInrequest_synthesizeplanimplementingimplementingsynthesizecompletedcancelledDuplicate calls are routing-idempotent but not event-idempotent:
each call appends a new event, but the guard
treats any count >= 1 as "opted in", so the routing decision is the
same whether you call once or five times. The event stream will
contain each duplicate for audit purposes.
synthesize.requestedCalling does not transition the phase. The
workflow stays in its current phase. The decision is only acted on
when you call in step 4.
request_synthesizefinalize_oneshotStep 4 — Finalize (the choice point)
When the implementing loop is done — tests pass, typecheck clean, all
commits made — call to resolve the choice state:
finalize_oneshottypescript
mcp__exarchos__exarchos_orchestrate({
action: "finalize_oneshot",
featureId: "fix-readme-typo"
})The handler:
- Reads the current state and verifies and
workflowType === 'oneshot'.phase === 'implementing' - Hydrates from the event store so the guard sees the same view the HSM will see during the actual transition.
_events - Evaluates against the state. The guard inspects
guards.synthesisOptedInand thestate.oneshot.synthesisPolicyarray._events - Calls with the resolved target phase (
handleSetorsynthesize). The HSM re-evaluates the guard at the transition boundary, so any race between the read and the transition is caught safely.completed
Possible outcomes:
| | Resolved target | Path |
|---|---|---|---|
| (any) | | PR path |
| (any) | | direct-commit path |
| yes | | PR path |
| no | | direct-commit path |
Step 5a — Direct-commit path (terminal)
If finalize resolved to , you're done. The commits made
during implementing are already on the current branch. Push them if
they aren't already pushed:
completedbash
git pushThe workflow is now in and will not appear in the default
pipeline view.
completedStep 5b — Synthesize path
If finalize resolved to , hand off to the standard synthesis
flow — see . The same /
/ machinery used by the
workflow applies. After the PR merges, the workflow transitions
via the existing guard, same as
every other workflow type.
synthesize@skills/synthesis/SKILL.mdprepare_synthesisvalidate_pr_bodycreate_prfeaturesynthesize → completedmergeVerifiedYou do not need to run or
for an opt-in oneshot synthesize. Those phases
do not exist in the oneshot playbook. The PR review is the only review.
/delegate/reviewExample invocations
Example A — Direct-commit (default on-request
policy, no opt-in)
on-requesttext
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 set {
featureId: "fix-readme-typo",
phase: "implementing", // top-level
updates: {
"artifacts.plan": "...",
"oneshot.planSummary": "..."
}
}
4. [RED] writes test that greps README for 'recieve' and expects 0 matches
— fails (1 match exists)
5. [GREEN] edits README, fixes typo
— test passes
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."Example B — Mid-implementing opt-in (on-request
→ user changes mind)
on-requesttext
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. [RED] writes test for null-input case
5. [GREEN] adds null check
6. [REFACTOR] extracts validateInput helper
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/synthesis/SKILL.md → prepare_synthesis →
validate_pr_body → create_pr → mergeExample C — synthesisPolicy: 'always'
(PR mandatory)
synthesisPolicy: 'always'text
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 + TDD + 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 → PRState management
Track oneshot-specific state under the key on the workflow state:
oneshottypescript
mcp__exarchos__exarchos_workflow({
action: "set",
featureId: "<id>",
updates: {
"oneshot": {
"synthesisPolicy": "on-request",
"planSummary": "Fix off-by-one in pagination helper"
}
}
})The field is optional and defaults to per
the schema in . Setting it
explicitly is recommended when the user has stated a preference.
synthesisPolicy'on-request'servers/exarchos-mcp/src/workflow/schemas.tsPhase Transitions and Guards
For the full transition table for oneshot, consult
.
@skills/workflow-state/references/phase-transitions.mdNote: The engine'soutput and the HSM definitions inexarchos_workflow describe playbook="oneshot"are the canonical sources for transition behavior.hsm-definitions.tsis a prose reference that can drift — when discrepancies arise, prefer enginephase-transitions.mdoutput.describe
Quick reference for oneshot:
| From | To | Guard |
|---|---|---|
| | |
| | |
| | |
| | |
| (any) | | universal — always allowed |
synthesisOptedInsynthesisOptedOutstate.oneshot.synthesisPolicystate._eventsalwaysneveron-requestsynthesize.requestedSchema discovery
Use
for parameter schemas (including the enum) and
for the
phase transitions, guard names, and playbook prose. Use
for the orchestrate action schemas.
exarchos_workflow({ action: "describe", actions: ["init", "set"] })synthesisPolicyexarchos_workflow({ action: "describe", playbook: "oneshot" })exarchos_orchestrate({ action: "describe", actions: ["request_synthesize", "finalize_oneshot"] })TDD is still mandatory
The iron law from applies to oneshot. There is no
exemption for "small" changes. Specifically:
@rules/tdd.md- Every behavior change starts with a failing test
- Every test must fail before its implementation is written
- Tests must be run after each change to verify state
- Commits stay atomic — one logical change per commit
The temptation in a oneshot is to skip the test "because it's just one
line". Resist that. The test is what makes the change auditable, and
auditability is the entire reason oneshot exists alongside the lighter
"bypass workflows entirely" path.
Anti-patterns
| Don't | Do Instead |
|---|---|
| Skip the plan phase ("it's obvious") | Write the four-line plan anyway — it's the artifact future-you reads |
| Skip the TDD loop in implementing | Always RED → GREEN → REFACTOR, even for one-liners |
| Use oneshot for multi-file refactors | Use |
| Try to grow a oneshot into a feature workflow mid-stream | Cancel and restart with |
Call | Wait for the user to ask for a PR, then call it |
| Bundle unrelated changes into one commit "since it's a oneshot" | Keep commits atomic — there's no review phase to catch bundling |
Forget to call | The workflow stays in |
Completion criteria
- called with
exarchos_workflow initworkflowType: "oneshot" - One-page plan persisted to
artifacts.plan - Phase transitioned to
implementing - All planned behaviors implemented via TDD with atomic commits
- called and resolved to either
finalize_oneshotorcompletedsynthesize - If direct-commit path: commits pushed
- If synthesize path: PR created via and merged
@skills/synthesis/SKILL.md