From 37fa3c58b40e240974c0b3d1eb9e8f78d53892b1 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sat, 20 Jun 2026 19:12:15 -0700 Subject: [PATCH] docs(kanban-worker): document kanban_complete artifacts deliverable param (#49854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kanban-worker skill taught kanban_complete with three full examples but never mentioned the artifacts=[...] parameter added in #27813 — so a worker reading the skill had no way to learn it can ship a chart/PDF/image as a native upload to the subscriber's chat. Adds a 'Shipping deliverables' section covering absolute-path rules, the inline-vs-file extension behavior, and the trap that the notifier reads the top-level artifacts list (NOT metadata.*). --- skills/devops/kanban-worker/SKILL.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/skills/devops/kanban-worker/SKILL.md b/skills/devops/kanban-worker/SKILL.md index 7dd64ad55e3..c9e91504e89 100644 --- a/skills/devops/kanban-worker/SKILL.md +++ b/skills/devops/kanban-worker/SKILL.md @@ -100,6 +100,27 @@ kanban_complete( Shape `metadata` so downstream parsers (reviewers, aggregators, schedulers) can use it without re-reading your prose. +## Shipping deliverables (`artifacts=[...]`) + +If your task produced files a human actually wants — a chart, a PDF, a spreadsheet, a generated image, an archive — pass their **absolute paths** to `kanban_complete(artifacts=[...])`. The gateway notifier uploads each one as a native attachment to whoever subscribed to the task, so the deliverable lands in their chat alongside the completion message instead of being a path they have to go fetch. + +```python +kanban_complete( + summary="Q3 revenue analysis: 14% QoQ growth, EMEA the laggard. Chart + full PDF attached.", + artifacts=["/tmp/q3-revenue.png", "/tmp/q3-report.pdf"], + metadata={"rows_analyzed": 48000, "growth_qoq": 0.14}, +) +``` + +Images and video embed inline; PDFs, docx, csv/xlsx/json/yaml, pptx, zip/tar/gz, audio, and html upload as files. Rules: + +- **Absolute paths only**, and the file must still exist when you complete — don't point at a scratch file you already deleted. +- **Only real deliverables.** Skip intermediate logs, scratch files, and inputs the human already has. +- `artifacts` is the **top-level** parameter the notifier reads. Do not bury deliverable paths in `metadata` (e.g. `metadata.codex_lane.artifacts`) and expect them to upload — the notifier only scans the top-level `artifacts` list, with a best-effort fallback over your `summary`/`result` text. Metadata paths are for downstream-worker bookkeeping, not delivery. +- A bare string is auto-promoted to a one-element list, and it merges with any pre-existing `metadata.artifacts` without dupes. + +Same primitive works outside kanban: any agent surface delivers a file just by writing its absolute path into the response, and Slack/Discord/Telegram/etc. upload it natively — the `artifacts` param is the structured kanban entry point. + ## Claiming cards you actually created If your run produced new kanban tasks (via `kanban_create`), pass the ids in `created_cards` on `kanban_complete`. The kernel verifies each id exists and was created by your profile; any phantom id blocks the completion with an error listing what went wrong, and the rejected attempt is permanently recorded on the task's event log. **Only list ids you captured from a successful `kanban_create` return value — never invent ids from prose, never paste ids from earlier runs, never claim cards another worker created.**