* cargo-orchestration 1.7.0: draw the workflow
Nothing in the bundle told an agent to show a node graph as a picture. The
only nudge was one line in interaction.md — "a compact node-flow sketch or
table beats prose" — which left the format to the model, so the plan gate
asked users to approve a graph they had to reconstruct from prose. Every
surface these skills print into renders Mermaid.
- references/node-diagram.md: when to draw one (plan gate, "what does this
play do", trace reporting), when not to, the shape/edge mapping per node
kind, cost marking, and the rules that make a diagram true.
- scripts/workflow-to-mermaid.ts: zero-dep TS (Node >= 22.18, 6 fixture
cases) taking release get / get-draft / template get / an ad-hoc run get /
a raw node array. Flags: --title, --direction, --paid, --highlight.
- Two doc defects found against a live workspace: release get's documented
nodes[] was a {uuid, slug, name} summary of the full graph it actually
returns, and run get carries nodes XOR releaseUuid depending on whether
the run came from a deployed release.
- Node slugs are not unique within a release (six `variables` in one shipped
waterfall), so anything walking the graph keys on uuid. Recorded as router
gotchas, with the knock-on for {{nodes.<slug>...}} ambiguity.
- Call sites wired: plan gate and presenting defaults, router rules,
nodes.md, the diagnostics trace runbook, and cdk plan.
- CI runs fixtures for every cargo-*/scripts/*.ts, not only cargo-gtm's.
Verified against CLI 1.0.52: every diagram in the reference is script output
from a real release, and each parses under mermaid 11.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Move the diagram generator into the CLI
`cargo-ai orchestration node diagram` replaces the skill script the reference
was prototyped against. It belongs next to `node validate` — same input, same
free/runs-nothing character — and the sequence now reads validate → diagram →
deploy without leaving the CLI.
- scripts/workflow-to-mermaid.ts and its fixtures deleted; the CI fixture glob
goes back to cargo-gtm/scripts/*.ts.
- node-diagram.md documents the command: one source per call (--nodes / --file
/ --workflow-uuid / --draft / --release-uuid / --run-uuid), the JSON shape,
and reading `warnings` out loud rather than drawing over a broken graph.
- --run-uuid absorbs the nodes-XOR-releaseUuid split, so the diagnostics
runbook no longer has to explain which kind of run it was handed.
- Requires CLI >= 1.0.54 (getcargohq/cargo#5580); the cli-version pin moves in
the follow-up that ships with that release.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Refresh skill-metadata content hashes after rebase
The rebase onto main took both sides of the version conflicts in cargo/SKILL.md
and cargo-orchestration/SKILL.md (this branch's 1.20.0 / 1.7.0, which stay ahead
of main's 1.19.2 / 1.6.3), which left the recorded contentHash in the two
skill-metadata.json files stale. Regenerated with skills-metadata.mjs --write;
skills-lint is back to 0 errors.
Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
7.7 KiB
Run trace — explain one run end-to-end
Use this when you have (or can find) a single run UUID and need to answer "what actually happened to this record?" — a hard failure, or the more common case: status: "success" with wrong or empty output.
Field-by-field semantics for everything used here live in
../../cargo-orchestration/references/troubleshooting.md("Debugging a workflow run"). This runbook is the ordered procedure.
0. Find the run
Every step below needs a run UUID. Work down this ladder and stop at the first rung that matches what the user actually gave you — most of the time it's a symptom and a company name, not a UUID.
run listcannot answer "the last run".cargo-ai orchestration run listrequires--workflow-uuid; there is no unfiltered form, and a play's UUID is not a workflow UUID. Orchestration SQL has no such requirement, so it — notrun list— is the entry point whenever you don't already know the workflow. Concluding "the run data isn't accessible" becauserun listrefused is a wrong answer:runsis queryable with no filter at all.
"Look at the last run" / "what just ran" — no UUID, no workflow, nothing:
cargo-ai orchestration query execute \
"SELECT uuid, workflow_uuid, record_title, status, created_at
FROM runs
ORDER BY created_at DESC
LIMIT 10"
A company, domain, or record the user names ("the run for acme.com") — record_title carries the record's title, or for record-less runs the input payload, so a substring match finds it:
cargo-ai orchestration query execute \
"SELECT uuid, workflow_uuid, record_title, status, created_at
FROM runs
WHERE record_title ILIKE '%acme.com%'
ORDER BY created_at DESC
LIMIT 10"
A play or workflow by name — resolve to a workflowUuid first, then filter. runs has no play column, so this hop is mandatory:
cargo-ai orchestration play list # → find the play, take play.workflowUuid
cargo-ai orchestration query execute \
"SELECT uuid, status, created_at, credits_used_count
FROM runs
WHERE workflow_uuid = '<play.workflowUuid>'
ORDER BY created_at DESC
LIMIT 20"
Play anatomy and the rest of the play surface: ../../cargo-orchestration/references/examples/plays.md.
Coming from a batch sweep — you already have exemplar UUIDs; skip ahead.
When the discovery query itself errors
| Error | Cause and fix |
|---|---|
Limit for number of columns to read exceeded. Requested: 51, maximum: 50. |
You ran SELECT *. runs is wider than the 50-column read cap — name the columns you need, as every query above does. |
Unknown expression identifier '<col>' |
That column doesn't exist. runs has no play_uuid, no name, and no trigger-source column; the ones used here (uuid, workflow_uuid, release_uuid, batch_uuid, record_id, record_title, status, created_at, credits_used_count) are confirmed present. |
Where a run was triggered from — the CLI, a scheduled play, or a click in the UI editor — is not supposed to change where it lands: all of them write to runs and are readable with run get. So a run the user can see in the UI but that none of these queries return is a real bug, not a boundary you should work around or explain away. Say so and file a report (skill § "When diagnosis dead-ends"), quoting the queries you ran.
1. Pull the trace
cargo-ai orchestration run get <run-uuid>
Read three fields, in this order:
run.executions[]— the node-by-node path. For each node:nodeSlug,status,nextNodeUuid,nodeChildIndex,creditsUsedCount. This tells you where execution went, including which child abranchtook (nodeChildIndex0= matched/yes,1= not matched/no).runContext— per-node output keyed bynodeSlug. This is the actual data downstream expressions saw as{{nodes.<slug>...}}. It is the source of truth; thetitleon an execution is a truncated summary, never evidence.runComputedConfigs— what each node was actually called with after expression resolution. When a node received garbage, this shows the garbage.
Don't paste the raw response into the conversation — extract the two or three nodes that matter (see "Presenting" below).
2. Diagnose by symptom
| Symptom | Where to look | Typical conclusion |
|---|---|---|
Run error |
First executions[] item with status: "error"; its runContext.<slug> entry carries the error detail |
Failing node identified — match it against the error-pattern table in troubleshooting.md ("Run error recovery") |
Run success, output empty |
runContext.<upstreamSlug> of the node that produced the empty value |
Expression path doesn't exist — commonly agent output nested under .answer ({{nodes.qualify.answer.qualified}}, not {{nodes.qualify.qualified}}) |
| Wrong branch taken | The branch node's nodeChildIndex + the runContext of the node its condition references |
Condition resolved falsy because the referenced path is missing/undefined — verify the real shape in runContext |
| Connector node "worked" but downstream empty | runContext.<connectorSlug> |
Partial provider response; the real field names differ from the ones referenced (e.g. contact.email vs email) |
| One node absurdly slow | Spans timing query below | Rate-limited or retrying connector; see the batch-sizing section of troubleshooting.md |
Per-node timing for the slow-node case:
cargo-ai orchestration query execute \
"SELECT node_slug, execution_status,
dateDiff('second', execution_started_at, execution_finished_at) AS duration_s
FROM spans
WHERE run_uuid = '<run-uuid>'
ORDER BY duration_s DESC"
3. Confirm the fix on the same record
Stage → approve → deploy → re-run the exact record IDs that exposed the bug — the command sequence is in troubleshooting.md ("Re-run a single record after fixing"). Re-running paid nodes counts as a paid action: pilot gate + receipt per ../../cargo-gtm/references/cost-discipline.md.
Presenting a trace
Per ../../cargo/references/interaction.md: conclusion first, then a compact path table — one row per relevant node (nodeSlug → status → the one field that matters), then the recommended fix. Example shape:
The run "succeeded" but the branch took the no-path: the condition reads
{{nodes.qualify.qualified}}, but the agent's output is nested under .answer.
| node | status | evidence |
|-----------|---------|--------------------------------------------------|
| qualify | success | runContext.qualify.answer.qualified = true |
| branch_1 | success | nodeChildIndex = 1 (no-path) — condition falsy |
Fix: change the condition to {{nodes.qualify.answer.qualified}} and re-run
record <id> to confirm (1 record ≈ <n> credits).
For a wrong-branch or wrong-path diagnosis, add the graph with the offending node marked — the user has to see the fork to agree the run went down the wrong side of it:
cargo-ai orchestration node diagram --run-uuid <run-uuid> --highlight branch_1 --raw
Free, runs nothing, and it works for either run shape — an ad-hoc action execute
run carries its own nodes, a run of a deployed tool or play carries only a
releaseUuid, and --run-uuid follows whichever it has. Flags and mapping rules:
../../cargo-orchestration/references/node-diagram.md.