You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(demos): deleted-lineage demo (D2) + a previewable dynamic node (D3)
D2 — a new "Deleted custom node" demo that ships ALREADY tombstoned: the seeder
publishes a lineage, builds a workflow on it, then soft-deletes the lineage.
The reader opens it and sees the red Deleted badge, the "(deleted dynamic node)"
alert and the "Activity type not registered" error, with no destructive step and
nothing consumed for whoever walks next. Its guide steps name the D-11 gap
(Try/Run stay enabled) and the catalog-load timing that made me misread this
check the first time.
D3 — the Part-14 dynamic node is now tagged `@deterministic true` AND binds its
output to a ctx key. Both were needed: without the tag the script is treated as
non-deterministic and deliberately never cached, so there is nothing to preview;
without the binding the widget honestly reports "this step's output isn't bound
to a workflow value yet". With both, 14.9 finally shows what it promises —
{"fileName":"901E42EB-7094-4B67-B7FA-FD62618D2208-WALK-14-9.PDF"}.
That also sharpens D-12. The bogus "cache evicted — re-run to repopulate"
message appears specifically for a node that is never cached, so the fix is to
say "not cached: this node is non-deterministic" rather than to blame an
eviction that never happened.
14.9 ticked. 14.8's observable halves all pass on the new demo; it stays open
only on D-11's "Try disabled" criterion.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1. Right-click the node → **Edit script** opens the script editor with the published TypeScript source (JSDoc `@inputs`/`@outputs` drive the ports).
216
217
1.**+ New custom node** (palette) opens the authoring editor — publishing runs the jsdoc → signature → ts-check → allowlist gates (`MANUAL_TEST_PLAN.md` Part 14).
217
218
1.**Delete + re-create restores the node:** delete this custom node (**Dynamic nodes** page), then **+ New custom node** and publish the *same* name — it comes back with its history continued (v2), instead of dead-ending on a reserved-slug conflict (14.14).
219
+
1.**Try it (14.9):** the script is tagged `@deterministic true`, so its output is **cached** and the node shows a real **preview** after a run — an untagged (non-deterministic) script re-executes every run and is deliberately never cached, so it has no preview to show.
218
220
1. ⚠️ *Executing* this node in a run additionally needs the Temporal worker started with `PLATFORM_API_KEY` (14.9).
1. This workflow references a custom node whose **lineage has been deleted**. Nothing to set up — it ships in that state.
229
+
1. The canvas node carries a red **Deleted** badge and its settings show *(deleted dynamic node)*.
230
+
1. The validation chip reads **1 error** — *Activity type `dyn.demo-deleted-node` is not registered*. Give the activity catalog a moment to load: `dyn.*` types are deliberately given the benefit of the doubt while it is still fetching, so the error appears a beat after the canvas.
231
+
1. ⚠️ **Known gap (D-11):****Try** and **Run** are still enabled here even though the graph cannot run — a run fails at `dynamicNode.resolveLineage`. Whether *any* validation error should disable Try, or only errors that make the graph structurally unrunnable, is an open product decision.
232
+
1. Restoring it is one step: publish a node with the **same name** from **Dynamic nodes ▸ New custom node** and the lineage comes back with its history continued (14.14).
233
+
234
+
---
235
+
222
236
## 🤖 AI agent chat logs
223
237
224
238
Transcripts captured from **real live runs** of the workflow agent (Azure gpt-5.4). Open the demo link — the workflow the agent built loads on the canvas **and** the agent drawer opens and **replays** the whole conversation (your prompt + every tool call it made) beside it, so you can see the result and how it was built in one place.
Copy file name to clipboardExpand all lines: docs-md/workflows/MANUAL_TEST_PLAN.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -606,7 +606,7 @@ One `source.api` and one `source.upload` max per workflow.
606
606
-[ ]**14.8 In-canvas custom node.** Palette **Custom** section → **New custom node** modal → publish → node auto-drops as `dyn.<slug>` with a grape **DYN** badge. Right-click a `dyn.*` node → **Edit script**. **Pass:** deleted-lineage node shows a red **Deleted** badge, settings Alert, Try disabled.
607
607
608
608
### Execute + security
609
-
-[]**14.9 Execute (Try).** Build `source.api → dyn.uppercase-url`, wire `document`, Save → **Try** with `{"documentUrl":"https://example.com/foo.pdf"}`. **Pass:** node goes blue→green; preview shows the uppercased URL. Publish v2 (reverse) → Try → cache miss → preview shows reversed URL.
609
+
-[x]**14.9 Execute (Try).** Build `source.api → dyn.uppercase-url`, wire `document`, Save → **Try** with `{"documentUrl":"https://example.com/foo.pdf"}`. **Pass:** node goes blue→green; preview shows the uppercased URL. Publish v2 (reverse) → Try → cache miss → preview shows reversed URL.
610
610
-[x]**14.10 Runtime errors.** Script `throw` → `errorMessage` prefixed `[DynamicNodeRuntimeError] exitCode=1 …`; timeout (>60s) / stdout >5MB / invalid JSON / missing output port each map to their typed error (truncated 2KB).
611
611
-[x]**14.11 🔒 Network egress blocked.** Publish/run a node doing `await fetch("https://blocked.example.com")` with that host **not** in `DYNAMIC_NODE_ALLOW_NET`. Fast path — hit the runner directly:
Copy file name to clipboardExpand all lines: feature-docs/20260724-workflow-builder-spec-completion/COVERAGE_GAP_LOG.md
+9-2Lines changed: 9 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,13 @@ Create, Publish, Author, Drag, Declare); only **10 of 16 parts** carry a
26
26
27
27
## G1 — Demos to seed (`scripts/seed-feature-demos.mjs`)
28
28
29
+
> **D1–D4 shipped.** D2 is a *Deleted custom node* demo that ships already
30
+
> tombstoned — red **Deleted** badge, `(deleted dynamic node)` alert and the
31
+
> catalog error, with no destructive step for the reader. D3 tagged the Part-14
32
+
> dynamic node `@deterministic true`**and bound its output**, which is what
33
+
> makes 14.9's preview show the real value:
34
+
> `{"fileName":"901E42EB-…-WALK-14-9.PDF"}`.
35
+
>
29
36
> **D1 + D4 shipped.** The Part-10 library demo now declares a typed signature
30
37
> (input *Prepared file*`PreparedFile`, output *OCR result*`OcrResult`) and
31
38
> carries **two versions**. That unblocked 7.8, 10.4, 12.4 and 12.5 in one
@@ -35,8 +42,8 @@ Create, Publish, Author, Drag, Declare); only **10 of 16 parts** carry a
35
42
| # | Demo | Covers | Why it's a gap | Size |
36
43
|---|---|---|---|---|
37
44
|~~**D1**~~ ✅ **DONE**|**Library workflow with typed ports** — declare an input `kind: PreparedFile` and an output `kind: DocumentContent`|**7.8**, and enriches Part 10 | 7.8 is the only check for typed library ports, and no seeded library declares a `kind`. I had to author `WALK-7.8 typed ports` to walk it at all | S |
38
-
|**D2**|**Workflow referencing a deleted `dyn.*` lineage**, seeded already-deleted |**14.8** (deleted half) | The plan asks you to delete a lineage yourself — destructive, and it consumes the Part-14 demo for the next walker. Seeded in the end state, the user just opens it and sees the red **DELETED** badge, the settings alert and the validator error | S |
39
-
|**D3**|**Runnable dynamic node** — extend the existing Part-14 demo rather than add one |**14.9**| 14.9 says "build `source.api → dyn.uppercase-url`". The existing Part-14 demo shows the DYN pill and script editor but is not wired to run. Also the natural home for **D-12** once the preview message is fixed | M |
45
+
|~~**D2**~~ ✅ **DONE**|**Workflow referencing a deleted `dyn.*` lineage**, seeded already-deleted |**14.8** (deleted half) | The plan asks you to delete a lineage yourself — destructive, and it consumes the Part-14 demo for the next walker. Seeded in the end state, the user just opens it and sees the red **DELETED** badge, the settings alert and the validator error | S |
46
+
|~~**D3**~~ ✅ **DONE**|**Runnable dynamic node** — extend the existing Part-14 demo rather than add one |**14.9**| 14.9 says "build `source.api → dyn.uppercase-url`". The existing Part-14 demo shows the DYN pill and script editor but is not wired to run. Also the natural home for **D-12** once the preview message is fixed | M |
40
47
41
48
|~~**D4**~~ ✅ **DONE**|**Part-10 demo library needs declared ports and a second version**|**7.8**, **12.5**, **10.4**| The seeded `Demo — Library workflow (Part 10)` declares **0 inputs / 0 outputs**, so the childWorkflow signature summary renders empty — nothing to look at. It also has **only one version**, so 12.5's "pick `v2` → stamps `version:2`" cannot be walked at all. Giving this one demo typed ports and a v2 closes D1 as well | S |
"This workflow references a custom node whose **lineage has been deleted**. Nothing to set up — it ships in that state.",
1588
+
"The canvas node carries a red **Deleted** badge and its settings show *(deleted dynamic node)*.",
1589
+
"The validation chip reads **1 error** — *Activity type `dyn.demo-deleted-node` is not registered*. Give the activity catalog a moment to load: `dyn.*` types are deliberately given the benefit of the doubt while it is still fetching, so the error appears a beat after the canvas.",
1590
+
"⚠️ **Known gap (D-11):** **Try** and **Run** are still enabled here even though the graph cannot run — a run fails at `dynamicNode.resolveLineage`. Whether *any* validation error should disable Try, or only errors that make the graph structurally unrunnable, is an open product decision.",
1591
+
"Restoring it is one step: publish a node with the **same name** from **Dynamic nodes ▸ New custom node** and the lineage comes back with its history continued (14.14).",
1592
+
];
1593
+
1513
1594
constDYN_DEMO_STEPS=[
1514
1595
"The **CUSTOM** section of the activity palette lists **demo-uppercase** with a **DYN** badge — click it to drop another instance.",
1515
1596
"The canvas node carries a purple **DYN** pill; select it → the Inputs section shows its `document` port bound to *Prepare*'s output.",
1516
1597
"Right-click the node → **Edit script** opens the script editor with the published TypeScript source (JSDoc `@inputs`/`@outputs` drive the ports).",
1517
1598
"**+ New custom node** (palette) opens the authoring editor — publishing runs the jsdoc → signature → ts-check → allowlist gates (`MANUAL_TEST_PLAN.md` Part 14).",
1518
1599
"**Delete + re-create restores the node:** delete this custom node (**Dynamic nodes** page), then **+ New custom node** and publish the *same* name — it comes back with its history continued (v2), instead of dead-ending on a reserved-slug conflict (14.14).",
1600
+
"**Try it (14.9):** the script is tagged `@deterministic true`, so its output is **cached** and the node shows a real **preview** after a run — an untagged (non-deterministic) script re-executes every run and is deliberately never cached, so it has no preview to show.",
1519
1601
"⚠️ *Executing* this node in a run additionally needs the Temporal worker started with `PLATFORM_API_KEY` (14.9).",
1520
1602
];
1521
1603
@@ -1582,6 +1664,48 @@ async function createDemo(demo) {
1582
1664
* Returns its guide-result row, or null when the dynamic node couldn't be
1583
1665
* published.
1584
1666
*/
1667
+
/**
1668
+
* D2 — publish a lineage, build a workflow on it, then soft-delete the
1669
+
* lineage so the demo ships already broken. Best-effort like its sibling: no
1670
+
* deno-runner means no publish, so the demo is skipped rather than failing the
0 commit comments