Skip to main content

post-build-flow

Handles workflow verification and setup after build-workflow succeeds, or when the message contains workflow-verification-follow-up or workflow-setup-required. Load after direct builds, when verificationReadiness requires action, or on orchestrator verify/setup follow-up turns.

跳到安装

来源信息

仓库
n8n-io/n8n
最近来源活动
2026年9月28日 03:39
检测到的 SKILL.md 语言
英语
星标
206,150
分支
60,906

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
2 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
post-build-flow
description
Handles workflow verification and setup after build-workflow succeeds, or when the message contains workflow-verification-follow-up or workflow-setup-required. Load after direct builds, when verificationReadiness requires action, or on orchestrator verify/setup follow-up turns.
recommended_tools
["ask-user","verify-built-workflow","workflows","build-workflow","executions"]
# Post-Build Flow Use this skill after `build-workflow` succeeds on a direct orchestrator build, especially when the build result contains `postBuildFlow.required: true`, or when the current message contains `<workflow-verification-follow-up>` or `<workflow-setup-required>`. One-off builds (`postBuildFlow.reason: "direct-one-off-build-succeeded"`) hand off to the `one-off-operations` skill instead — verification is optional there and completion is a live run with read-back. If both sets of instructions are in context for a one-off build, the one-off flow wins. These instructions are in English, but user-visible text you write while following them stays in the user's conversation language. For trigger `inputData` shapes, read `${N8N_WORKSPACE_DIR}/knowledge-base/reference/trigger-input-data-shapes.md` in the sandbox workspace when available, or load this skill's `references/trigger-input-data-shapes.md` linked file. ## Setup panel Use this section when the system prompt describes the persistent setup panel, setup returns `announced: true`, or the current user input contains `<workflow-test-request>`. Otherwise, keep the setup card flow below. - Setup requirements can appear while the workflow is being built. The user can complete them immediately. Refer to the "setup panel" without a position or a claim that setup must wait until the build finishes. - Verify what the build can simulate before asking the user to finish setup. Missing credentials do not prevent this verification. Report which outputs were simulated. A simulated result does not prove a live connection. - When setup returns `announced: true`, summarize the open items and any validation warnings. End the turn. The user can complete setup in the panel while chat stays available. Do not wait, poll, or open a trigger-test card. - On a later user turn, trust `<workflow-setup-state>` over earlier setup results. If items settled, none remain open, and there are no validation warnings, verify the current saved configuration with `verify-built-workflow`. It refreshes the credential plan. Report remaining simulations or connection failures. Do not claim live success from the earlier build result. - `<workflow-test-request>` in the current user input means the user clicked Execute. A block in conversation history does not request another execution. Use the workflow ID in the current block. Inspect its current `<workflow-setup-state>` and read the saved workflow with `workflows(action="get-as-code")`. Do not call `workflows(action="setup")` for this precheck. It announces setup and ends the turn. If the target is absent from the state block, inspect its saved configuration. If required setup cannot be confirmed, report what is missing and end the turn. If required items remain open for this workflow, report them and end the turn without a live run. Otherwise, use `executions(action="run")` with suitable trigger input. The user has already requested this test; do not ask whether they want it. The execution tool still enforces its approval policy. Do not publish the workflow to test it. - Read the execution output and summarize what ran and what it returned. For failures, inspect `executions(action="debug")`. Fix the same workflow when possible. Use the current saved source so panel edits are preserved. Report unresolved setup or failures in chat. Before another live run, inspect the successful effect nodes from the failed run. Follow [Cleaning up after a live test](#cleaning-up-after-a-live-test) for any artifacts they left behind. After a repair and that artifact check, test the updated workflow and inspect its output. Do not substitute mocked verification for the requested execution. A setup card that was already open keeps its apply and trigger-test resume flow. Its result is not a panel announcement unless it has `announced: true`. ## Verification follow-up When the current message contains `<workflow-verification-follow-up>`, verify immediately from the payload's `obligation` — do not acknowledge first. If the obligation is `ready_to_verify` or `verifying`, call `verify-built-workflow`. Do **not** call `workflows(action="setup")` in this turn and do **not** declare the workflow finished if `outcome.setupRequirement.status === "required"` — setup is routed automatically as a separate `<workflow-setup-required>` step after verification. For a multi-trigger outcome, verify every trigger that does not yet have a recorded successful verification. Make all of these calls in this turn. ## Setup follow-up When the current message contains `<workflow-setup-required>`, your first action is to call `workflows(action="setup")` with the `workflowId` from the payload. Do not verify, do not ask, do not write a message first — the inline setup card in the n8n Assistant panel is the user-visible surface. If the result has `announced: true`, use the persistent panel instructions above and end the turn. If it returns `deferred: true`, respect the user's choice and do not retry with any other setup tool. A result carrying `skippedByUser` names credentials the user already passed on: never re-open setup for those, in this turn or any later one — see [Credentials the user skipped](#credentials-the-user-skipped). After setup completes or is applied, follow [Mocked verification live-test follow-up](#mocked-verification-live-test-follow-up) if the payload or prior verification evidence says mocked credentials, simulated node output, fixture overrides, temporary pin data, or another mocked input was used. ### Choosing the credential type for a service Pick in this order: 1. **A dedicated credential type** (`slackApi`, `notionApi`, …) whenever one exists — search with `credentials(action="search-types")`. 2. **Simplified Custom Auth** (`httpTemplatedCustomAuth`) for any service without a dedicated type whose auth is expressible as header/query/body values — which covers API keys and bearer tokens (`Authorization: Bearer <token>` becomes `{"headers":{"Authorization":"Bearer {{api_key}}"}}`, not `httpBearerAuth`). Always provide a recipe (below) so the user only pastes their secret. 3. **Plain generic types** (`httpBasicAuth`, `httpDigestAuth`, `oAuth2Api`, …) only for what a template cannot express: basic auth's base64-encoded pair, digest's challenge-response, OAuth flows — or when the user explicitly asks for a specific plain type: an explicit user choice wins (setup accepts it with `allowPlainGenericAuth: true`). ### Credential recipes for Simplified Custom Auth When the workflow authenticates a service through Simplified Custom Auth, include `credentialHints` in the same `workflows(action="setup")` call so the setup card pre-fills the credential and the user only pastes their secret — instead of facing an empty JSON template they'd have to decode from the provider's docs. Before composing the hints, load the `credential-recipe-research` skill and execute its lookup procedure — the template, `docsUrl` and `testUrl` must come from the provider documentation it has you fetch, never from memory: - `template` — the auth request parts (headers/qs/body) exactly as documented, with `{{placeholder}}` markers where the user's values go. - `placeholders` — one entry per marker: `name`, user-facing `title`, an optional `info` clarifying the value itself — its format or which of the provider's tokens it is (e.g. "Starts with tvly-"). Never where to obtain it, and never a URL or domain: the user asks the n8n Assistant for that from the credential form. `type` is `password` unless clearly non-secret (at least one placeholder must stay `password`). Add `optional: true` only when the provider documents the value as optional (e.g. an org/region qualifier) — template entries referencing an empty optional placeholder are omitted from the request. - `docsUrl` — the provider page where a logged-in user CREATES/COPIES the secret (e.g. `https://replicate.com/account/api-tokens`) — never the API reference. Not shown in the form: the n8n Assistant help thread uses it to send the user to the exact page. Found via the `credential-recipe-research` procedure; omit when it finds nothing conclusive. - `testUrl` — a documented side-effect-free GET that rejects a bad key with 401/403, used to verify the credential on save and later retests; never one of the workflow's own endpoints, never anything billable. Found via the `credential-recipe-research` procedure; omit when nothing qualifies — a credential without a testUrl saves fine and honestly shows "could not be verified", which beats a false green. - `acceptedStatusCodes` — almost always omit; the user can adjust it later on the credential if a service's auth answers 401/403 to valid GETs. - `suggestedName` — display name for the created credential. Example — fal.ai's docs say requests use `Authorization: Key <FAL_KEY>` and `GET https://api.fal.ai/v1/models/usage` is a documented side-effect-free endpoint that rejects a bad key (the model-serving host `fal.run` is not a key-check endpoint): ```json { "action": "setup", "workflowId": "...", "credentialHints": [ { "suggestedName": "fal.ai API Key", "template": { "headers": { "Authorization": "Key {{api_key}}" } }, "placeholders": [ { "name": "api_key", "title": "fal.ai API key", "info": "Key ID and secret, separated by a colon", "type": "password" } ], "docsUrl": "https://fal.ai/dashboard/keys", "testUrl": "https://api.fal.ai/v1/models/usage" } ] } ``` Never put a real secret in a recipe — the user pastes it in the setup card and it is stored redacted in the credential. Add `nodeName` when several nodes use Simplified Custom Auth for different services. You cannot see the secret, but once setup reports the credential applied, treat it as fully configured — the `{{placeholder}}` markers live only in the template; the stored values replace them at request time. If a live test later fails with an auth error, that is the moment to have the user re-open the credential and re-paste the value. If the user defers setup instead, don't hand them manual field-by-field credential instructions for the n8n editor — tell them to reopen setup when they're ready: the card pre-fills everything except their key. ### Credentials the user skipped Skipping is remembered for the whole conversation. A setup result may carry `skippedByUser` (nodes and credential types the user passed on), and a build outcome may carry `setupRequirement.status === "not_required"` with `reason: "skipped-by-user"`. In both cases the blocking setup card is off the table for those credentials — including after later edits, rebuilds, and `<workflow-setup-required>` steps. Asking again is the single most common complaint about this flow. Instead, in your normal message: - name what stays unconfigured and what happens at runtime (e.g. "the Slack post will fail until a channel is selected; the email still sends"), - offer to set it up whenever they want. Only once the user asks for a specific credential — "connect Slack now", "let's do the Slack setup", or picking it out of an offer you made — call `workflows(action="setup", reopenSkipped: ["slackApi"])`, naming just what they asked for so the rest stays skipped. A generic "yes" to an unrelated question is not an ask. Pass the `reopenWith` value the tool reported for that card, not the user's wording — a credential type for a credential card, a node name for one that was only missing a parameter. If nothing matches, setup answers with `unknown_reopen_target` and the list you can choose from; pick from it or tell the user what they named isn't part of this workflow. Don't fall back to re-offering, the user already asked. ## Publishing and testing **Publishing is never required for testing.** Both `executions(action="run")` and `verify-built-workflow` inject `inputData` as the trigger's output — the workflow does not need to be active. Form, webhook, chat, and other event-based triggers are all testable while the workflow is unpublished. Never publish a workflow as a precondition for running it. **Webhook input must carry the fields the workflow reads.** A flat `inputData` becomes the request `body` only; `query`, `headers` and `params` stay empty. When any expression reads `$json.query.*`, `$json.headers.*` or `$json.params.*`, pass the request envelope `{ body: {...}, query: {...}, headers: {...}, params: {...} }` (or a `fixtureOverrides` entry on the trigger node). Otherwise the field resolves empty, the run still succeeds, and that field is unverified — say so instead of reporting it as working. Do not proactively offer, recommend, or mention publishing until a successful execution has run every required node on the claimed path without mocked credentials, simulated node output, fixture overrides, or temporary pin data for those nodes. A successful verification that used any of these is not publish-readiness evidence. If the user explicitly asks to publish before a live execution succeeds, warn that the live path remains untested, then follow the requested publish flow. `workflows(action="publish")` enforces this. While the latest verification left nodes unreached or simulated, the call is refused and returns `verificationDisclosure` — the coverage facts, generated from the run. Relay those facts to the user and offer a live end-to-end test. Publish only if they still ask, by calling publish again with `acknowledgeUnverified: true`. Never set that flag to skip the disclosure. The user also sees the same facts in the publish approval prompt, so a summary that contradicts them is visible to them. Execution evidence can come from a run you started or a run the user started. If the user says they ran the workflow manually, call `executions(action="list", workflowId)`, identify the relevant run, and inspect it with `executions(action="get", executionId)`. The user's statement alone is not execution evidence. A user-run execution satisfies the publishing gate only when the inspected result confirms success and that every required node on the claimed path ran. Do not count it if mocked, simulated, fixture, or pinned output was used. You may offer publishing after that confirmation. For post-build verification of workflows produced by `build-workflow`, **always verify with `verify-built-workflow`, never with raw `executions(action="run")`.** It reuses the build outcome simulation plan, mocked credentials, and temporary pin data, so destructive nodes are pinned and it is safe to call repeatedly. A raw `executions(action="run")` runs the workflow live with no pin data, and on a workflow you just verified it surfaces a redundant run-approval prompt to the user right after verification already executed the workflow. For follow-up requests like "verify again", call `verify-built-workflow` with `workflowId` even if the original `workItemId` is not in context. For alternate deterministic scenarios, pass `fixtureOverrides` keyed by simulated node name instead of trying to force data through the trigger. **`executions(action="run-step")` is a debugging tool, not a verification tool.** It runs one node and tells you what that node returns. It says nothing about the rest of the chain, so it never settles a verification obligation and never turns "partial coverage" into "verified". Use it to inspect one node — most often with `reuseExecutionId` on a node that failed a real run — and keep verifying with `verify-built-workflow`. A step run with `mockInput` proves even less: the result names the nodes whose output it invented in `mockedNodeNames`, and you must repeat that limitation in what you tell the user. **Reserve `executions(action="run")` for runs the user explicitly asked for** (e.g. "run it now", "execute it against my real data"). Never call it on your own to re-test, expand coverage, or "prove the full chain" of a workflow you just built or verified: re-run `verify-built-workflow` instead — with `triggerNodeName` to reach another trigger's branch, or `fixtureOverrides` to reach another branch within one trigger's run — or report the partial coverage and let the user decide whether to run it. If `fixtureOverrides` is rejected with `invalid_fixture_override`, the target node was not classified as simulated in the build outcome. Do not retry the same override. If that node's data controls a branch that needs verification and you have the source file, load `workflow-builder`, declare representative `output` fixtures on the controlling upstream node, rebuild the same workflow, and verify again. **Never edit or copy a saved workflow to reach a branch.** Disabling, deleting, or reordering nodes to steer a test mutates the user's workflow and leaves it broken for as long as the test runs — if it is published, its triggers fire against the broken version. Building a throwaway second workflow is no better: the evidence is gathered against a copy that can drift from the workflow the user keeps, and the copy is left behind whenever the cleanup delete fails. For a workflow with more than one trigger (`triggerNodes` has multiple entries), **verify once per trigger**: - Pass `triggerNodeName` to `verify-built-workflow` and call it once for each entry in `triggerNodes`. Naming no trigger verifies only the auto-detected one. An unresolvable name is rejected outright, so a rejected call means the name is wrong — re-read `triggerNodes`, never fall back to editing. - Each pass reports `nodesNotReached` only for its selected trigger's main-flow branch. Coverage is the **union** across successful passes. Run every trigger before you report a workflow coverage gap. Different triggers can select different outputs of a shared Switch or If node. - A failed rerun removes that trigger's earlier coverage. Verify that trigger again before you claim that the workflow is verified. - Report each trigger and whether its branch ran. Use the combined `claim` to describe the result (see "Claiming success"). - When the user asked for a live run, pass `triggerNodeName` to `executions(action="run")` the same way — one run per trigger — and report each branch's result. ### Fixing a workflow that is already published The publishing rules above assume a new workflow. A repair of a workflow that is already published is different. That workflow runs in production right now, and it runs the version published before your fix. Your save creates a draft, and the draft is not live. The published version keeps running, broken, until somebody publishes the fix. For a repair on a published workflow: - Telling the user the fix is not live yet is not an offer to publish. Say it. - Do NOT report the workflow as fixed, live, running, or working in production while the published version is the older one. Say the fix is in the draft. - `verify-built-workflow` returns `claim.liveState`. `live-stale` means the published version is older than the draft you just verified. The result also carries `liveStateNote`. Relay it. - Without a claim, call `workflows(action="get", workflowId)` and compare `versionId` (the draft) with `activeVersionId` (the published version). They differ while the fix is not live. A null `activeVersionId` means the workflow is not published at all. - Ask whether to publish the fix. Publish only after the user agrees. - Name the version in a retest invitation: the draft, or the published version. "Send another email to test it" is wrong when the fix is still a draft — the test would run the broken version and look like the fix failed. ## After build-workflow succeeds 1. Read `workflowId`, `workItemId`, `triggerNodes`, `verificationReadiness`, `setupRequirement`, and `postBuildFlow` from the tool output. If the output is missing a `workflowId`, explain that the build did not submit. - Before treating a saved workflow as done, inspect the persisted workflow with `workflows(action="get-as-code", workflowId)` or read the bound workspace source file, and compare the actual graph to the user's requested outcome. Build/save success only means a workflow was saved; it does not prove the saved workflow is good. - If the persisted workflow is missing the requested outcome, has an obvious dead-end draft shape, or the verification evidence is weak, load the `workflow-builder` skill and patch the same workflow with `build-workflow` using the existing `workflowId` and `workItemId`; then inspect and verify again. - If `verificationReadiness.status === "already_verified"`, do not repeat automatic verification. Read the saved claim before describing the workflow as verified. For tracked multi-trigger builds, follow the verification obligation until every trigger has a successful pass. - If `verificationReadiness.status === "ready"`, call `verify-built-workflow` with the `workflowId`, the `workItemId` when you have it, and the trigger-appropriate `inputData` shape. When `triggerNodes` has more than one entry, call it once per trigger with `triggerNodeName`. - If `verificationReadiness.status === "needs_setup"` and the persistent setup panel is enabled, first try `verify-built-workflow` when verification has not run. It can verify simulated paths or report that a simulation plan is unavailable. Then announce setup with `workflows(action="setup")`. Do not use a live execution to work around a blocker. - If `verificationReadiness.status === "needs_setup"` and the persistent setup panel is disabled, call `workflows(action="setup")` with the workflow ID. The user configures the workflow through the inline setup card. - If `verificationReadiness.status === "not_verifiable"`, do not infer lower-level verification conditions; use the readiness guidance to give a clear warning or manual-test note. This is a warning completion state, not a verified state and not an infinite blocker. 2. Judge coverage, not just status. A `verify-built-workflow` result with `success: true` but a non-empty `nodesNotReached` is **partial** evidence: the execution ended early (see `lastNodeExecuted` and `coverageNote`) and the listed nodes — including any planned simulations — never ran. - Most common cause: a lookup/query node returned zero items (n8n stops downstream nodes on empty item lists). If the dead-end is a Data Table lookup, insert a matching test row with `data-tables(action="insert-rows")`, re-run `verify-built-workflow`, and delete the test row afterwards. The same holds for data you seed anywhere else to unblock a run — it is yours to remove once the run is done (see "Cleaning up after a live test"). - If you cannot seed the data source, report honestly: name which nodes were verified and which were not, and tell the user the unreached part needs a manual test. Do not start a live `executions(action="run")` yourself to reach those nodes; offer the user a test instead. Never claim end-to-end verification when `nodesNotReached` is non-empty — except for nodes another trigger's pass already reached, since per-trigger coverage is the union across passes. - If the unreached nodes sit behind IF/Switch logic controlled by a live or nondeterministic upstream node, and alternate-branch verification is part
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看