← VolcanoCONTENT HISTORY

Update to Volcano

Snapshot Oct 24, 2026 · 13:36 UTC · version 0.2.26

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Volcano and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Use for Volcano durable functions, long-running or resumable workflows, checkpointed steps, waits, polling, durable executions, idempotent starts, and durable function schedulers.",
  "included_files": [],
  "name": "volcano-durable",
  "skill_md_contents": "---\nname: volcano-durable\ndescription: Use for Volcano durable functions, long-running or resumable workflows, checkpointed steps, waits, polling, durable executions, idempotent starts, and durable function schedulers.\n---\n# Volcano Durable Functions Skill\n\n## Role and pairing\n\nUse a durable function when work must survive restarts, wait without holding a\nrequest open, or resume from completed steps. Examples include order pipelines,\nagent runs, approval flows, reconciliation jobs, and slow batch work.\n\nAlways pair this skill with:\n- `volcano-sdk` for the application entrypoint and domain routing.\n- `volcano-platform` for project shape, variables, config, auth, and cloud safety.\n\nUse `volcano-functions` only when the same task also has standard synchronous\nfunctions. The handler contracts differ.\n\n## Core contract\n\n- Durable functions are a separate collection from standard functions.\n- Durable functions use `volcano/functions/` and are marked with `kind: durable`\n  in `volcano-config.yaml`.\n- A function kind is fixed when the function is created.\n- Deploy locally with `volcano durable deploy` and to cloud with\n  `volcano cloud durable deploy`. Standard function deploy skips manifest\n  entries marked durable.\n- Start an execution. Do not invoke a durable function.\n- A start returns an execution handle. Poll the execution for its result.\n- JavaScript, TypeScript, and Python can author durable handlers. Ruby clients\n  can start and read executions but cannot author handlers.\n- Local and cloud use the same handler, manifest, and execution commands.\n\nUse the project's language and supported capability:\n\n| Project signal | Author durable handlers | Manage executions | SDK behavior |\n|---|---|---|---|\n| `package.json`, `.ts`, `.js` | JavaScript/TypeScript | JavaScript/TypeScript | camel-case methods and result envelopes |\n| `pyproject.toml`, `requirements.txt`, `.py` | Python | Python | snake-case methods and typed exceptions |\n| `Gemfile`, `.gemspec`, `.rb` | Use JavaScript or Python | Ruby | snake-case methods and typed exceptions |\n\n## Authoring rule: replay must be deterministic\n\nEach context operation is checkpointed. On resume, completed operations replay\ntheir recorded results. Code between operations runs again.\n\n- Put side effects and decisions that must run once inside `ctx.step`.\n- Use `ctx.wait` for delays. Do not hold the runtime with timers or sleep.\n- Do not branch between checkpoints on the current time, random data, or mutable\n  external state.\n- Give operations stable names and reach them in the same order on replay.\n- Return the application result directly. Do not return the standard function\n  `{ statusCode, body }` shape.\n\n## JavaScript and TypeScript\n\nUse a directory function so its dependency manifest stays with its source:\n\n```text\nvolcano/functions/order-pipeline/\n├── index.js\n└── package.json\n```\n\n```json\n{\n  \"private\": true,\n  \"dependencies\": {\n    \"@volcano.dev/sdk\": \"latest\"\n  }\n}\n```\n\n```js\nconst { durable } = require('@volcano.dev/sdk/durable');\n\nexports.handler = durable(async (input, ctx) => {\n  if (!input?.order_id) throw new Error('order_id is required');\n\n  const charge = await ctx.step('charge', () => chargeCard(input.order_id));\n  await ctx.wait('settle', '30s');\n\n  const packed = await ctx.map('pack', input.items ?? [], (item, itemCtx) =>\n    itemCtx.step('pack-item', () => pack(item)),\n  );\n\n  return { charge_id: charge.id, packed: packed.results };\n});\n```\n\n## Python\n\n```text\nvolcano/functions/order-pipeline/\n├── main.py\n└── requirements.txt\n```\n\n```text\nvolcano-sdk\n```\n\n```python\nfrom volcano_sdk.durable_authoring import durable\n\n\n@durable\ndef handler(event, ctx):\n    if not event or not event.get(\"order_id\"):\n        raise ValueError(\"order_id is required\")\n\n    charge = ctx.step(\"charge\", lambda scope: charge_card(event[\"order_id\"]))\n    ctx.wait(\"settle\", \"30s\")\n    return {\"charge_id\": charge[\"id\"]}\n```\n\nPython durable operations are synchronous. A step function receives its scope.\n\n## Context operations\n\n| Operation | Use |\n|---|---|\n| `ctx.step(name?, fn, options?)` | Run work and record its result. Retry policy and at-most-once behavior belong here. |\n| `ctx.wait(name?, duration)` | Suspend for at least one second without holding compute. |\n| `ctx.waitUntil(name?, check, options)` | Poll state until `options.until` passes. `initialState` is required. |\n| `ctx.map(name?, items, fn, options?)` | Run one checkpointed child context per item. Set `concurrency` when required. |\n| `ctx.parallel(name?, branches, options?)` | Run independent checkpointed branches. |\n| `ctx.child(name?, fn)` | Group operations in a child context. |\n| `ctx.log` | Log with execution identifiers attached. |\n\nEach step attempt, wait, poll check, child, map item, and parallel branch uses a\ndurable operation. `durable get` shows the function's execution timeout and\nresult retention. Read the plan limits documentation for operation allowance,\noperations per execution, and concurrency limits.\n\n## Start and manage executions from an application\n\n`start` accepts an application credential and returns an execution handle. An\nexecution name makes retries idempotent. `get`, `list`, and `stop` are\nowner-scoped; call them from trusted backend code with the project owner's\nplatform user token. Auth-user sessions, anon keys, service keys, and project\naccess tokens are not accepted.\n\n### JavaScript and TypeScript\n\n```ts\nimport { VolcanoClient } from '@volcano.dev/sdk';\n\nconst { data: handle, error } = await volcano.durable.start(\n  'order-pipeline',\n  { order_id: 4417 },\n  { executionName: 'order-4417' },\n);\nif (error || !handle) throw error ?? new Error('Durable start returned no execution');\n\nconst owner = new VolcanoClient({\n  anonKey: process.env.VOLCANO_ANON_KEY!,\n  apiUrl: process.env.VOLCANO_API_URL,\n  accessToken: process.env.VOLCANO_PLATFORM_TOKEN!,\n});\nconst read = await owner.durable.get(projectId, 'order-pipeline', handle.id);\nif (read.error) throw read.error;\nconst listed = await owner.durable.list(projectId, 'order-pipeline', { status: 'running' });\nif (listed.error) throw listed.error;\nconst stopped = await owner.durable.stop(projectId, 'order-pipeline', handle.id);\nif (stopped.error) throw stopped.error;\n```\n\n### Python\n\n```python\nimport os\nfrom volcano_sdk import VolcanoClient\n\nowner = VolcanoClient(\n    anon_key=os.environ[\"VOLCANO_ANON_KEY\"],\n    access_token=os.environ[\"VOLCANO_PLATFORM_TOKEN\"],\n)\nhandle = client.durable.start(\n    \"order-pipeline\", {\"order_id\": 4417}, execution_name=\"order-4417\"\n)\nexecution = owner.durable.get(project_id, \"order-pipeline\", handle.id)\npage = owner.durable.list(project_id, \"order-pipeline\", status=\"running\")\nowner.durable.stop(project_id, \"order-pipeline\", handle.id)\n```\n\n### Ruby\n\n```ruby\nrequire \"volcano\"\n\nowner = Volcano::Client.new(\n  anon_key: ENV.fetch(\"VOLCANO_ANON_KEY\"),\n  access_token: ENV.fetch(\"VOLCANO_PLATFORM_TOKEN\")\n)\nhandle = client.durable.start(\n  \"order-pipeline\", { order_id: 4417 }, execution_name: \"order-4417\"\n)\nexecution = owner.durable.get(project_id, \"order-pipeline\", handle.id)\npage = owner.durable.list(project_id, \"order-pipeline\", status: \"running\")\nowner.durable.stop(project_id, \"order-pipeline\", handle.id)\n```\n\nPoll `get` for live state. Listings carry the last observed state. `stop` is\nasynchronous, so poll until the execution reaches a terminal status.\n\n## Manifest\n\n```yaml\nversion: 1\nfunctions:\n  - name: order-pipeline\n    kind: durable\n    public: false\n    variable_scope: scoped\n    variables: [PAYMENTS_API_KEY]\n```\n\nRules:\n- Omitting `kind` means `standard`.\n- `kind` is an assertion. Config deploy rejects a mismatch.\n- Do not set `invocation_mode`, `http_auth_mode`, or `openapi_spec` on a durable\n  function. Durable functions have no synchronous HTTP invocation path.\n- `public: true` lets an anon key start executions. It does not let that key\n  read results or stop executions.\n- A declared `schedulers` list is fully synced by config deploy. Omitted entries\n  are deleted.\n\n## Local workflow\n\nRun and verify Durable functions locally before cloud deployment:\n\n```sh\nvolcano start\nvolcano durable deploy --all\nvolcano durable get order-pipeline\n\nvolcano durable start order-pipeline \\\n  --input '{\"order_id\":4417}' \\\n  --name order-4417\n\nvolcano durable executions list order-pipeline --status running\nvolcano durable executions get order-pipeline <execution-id>\nvolcano durable logs order-pipeline --type runtime\n```\n\nLocal execution uses one region. Waits resolve immediately so long workflows\nfinish quickly while still suspending and replaying checkpoints. Instant waits\ncause more resumes per wall-clock minute than production, which helps expose a\nstep that is unsafe to replay. Set `LOCAL_DURABLE_REAL_TIME=true` before\n`volcano start` when wait timing must be real. Local executions persist across\n`volcano stop` and `volcano start`. Volcano does not expose externally completed\ncallbacks in local or cloud execution; use `ctx.waitUntil` to poll application\nstate instead.\n\nLocal executions increment the same execution, operation, and compute counters\nas cloud executions. Inspect them through `GET /projects/{id}/usage`; the CLI\nhas no project usage command. For `ctx.waitUntil`, `maxAttempts` directly bounds\nthe poll operation count, so check local usage before cloud deployment.\n\n## Cloud workflow\n\nCloud deploy requires explicit user approval. Follow `volcano-platform` for\nlogin, project selection, variables, and config deployment.\n\n```sh\n# Deploy every manifest entry marked durable.\nvolcano cloud durable deploy --all\n\n# Or deploy one source. Visibility flags work only with -f.\nvolcano cloud durable deploy -f order-pipeline --private\n\n# Deployment is asynchronous. Wait for active before starting work.\nvolcano cloud durable get order-pipeline\n\nvolcano cloud durable start order-pipeline \\\n  --input '{\"order_id\":4417}' \\\n  --name order-4417\n\nvolcano cloud durable executions get order-pipeline <execution-id>\n```\n\nFor local commands, use `volcano durable ...`. For cloud commands, insert\n`cloud` after `volcano`. `--input` accepts an inline JSON object or a file\ncontaining one. Omitting it means no input. `--name` is the idempotency key in\nboth local and cloud. Repeating the same name returns the same execution instead\nof starting duplicate work.\n\nExecution statuses are `pending`, `running`, `succeeded`, `failed`,\n`timed_out`, `stopped`, and `unknown`. Fetch one execution to refresh its state.\n`unknown` is terminal. Retry the start with the same execution name to recover\nthe same execution when possible.\n\n## Schedulers\n\nA durable scheduler starts an execution on each tick. It does not invoke the\nfunction.\n\n```sh\nvolcano cloud durable schedulers create order-pipeline \\\n  --name nightly-orders \\\n  --cron \"0 2 * * *\" \\\n  --input '{\"scope\":\"nightly\"}'\n\nvolcano cloud durable schedulers list order-pipeline\nvolcano cloud durable schedulers disable order-pipeline <scheduler-id>\nvolcano cloud durable schedulers enable order-pipeline <scheduler-id>\n```\n\nSchedulers require SUPERAGENT. A tick can overlap a running execution and uses the\nsame execution allowance, operation allowance, and concurrency cap as a manual\nstart.\n\n## Safety\n\n- Validate public-function input. Anyone with the project's anon key can spend\n  execution and operation allowance on a public durable function.\n- Keep execution names tied to one unit of work. A name stays reserved while\n  its execution is readable.\n- Keep returned results small. Persist data that must outlive result retention.\n- Stopping is asynchronous and does not undo completed steps. Poll with\n  `executions get` until terminal.\n- Deleting a durable function removes its execution history. Confirm before\n  `durable delete`, `executions stop`, or `schedulers delete`.\n- Bound `logs --follow` with a timeout in agent-driven diagnostics.\n\n## Troubleshooting\n\nUse `volcano durable ...` for local state and `volcano cloud durable ...` for\ncloud state.\n\n1. Run `durable get <name>` with the correct prefix and inspect status.\n2. For deploy failure, run `durable logs <name> --type build`.\n3. For execution failure, run `durable logs <name> --type runtime`.\n4. A `404` can mean the name belongs to the standard function collection.\n5. A start during provisioning returns `409`; wait for `active`.\n6. A `429` means a concurrency or durable allowance limit blocked the start.\n7. A scheduler `403` can mean the project plan does not include schedulers.\n\n## Verification\n\n- Validate source syntax or run the project's typecheck and unit tests.\n- Confirm the manifest names every durable function with `kind: durable`.\n- Run `volcano start` and `volcano durable deploy --all`.\n- Wait for local function status `active`.\n- Start one local execution with a unique idempotency name.\n- Poll it to a terminal status and check its result.\n- Read runtime logs if the result is not `succeeded`.\n- After approved cloud deployment, repeat the execution check with\n  `volcano cloud durable`.\n\n## References\n\n- Hosting contract: `volcano-hosting/docs/public/functions/durable-functions.md`\n- Local guide: `volcano-hosting/docs/public/guides/durable-functions-locally.md`\n- CLI contract: `volcano-cli/docs/durable-functions.md`\n- Command source: `volcano-cli/internal/cmd/durable/`\n"
}

SHA-256 of public snapshot: c84b05ba76b62b95e0a070787695f9c426bdbe7911d0b0e820d3907a5e8468c8