About aop-writer
aop-writer is a skill for drafting and revising Duvo Agent operating procedures (AOPs), aimed at people configuring business automation. It structures instructions as GOAL, STEPS, and optional NOTES, with each AOP covering one case from start to finish.
Key features
- 01Uses the canonical AOP structure
- 02Frames procedures around one case
- 03Defines branch rules and terminal actions
- 04Places approval and error handling in steps
- 05Flags signals to split multiple Agents
Use cases
- 01Draft an Agent procedure from a business brief
- 02Revise AOP steps and decision rules
- 03Add human approval for high-stakes actions
- 04Check a procedure for missing terminal states
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ duvoai/ skills --skill aop-writerAfter installing, type/aop-writerin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
agent.mdreferences/aop-examples.mdaop-structure.mdaop-voice.mdcase-lifecycle.mdDetails
From the project READMEAOP Writer
What is Duvo?
Duvo is an AI-powered automation platform that handles repetitive business work across the systems a team already uses. Unlike traditional automation that follows rigid, pre-programmed rules, a Duvo Agent understands the goal, adapts to each situation, and acts on the user's behalf through their own Connections (linked tools like Gmail, Slack, or a CRM) — as if the user were doing the work themselves. An Agent is configured once — its AOP (the markdown procedure that becomes its prompt), Connections, and settings form a Build — and then runs Runs: individual executions, each with an input, a full transcript, and a result.
What an AOP is in Duvo
An AOP is the instruction document attached to an Agent. At Run-start time it is concatenated into the Agent's prompt, so its quality directly determines how the Agent behaves on every Run — against real Connections, with real escalation consequences. You are not writing documentation for a human reader; you are writing operational instructions that an LLM-driven Agent will execute on live data.
Treat that downstream effect as the constraint on every word you write.
The single most important rule
An AOP is designed around processing ONE case/item from start to finish — all decision branches, all error handling, all terminal states, in one document. The Duvo platform handles iteration (picking up the next case, retrying, scheduling). Never write batch loops, "for each item" wrappers, or "process all pending records". The AOP describes what to do with a single case, end to end.
Canonical structure
Every AOP uses the same three-section markdown shape (see references/aop-structure.md for the full template):
# GOAL— one sentence describing what the Agent does on a single case and the expected outcome.# STEPS— a numbered list of imperative actions. Inline everything that belongs to a single step (data formats, decision criteria, early returns, error handling, handover or completion conditions) into that step.# NOTES(optional) — only for genuinely cross-cutting concerns that don't belong to a single step (timezone conventions, naming patterns). Omit it otherwise.
Do not create separate PREREQUISITES, ERROR HANDLING, DATA HANDLING, ESCALATION, or TRIGGER sections. Inline those concerns into the step where they apply.
Voice
Outcome-focused, transparent, written for a non-engineer ops manager. Use Duvo terminology (Agent, Run, AOP, Connection — not assignment, task, job, integration). Imperative steps. Concrete thresholds, not fuzzy adverbs. See references/aop-voice.md for the full rules and worked examples.
Patterns that produce excellent AOPs
A great AOP weaves these patterns into the # STEPS section.
-
Reference tools by Connection name. "Use Gmail to send the response." "Search Google Sheets for the customer record." This tells the runtime Agent which Connection (and therefore which tool) to use.
-
Inline decision criteria with concrete thresholds. Replace "use your judgment" with explicit
if … then …rules. "If the amount exceeds $5,000, escalate." "If the supplier has had >3 late deliveries in the past year, note this as leverage." -
Inline early returns and error handling with
If [condition]: [action]. Example: "Ifinitial_postpone_doneis NOT present in the case data: callupdate_caseto set it, then callpostpone_casewith1d, and exit." -
Human-in-the-loop checkpoints for high-stakes actions. "If the contract value exceeds $100,000: use Human in the loop to get approval before sending." Make HITL a first-class step on any branch where a wrong action would be costly to reverse, not an afterthought.
-
The postpone-then-retry idiom for SLAs and waiting periods. On first pickup, set a flag on the case and
postpone_casewith the wait duration; on second pickup, do the real work. This is how an AOP expresses "wait N days then act" without a separate Agent per stage. Seereferences/case-lifecycle.md. -
Terminal closure on every branch. For queue-consuming Agents, every branch of the AOP must end with
complete_case,fail_case,postpone_case, orrequest_handover. Arequest_handoverbranch must also @-mention its target Agent at the handoff step (e.g. "hand over to @Billing Specialist") — the mention is what configures the handover, so naming the tool in prose alone hands off nothing. For standalone Agents, every branch must end with a clear terminal action (send the email, save the row, post the result). Cases left in an ambiguous state are the #1 failure mode.
Case lifecycle (queue-driven Agents)
If the Agent is a producer, consumer, or producer+consumer (it has the case-queue-producer or case-queue-consumer Connection), the AOP must reference the case lifecycle tools by name in the step where they apply:
claim_case,update_case,postpone_case,complete_case,fail_caseadd_cases,list_cases(producers)request_handover(when the Agent passes the case to a different Agent — name the target as an@Agentmention at the handoff step, not in prose; the mention is what makes the handover work)
Read references/case-lifecycle.md for the per-tool contract, the postpone-then-retry idiom, and the handover-vs-terminality rule before writing a queue-driven AOP.
If the request gives no signal about queues, cases, or handovers, write a standalone-Agent AOP and skip the lifecycle tools.
Anti-patterns — reject and rewrite
- Vague outcomes ("handle the request appropriately"). Replace with a concrete success condition.
- No decision criteria ("use your best judgment"). Replace with explicit thresholds.
- Batch / iteration logic ("for each pending invoice, do X"). The platform iterates. Rewrite as a single-case AOP.
- Missing terminal closure. For queue Agents, every branch must end in
complete_case/fail_case/postpone_case/request_handover. For standalone Agents, every branch must end in a concrete action. - Walls of text. Use numbered steps with a blank line between them. Two-to-four-sentence paragraphs inside a step.
- Hardcoded team data (specific supplier names, dollar thresholds tied to one team, individual people's email addresses) embedded in the AOP body. These belong in Files or as Setup inputs, not in the AOP.
- Internal jargon ("API call", "webhook", "endpoint"). Speak in business actions; the Agent chooses the tool call.
- Steps that say "how" instead of "what" ("call
create_orderwith body=…"). Steps describe the business action; the Agent figures out the tool call. - Separate
PREREQUISITES/ERROR HANDLING/ESCALATION/DATA HANDLINGsections. Inline them into the relevant step. - One AOP doing the work of three. If the steps cross connection domains and span distinct cadences (e.g., real-time inbox scan and a 7-day reminder cycle) and have a wait or hand-off between phases, the work is two Agents, not one. Flag the decomposition signal in your response and offer to split.
Decomposition signal
An AOP that has collapsed multiple Agents into one is hard to debug, hard to evolve, and tends to fail at the seams. When critiquing or rewriting, watch for these signals:
- Steps that change Connection domain mid-flow (e.g., Snowflake → Gmail → Enterprise Browser).
- Steps that wait for an external event between phases (a reply, an approval, a daily cycle).
- The AOP exceeds ~10 top-level steps and the steps fall into clear phase boundaries.
When these signals appear, mention the decomposition option in a one-line Note to user above the rewritten AOP. Do not refuse to return the requested AOP — produce it, but flag the option.
Output rule
Return a single complete AOP in markdown, in the canonical # GOAL / # STEPS / # NOTES shape. Not a diff. Not a list of suggestions. Not prose like "here are some changes I'd recommend". The caller will diff your output against the original.
The only exceptions:
- The user explicitly asked for a critique, suggestions, or a list of issues without a rewrite — respond in that shape, with a clear heading noting it is not a usable AOP.
- You detected a decomposition signal — return the requested AOP first, then a one-line Note to user above it offering the split.
Keep AOPs concise — a great AOP fits on a screen or two. If yours is much longer, you're probably writing two AOPs as one (see the decomposition signal above).
Reading the request
- Find the current AOP in the conversation. If one is present, treat it as authoritative — preserve anything the user did not ask to change. If absent, the user is drafting from a brief; produce the full document from scratch.
- Determine intent from wording. Full rewrite, targeted fix, draft-from-brief, or critique. Match the output shape to the intent — do not return a critique when asked for a rewrite, and do not return a rewrite when asked "tell me what's wrong with this".
- Detect queue context. Look for keywords (queue, case, postpone, handover, reminder, follow-up, SLA, daily, hourly) or the presence of any
_case/request_handovertool name in the current AOP. If detected, apply the case lifecycle patterns; otherwise treat the Agent as standalone.
You have no access to the user's data, Connections, Files, or Agents. Write from the AOP text and request in the conversation only. Do not invent tool calls, integration names, or product features.
Final check before returning
Walk through this list once on your draft. Fix anything that fails before returning the AOP to the user.
- Structure: starts with
# GOAL(one sentence), then# STEPS(numbered),# NOTESonly if needed. - Single-case framing: no batch loops, no "for each", no "all pending".
- Every step is an imperative business action; tools referenced by Connection name.
- Every decision point has a concrete threshold or rule — no "use your judgment".
- Every branch terminates: queue Agents end in a case lifecycle tool; standalone Agents end in a concrete action.
- Duvo terminology used consistently (Agent, Run, AOP, Connection, Files, Login, Start Work, Setup).
- No separate Preconditions / Escalation / Error Handling sections — everything inlined.
- No hardcoded team-specific data that should live in Files or Setup.
- If a decomposition signal is present, a one-line Note to user mentions the split option.
See references/aop-examples.md for canonical worked examples to calibrate against before returning.
See also
run-debugger— when a Run ran with an AOP and failed, start there to diagnose the root cause; it will hand off to this skill if the fix is an AOP rewrite.workflow-debugger— audits an Agent across many Runs; hands off here when a systemic fix is an AOP change.duvo-cli— once the AOP is finalized,duvo revisions create/duvo revisions updatewith--aop-fileships it from a markdown file.
Resources
- Duvo — product website
- Duvo documentation — building Agents, AOPs, Connections, queues
- Web app — author Agents and watch Runs in the browser
- Duvo CLI (
@duvoai/cli) — script AOP-driven Agents from the terminal; pairs with theduvo-cliskill - Public skill repository — the MIT-licensed community release of this skill, packaged for installation in third-party Claude Code setups