Velt Approval Engine Best Practices
Implementation guide for the Velt Approval Engine, documented on docs.velt.dev as the Review Workflow Builder (Beta): a workflow runtime for multi-step agent and human review. Covers the workflow model (definitions of nodes, edges, groups, and triggers), the 14 enveloped REST endpoints under /v2/workflow/* plus the raw-JSON inbound trigger endpoint, webhook delivery with HMAC verification, and the patterns and anti-patterns from the docs.
When to Apply
Reference these guidelines when:
- Authoring definitions:
agentnodes (url/urlPath,aiConfig),humannodes (mandatory reviewers, requiredon: "reject"edge),notificationnodes (email / Slack),webhooknodes (sync / async callback) - Routing with edges:
onroles (approve,reject,always,exhausted,customwith JSON-ASTwhen), reject loop-backs withloop.maxIterations, SLA breach routes - Using parallel groups with
waitAll/cancelOnQuorum/joinOnQuorum,requiredNodeIds, and group edge sources - Adding triggers that start runs:
inboundWebhook, cronschedule, GitHub / VercelappTrigger - Dispatching executions with an
idempotencyKey, and configuringwebhookConfigor a per-dispatchwebhookUrl+webhookSecret - Recording decisions with
/steps/recordReviewerDecision, or overriding with/steps/canceland/steps/resolve - Building webhook receivers: HMAC-SHA256 on raw bytes, idempotency on
(executionId, seq), recovery with/executions/getEventsandsinceSeq - Updating or copying definitions: full-replace updates with
ifVersion, stripping server-owned fields and nulls, write-onlywebhookConfig - Debugging
INVALID_ARGUMENTlinter failures (missing-breach-edge,loop-node-in-multiple-loops,group-joinonquorum-members-must-share-successors, reject-path and URL rules)
The agents that agent nodes run (built-in and custom agents, Run Execution, the aiConfig model allowlist) are covered by rest-agents in velt-rest-apis-best-practices. Other Velt REST APIs are covered there too; only the Approval Engine domain is covered here.
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Concepts | HIGH | concepts- |
| 2 | REST Endpoints | HIGH | rest- |
| 3 | Webhooks | HIGH | webhooks- |
| 4 | Patterns | MEDIUM-HIGH | patterns- |
Quick Reference
Concepts (HIGH)
concepts-workflow-model— definition anatomy and limits, the four node types, common node fields, lifecycles (waitingfor agent, human, async webhook steps), deterministic step IDs, scope semantics, versioning pin, tenant partitioning, beta limitationsconcepts-agent-node—agentIdplus requiredurl/urlPath, crawl and polling fields,aiConfig(provider,model,defaultModels,maxToolTurns),__mock__, noblocking: true, outputs, dispatchorganizationId/documentId, link to the Agents featureconcepts-human-node—reviewers[]vs legacyreviewerIds[],reviewerEmails,commentBody, resolution rule, requiredon: "reject"edge, undeclared reviewers returnrecorded: falseconcepts-notification-webhook-nodes— email / Slack notification config and{{...}}templating; webhook node sync vs async, callback token contract,hmac/token/noneauth, outputsconcepts-edge-model—EdgeEndpoint,onroles, JSON-ASTwhen(custom only), reject loop-backs,on: "exhausted", derivedcompiled.loops, fixed loop predicate, body shapes,previousAttempts, breach routing,compiledviewconcepts-groups-quorum— group fields, quorum counts approvals (passing agents count), policy behavior,requiredNodeIds, groups as edge sources,joinOnQuorumsuccessor inputconcepts-triggers— trigger entries (one mechanism each), scope inheritance, cronschedule, GitHub / VercelappTrigger, triggers now dispatch runs
REST Endpoints (HIGH)
rest-foundations— headers, envelope, error codes, linter codes parsed fromerror.message, Zoderror.details.issues, literal schema messages, rate limitingrest-definitions— create, update as full replace with requiredifVersion, round-tripping reads, get (nowebhookConfig), list withpageSize/ integercursor/items, soft orpurgedelete, 19 linter codes and edge-contract rulesrest-executions— dispatch fields and errors (tombstoned isFAILED_PRECONDITION), get, list (itemswithsteps: [], stringcursor), cancel (no-op on terminal runs),getEventswithsinceSeq,pageSize,hasMorerest-steps—recordReviewerDecision(recorded,rejectionReason,aggregatorStatus),recordAgentResolutionunavailable in beta,/steps/cancel,/steps/resolveaction matrix and loop-predicate caveatrest-object-views—ExecutionView,StepView(four node types),DefinitionViewwithcompiled,CompiledGraph,ApprovalEventView, human / agent / webhook step outputs,joinOnQuorumsuccessor input
Webhooks (HIGH)
webhooks-delivery—webhookConfigvs dispatch override, raw-byte HMAC verification, headers, retry schedule, 12-event catalog with per-node-typedata, cancellation reasons,(executionId, seq)idempotencywebhooks-inbound-handler—/v2/workflow/webhook-inbound/triggerraw-JSON contract, per-trigger secret, provider presets,allowedEvents, idempotency headers, 1 MB limit, no built-in rate limiting or payload URL screening
Patterns (MEDIUM-HIGH)
patterns-choose-the-right-construct— "I want X, use Y" decision table, parallel policy choice, webhooks plus pollingpatterns-rejection-and-loops— three rejection shapes, one group-source back-edge for parallel rewinds, anti-patterns (per-reviewer back-edges,slaMswith only reject, exhausted targets reachable twice)patterns-copy-update-versioning— manual copy steps, triggers andwebhookConfigpitfalls, full-replace updates, versioning without history or rollback
How to Use
Read individual rule files for detailed explanations and code examples:
rules/shared/concepts/concepts-workflow-model.md
rules/shared/concepts/concepts-agent-node.md
rules/shared/concepts/concepts-human-node.md
rules/shared/concepts/concepts-notification-webhook-nodes.md
rules/shared/concepts/concepts-edge-model.md
rules/shared/concepts/concepts-groups-quorum.md
rules/shared/concepts/concepts-triggers.md
rules/shared/rest/rest-foundations.md
rules/shared/rest/rest-definitions.md
rules/shared/rest/rest-executions.md
rules/shared/rest/rest-steps.md
rules/shared/rest/rest-object-views.md
rules/shared/webhooks/webhooks-delivery.md
rules/shared/webhooks/webhooks-inbound-handler.md
rules/shared/patterns/patterns-choose-the-right-construct.md
rules/shared/patterns/patterns-rejection-and-loops.md
rules/shared/patterns/patterns-copy-update-versioning.md
Each rule file contains:
- Brief explanation of why it matters
- Incorrect and correct request examples
- Common pitfalls and what NOT to do
- Verification checklist
- Source pointers to official docs
Compiled Documents
AGENTS.md— Compressed index of all rules with file paths (start here)AGENTS.full.md— Full verbose guide with all rules expanded inline