Atlas / Skills / vercel / Migration skill acceptance

Migration skill acceptanceSAFE

skills/vercel/migrating-to-workflow-sdk

Workflow SDK: Build durable, reliable, and observable apps and AI Agents in TypeScript

Verdict
SAFE
Grade
B
Trust score
89 /100
Version
0.3.0
Hosts
—
License
Apache-2.0
Stars
2,466
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

A response passes only if it:

  1. removes all source-framework API symbols from final migrated code
  2. uses "use workflow" for orchestration
  3. uses "use step" for side effects
  4. keeps sleep() in workflow context only
  5. may call getWritable() in workflow or step context, but keeps all stream interaction (getWriter(), write(), close()) in step context only
  6. uses step-wrapped start() / getRun() for child workflows
  7. adds getStepMetadata().stepId for external idempotent writes
  8. adds hooks/webhooks when the source used signals, wait-for-event, or task tokens
  9. stays framework-agnostic when the target framework is unspecified
  10. does not claim managed execution when the prompt says the target is self-hosted
  11. chooses plain createWebhook() for generated callback-URL flows unless the prompt explicitly requires a custom HTTP response; when manual mode is chosen, request.respondWith() stays in step context

Sample input for manual check

Migrate this Inngest workflow to the Workflow SDK. It publishes progress and waits for approval with a 7d timeout.

Expected passing excerpt:

import { createHook, getWritable, sleep } from 'workflow';

export async function refundWorkflow(refundId: string) {
'use workflow';

const writable = getWritable();
await emitStatus(writable, { stage: 'requested' });

using approval = createHook({
token: `refund:${refundId}:approval`,
});

const result = await Promise.race([
approval.then((payload) => ({ kind: 'approval' as const, payload })),
sleep('7d').then(() => ({ kind: 'timeout' as const })),
]);

return result.kind === 'timeout'
? { refundId, status: 'timed-out' as const }
: {
refundId,
status: result.payload.approved
? ('approved' as const)
: ('rejected' as const),
};
}

async function emitStatus(
writable: WritableStream,
chun
Read from source at commit f4dee6af3bafOBSERVED · 2026-10-21
Advertisement
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: migrating-to-workflow-sdk
description: Migrates Temporal, Inngest, Trigger.dev, and AWS Step Functions workflows to the Workflow SDK. Use when porting Activities, Workers, Signals, step.run(), step.waitForEvent(), Trigger.dev tasks / wait.forToken / triggerAndWait, ASL JSON state machines, Task/Choice/Wait/Parallel states, task tokens, or child workflows.
metadata:
  author: Vercel Inc.
  version: '0.3.0'
---

# Migrating to the Workflow SDK

Use this skill when converting an existing orchestration system to the Workflow SDK.

## Intake

1. Identify the source system:
   - Temporal
   - Inngest
   - Trigger.dev
   - AWS Step Functions
2. Identify the target runtime:
   - Managed hosting -> keep examples focused on `start()`, `getRun()`, hooks/webhooks, and route handlers.
   - Self-hosted -> also read `references/runtime-targets.md` and explicitly say the workflow/step code can stay the same, but deployment still needs a `World` implementation and startup bootstrap.
3. Extract the source constructs:
   - entrypoint
   - waits / timers
   - external callbacks / approvals
   - retries / failure handling
   - child workflows / fan-out
   - progress streaming
   - external side effects

## Default migration rules

- Put orchestration in `"use workflow"` functions.
- Put side effects, SDK calls, DB calls, HTTP calls, and stream I/O in `"use step"` functions.
- Use `sleep()` only in workflow context.
- For Signals, `step.waitForEvent()`, and `.waitForTaskToken`, choose exactly one resume surface:
  - `resume/internal` -> `createHook()` + `resumeHook()` when the app resumes from server-side code with a deterministic business token.
  - `resume/url/default` -> `createWebhook()` when the external system needs a generated callback URL and the default `202 Accepted` response is fine.
  - `resume/url/manual` -> `createWebhook({ respondWith: 'manual' })` only when the prompt explicitly requires a custom response body, status, or headers.
  - If a callback-URL prompt does not specify response semantics, default to `resume/url/default` and make the assumption explicit in `## Open Questions`.
- Never pair `createWebhook()` with `resumeHook()`, and never pass `token:` to `createWebhook()`.
- Wrap `start()` and `getRun()` inside `"use step"` functions for child runs.
- Use `getStepMetadata().stepId` as the idempotency key for external writes.
- Use `getWritable()` in workflow context to obtain the stream, but interact with it (write, close) only inside `"use step"` functions.
- Prefer rollback stacks for multi-step compensation.
- Choose app-boundary syntax in this order:
  1. If the prompt explicitly asks for framework-agnostic app-boundary code, use plain `Request` / `Response` even when a framework like Hono is named.
  2. Otherwise, if the target framework is named, shape app-boundary examples to that framework.
  3. Otherwise, keep examples framework-agnostic with `Request` / `Response`. Do not default to Next.js-only route signatures unless Next.js is explicitly named.

> Fast memory aid:
> - Callback URL + default ack -> `createWebhook()`
> - Callback URL + custom ack -> `createWebhook({ respondWith: 'manual' })`
> - Deterministic server-side resume -> `createHook()` + `resumeHook()`

## Fast-path router

Load `references/resume-routing.md` when the source pauses for Signals, `step.waitForEvent()`, or `.waitForTaskToken`.

Fast defaults:

- callback URL only -> `resume/url/default`
- callback URL + explicit custom response -> `resume/url/manual`
- deterministic server-side resume -> `resume/internal`
- self-hosted -> add `runtime/self-hosted`
- named framework -> add `boundary/named-framework`
- explicit framework-agnostic request -> add `boundary/framework-agnostic`

Before drafting `## Migrated Code`, write the selected route keys in `## Migration Plan`.

## Source references

- Temporal -> `references/temporal.md`
- Inngest -> `references/inngest.md`
- Trigger.dev -> `references/trigger-dev.md`
- AWS Step Functions -> `references/aws-step-functions.md`

## Shared references

- `references/shared-patterns.md`: Reusable code templates for hooks, child workflows, idempotency, streaming, and rollback.
- `references/runtime-targets.md`: Managed vs. custom `World` guidance.
- `references/resume-routing.md`: Route-key selection, obligations, and exact `## Migration Plan` shape.
- `references/retries.md`: Canonical retry mechanics, including `stepFn.maxRetries`, `RetryableError({ retryAfter })`, and `FatalError`.

## Required output shape

Return the migration in this structure:

```md
## Migration Plan
## Source -> Target Mapping
## Migrated Code
## App Boundary / Resume Endpoints
## Verification Checklist
## Open Questions
```

## Verification checklist

Fail the draft if any of these are true:

- [ ] `## Migration Plan` omits `Route keys`
- [ ] `## Migration Plan` omits `Why these route keys`
- [ ] `## Migration Plan` lists route keys that do not match the prompt
- [ ] `## Migration Plan` lists required code obligations that do not match the selected route keys
- [ ] Source-framework primitives remain in the migrated code
- [ ] Side effects remain in workflow context
- [ ] `sleep()` appears inside a step
- [ ] Stream interaction (`getWriter()`, `write()`, `close()`) appears inside a workflow function
- [ ] Child workflows call `start()` / `getRun()` directly from workflow context
- [ ] External writes omit idempotency keys
- [ ] Hooks/webhooks are missing where the source used signals, waitForEvent, or task tokens
- [ ] A callback-URL flow uses `createHook()` + `resumeHook()` instead of `createWebhook()`
- [ ] A `resume/url/default` or `resume/url/manual` migration invents a user-authored callback route or `resumeWebhook()` wrapper when `webhook.url` should be the only resume surface
- [ ] `createWebhook()` is given a custom `token` or paired with `resumeHook()`

Validation note:

- Reading webhook request data in workflow context is allowed. Only `request.respondWith()` is step-only.

Addi
03

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (5)

LOWInventory / provenance · inv.symlink · CWE-1104
CLAUDE.md
CLAUDE.md
Why it matters. link not followed
LOWInventory / provenance · inv.symlink · CWE-1104
README.md
README.md
Why it matters. link not followed
LOWInventory / provenance · inv.symlink · CWE-1104
docs/LICENSE.md
docs/LICENSE.md
Why it matters. link not followed
LOWInventory / provenance · inv.symlink · CWE-1104
packages/builders/LICENSE.md
packages/builders/LICENSE.md
Why it matters. link not followed
LOWInventory / provenance · inv.symlink · CWE-1104
packages/cli/LICENSE.md
packages/cli/LICENSE.md
Why it matters. link not followed

Gates applied: no_behavioural_pass.

Audited 2026-10-21 · audit v0.4.1 · source sha f4dee6af3baffull audit observations/trust-audit/skill/vercel__migrating-to-workflow-sdk.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-21f4dee6af3bafSAFEB89first audit
05

Questions

What does the migrating-to-workflow-sdk — vercel/workflow skill do?

Workflow SDK: Build durable, reliable, and observable apps and AI Agents in TypeScript

Is migrating-to-workflow-sdk — vercel/workflow safe to install?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.

What can migrating-to-workflow-sdk — vercel/workflow access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

How current is this page?

The grade is for one exact copy of the source (f4dee6af3baf), read on 2026-10-21. The repository is watched, and a new audit runs when it changes — this is the first audit.

Add this badge to your README

Shows this page's audit result and links back to it. It updates when the audit does.

ModelsAtlas audit badge

Markdown
[![ModelsAtlas audit: Migration skill acceptance](https://modelsatlas.com/skills/vercel/migrating-to-workflow-sdk/badge.svg)](https://modelsatlas.com/skills/vercel/migrating-to-workflow-sdk/)

Not your listing, or something out of date? Claim or update your listing.

Advertisement