velt-approval-engine-best-practices

Implement Velt Approval Engine workflows with REST endpoints, quorum groups, and signed webhooks.

1|Updated Jan 23, 2026
One-click install
npx skills add https://github.com/velt-js/agent-skills --skill velt-approval-engine-best-practices-velt-js
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: velt-approval-engine-best-practices
Source: https://github.com/velt-js/agent-skills/tree/main/skills/velt-approval-engine-best-practices
Command: npx skills add https://github.com/velt-js/agent-skills --skill velt-approval-engine-best-practices-velt-js

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Building multi-step approval workflows that combine AI agents with human reviewers involves tricky details: idempotent execution dispatch, parallel reviewer quorums, SLA breach routing, rejection loops, and HMAC-verified webhooks. This Skill provides the canonical implementation rules for the Velt Approval Engine so agents generate correct definitions, endpoint calls, and webhook receivers on the first attempt. ## Core Features & Use Cases - Workflow Definitions: Author nodes (agent/human), edges with when expressions, parallel quorum groups (waitAll / cancelOnQuorum / joinOnQuorum), and rejection loop regions, with the full 25-rule linter reference to debug INVALID_ARGUMENT rejections. - REST Endpoint Coverage: All 14 POST endpoints under /v2/workflow/* — definitions CRUD with ifVersion optimistic locking, execution dispatch with idempotencyKey, step decision recording, and admin resolve/cancel operations. - Webhook Reliability: HMAC-SHA256 signature verification on raw bytes, at-least-once idempotency keyed on (executionId, seq), and missed-event recovery via /executions/getEvents with sinceSeq. - Use Case: A developer needs an AI agent to draft marketing copy, then require both legal and brand reviewers to approve in parallel before publishing. The Skill supplies the exact /definitions/create payload with a joinOnQuorum group and the dispatch call with an idempotency key. ## Quick Start Ask the agent to create a Velt Approval Engine workflow definition where an agent drafts content and two human reviewers must approve in parallel before a publish step runs.

Frequently Asked Questions about velt-approval-engine-best-practices

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a Velt Approval Engine workflow definition with parallel reviewers?▼

POST to /v2/workflow/definitions/create with nodes (agent and human types), edges connecting them, and a groups entry listing memberNodeIds, expectedSteps, and quorum. Human nodes use reviewers: [{ userId, mandatory: true }], and every human node needs an onReject config or loop membership.

How do I prevent duplicate workflow executions when dispatching?▼

Always include an idempotencyKey in the /executions/dispatch request body, derived from a stable upstream identifier. Replays with the same key return the original executionId with deduplicated: true, which should be treated as success rather than retried.

Why does Velt webhook signature verification fail with express.json()?▼

express.json() re-serializes the body, changing whitespace and key order so the HMAC no longer matches. Use express.raw({ type: 'application/json' }) and compute HMAC-SHA256 over the raw bytes, comparing with crypto.timingSafeEqual against the x-velt-signature header.

Which onQuorumMet policy should I use for parallel approval groups?▼

Use cancelOnQuorum to cancel waiting sibling reviewers once quorum is met, joinOnQuorum to fire a single group-owned downstream step per shared successor, or the default waitAll to only emit the quorum-met event. cancelOnQuorum requires quorum < expectedSteps.

How do I recover missed Velt Approval Engine webhook events after downtime?▼

Call POST /v2/workflow/executions/getEvents with sinceSeq set to the last sequence number your receiver stored. It returns externally-visible events in order, which you re-apply idempotently using (executionId, seq) as the dedup key; non-contiguous seq values are normal.

Why does my definition get INVALID_ARGUMENT with missing-breach-edge?▼

Any node configured with slaMs must have an outgoing edge routed for breach handling, otherwise the linter rejects the definition. Add a breach-routed edge to an escalation node alongside the normal success-path edge.