Skip to content

design-artifact

design-artifact authors a designed, self-contained HTML page and publishes it to the canvas: a run report, an audit briefing, a chart, a small dashboard. A single agent node reads the canvas design guide, writes one token-themed page in the keelson palette from your request, and publishes it through canvas_publish, which validates any declared chart palette fail-closed before the page reaches the drawer. It is the reference shape for turning data or findings into a shareable page, and the smallest workflow in the catalog: one node that does the whole job.

The two tools it uses, canvas_publish and canvas_design_guide, are core harness primitives, not a rib’s, so the workflow runs on any registered provider with nothing extra installed. For live operational status a rib already renders as a board, open that surface instead; an artifact earns its place when the deliverable is a designed page someone will read, keep, or share.

Terminal window
keelson workflow run design-artifact --inputs ARGUMENTS="a briefing on this week's merged PRs"
keelson workflow run design-artifact --inputs ARGUMENTS="chart the last 30 days of token usage by model"

It pins no provider, so it runs against whatever the server registered. A page’s quality tracks the authoring model, so author runs the deep tier at effort: xhigh, and on Copilot it pins gpt-6-astra. Set provider: in the file (or KEELSON_WORKFLOW_PROVIDER) to author somewhere else. Unlike the GitHub-facing workflows it needs no gh CLI, no approval gate, and no human pause; any provider with the tool registry can run it.

One node, author, does the whole job. There is no DAG to draw: read the guide, write the page, publish it, and fix-and-republish on a rejected palette all happen inside a single agent turn. The iteration is the model’s, not the executor’s, so the workflow is one node rather than a read, author, validate, retry chain of them.

NodeKindWhat it does
authorpromptReads canvas_design_guide (kit, voice, and page, plus form and color when the page carries a chart and graphics when it carries a diagram), authors one self-contained page on the kit from $ARGUMENTS, checks the draft once against anti-patterns, and publishes it with canvas_publish, retrying on a rejected palette. Capped to canvas_publish and canvas_design_guide, bounded by a 30-minute idle timeout.

The publish gate is fail-closed. canvas_publish validates any palette the page declares on <body data-palette-dark="…" data-palette-light="…">, checking color-vision-deficiency separation and surface contrast per theme, and rejects a hard failure with a per-check report. The palette is checked by computation, never by eyeball, so a page cannot reach the drawer with an inaccessible chart.

A rejection self-corrects, it does not abort. The author node leaves fail_on_tool_error at its default (off), so a rejected palette comes back as a tool error the node reads and acts on: it fixes the colors, prefers the keelson series slots, and publishes again in the same turn. The workflow finishes green because the author corrected, not because the check was skipped.

Publication is required when the tool is available. require_tool_call: [canvas_publish] checks the observed tool results, not the author’s final prose. If canvas_publish is registered but the turn ends without a successful result, the node fails and names the missing tool. The check skips an unavailable canvas catalog for headless runs; otherwise, a green run means the artifact was published.

One page, both themes. The page starts from the kit’s stylesheet: keelson’s dark values on :root, light overrides on :root[data-theme="light"], a system font stack, and no external resources. It re-themes with the app and renders inside the sandboxed canvas frame whose CSP blocks all network egress.

The provider is deliberately open. No provider:/model: pin, because artifact quality tracks the authoring model. It is the mirror image of the review workflows, which pin down to a deterministic coding model; here you pin up to your strongest one, or leave it open to ride the server default.

  • Bound an agent’s reach: allowed_tools: [canvas_publish, canvas_design_guide] caps the node to exactly the two canvas tools.
  • Fail-closed tool validation: the palette check inside canvas_publish gates the output, and the unset fail_on_tool_error default lets the node self-correct on a rejection instead of failing the run.
  • A single-node workflow: when the loop is the model’s own (read, author, retry), the DAG collapses to one prompt node with the right tool rail.
  • Pin the author. Add provider:/model: (or set KEELSON_WORKFLOW_PROVIDER) to route authoring at your strongest model, the one adjustment this workflow most rewards.
  • Fold it into a bigger workflow. Drop the author node, its two tools and its prompt, at the tail of another pipeline so a run publishes its own designed report from the artifacts it just produced.
  • Restyle the page. The page inlines keelson’s design tokens; change the CSS custom-property values the prompt seeds to reskin the output. The palette validator still gates any declared chart series.
  • Canvas artifacts: the publishing contract, the design tokens, and the fail-closed validation in full.
  • Snapshots and surfaces: the canvas surface this page publishes into, and the streaming substrate behind it.
  • Workflow nodes: the prompt node, allowed_tools, and fail_on_tool_error.