@runcofactor/cli 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +125 -0
  2. package/dist/api-catalog-GFGCLVS4.js +401 -0
  3. package/dist/api-catalog-GFGCLVS4.js.map +1 -0
  4. package/dist/attachment-SJC7D7FY.js +276 -0
  5. package/dist/attachment-SJC7D7FY.js.map +1 -0
  6. package/dist/auth-EN6NQCJY.js +31 -0
  7. package/dist/auth-EN6NQCJY.js.map +1 -0
  8. package/dist/bin.js +7 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/chunk-3CZU7XCS.js +272 -0
  11. package/dist/chunk-3CZU7XCS.js.map +1 -0
  12. package/dist/chunk-4NRDONSC.js +1048 -0
  13. package/dist/chunk-4NRDONSC.js.map +1 -0
  14. package/dist/chunk-4PNOV7OV.js +51980 -0
  15. package/dist/chunk-4PNOV7OV.js.map +1 -0
  16. package/dist/chunk-52IO7ACJ.js +2941 -0
  17. package/dist/chunk-52IO7ACJ.js.map +1 -0
  18. package/dist/chunk-6LEZCKKV.js +663 -0
  19. package/dist/chunk-6LEZCKKV.js.map +1 -0
  20. package/dist/chunk-A4OFTUVV.js +170 -0
  21. package/dist/chunk-A4OFTUVV.js.map +1 -0
  22. package/dist/chunk-B2VISN2V.js +2459 -0
  23. package/dist/chunk-B2VISN2V.js.map +1 -0
  24. package/dist/chunk-CLAWT7BJ.js +271 -0
  25. package/dist/chunk-CLAWT7BJ.js.map +1 -0
  26. package/dist/chunk-GKY2KXO5.js +281 -0
  27. package/dist/chunk-GKY2KXO5.js.map +1 -0
  28. package/dist/chunk-I4QLI3JO.js +413 -0
  29. package/dist/chunk-I4QLI3JO.js.map +1 -0
  30. package/dist/chunk-IMPZAX6L.js +180 -0
  31. package/dist/chunk-IMPZAX6L.js.map +1 -0
  32. package/dist/chunk-J6SH7GQT.js +241 -0
  33. package/dist/chunk-J6SH7GQT.js.map +1 -0
  34. package/dist/chunk-JDBCZ3Z2.js +298 -0
  35. package/dist/chunk-JDBCZ3Z2.js.map +1 -0
  36. package/dist/chunk-JICSYFRJ.js +46 -0
  37. package/dist/chunk-JICSYFRJ.js.map +1 -0
  38. package/dist/chunk-JWHYXEA2.js +32 -0
  39. package/dist/chunk-JWHYXEA2.js.map +1 -0
  40. package/dist/chunk-N7HFALX3.js +88 -0
  41. package/dist/chunk-N7HFALX3.js.map +1 -0
  42. package/dist/chunk-Q4BO4Z5V.js +178 -0
  43. package/dist/chunk-Q4BO4Z5V.js.map +1 -0
  44. package/dist/chunk-QFDOWABX.js +195 -0
  45. package/dist/chunk-QFDOWABX.js.map +1 -0
  46. package/dist/chunk-SJJW77WN.js +605 -0
  47. package/dist/chunk-SJJW77WN.js.map +1 -0
  48. package/dist/chunk-VKVL7WBN.js +50 -0
  49. package/dist/chunk-VKVL7WBN.js.map +1 -0
  50. package/dist/chunk-WOHL4FTB.js +353 -0
  51. package/dist/chunk-WOHL4FTB.js.map +1 -0
  52. package/dist/chunk-XQXVG7RA.js +426 -0
  53. package/dist/chunk-XQXVG7RA.js.map +1 -0
  54. package/dist/chunk-ZD3KHESI.js +94 -0
  55. package/dist/chunk-ZD3KHESI.js.map +1 -0
  56. package/dist/credential-COLTBV6D.js +450 -0
  57. package/dist/credential-COLTBV6D.js.map +1 -0
  58. package/dist/credential-template-EEPYFG7R.js +291 -0
  59. package/dist/credential-template-EEPYFG7R.js.map +1 -0
  60. package/dist/debug-workflow-KOVH5GOP.js +259 -0
  61. package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
  62. package/dist/dist-44PZR7BQ.js +423 -0
  63. package/dist/dist-44PZR7BQ.js.map +1 -0
  64. package/dist/docs-3SSORHB5.js +366 -0
  65. package/dist/docs-3SSORHB5.js.map +1 -0
  66. package/dist/doctor-OTSIWV6G.js +132 -0
  67. package/dist/doctor-OTSIWV6G.js.map +1 -0
  68. package/dist/feature-flag-T2LRZME3.js +283 -0
  69. package/dist/feature-flag-T2LRZME3.js.map +1 -0
  70. package/dist/file-type-S3UUBVCT.js +4205 -0
  71. package/dist/file-type-S3UUBVCT.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +982 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/init-TGWRECT2.js +208 -0
  76. package/dist/init-TGWRECT2.js.map +1 -0
  77. package/dist/install-DXSNWZKO.js +295 -0
  78. package/dist/install-DXSNWZKO.js.map +1 -0
  79. package/dist/issues-XIZOPX6T.js +564 -0
  80. package/dist/issues-XIZOPX6T.js.map +1 -0
  81. package/dist/knobs-NBINZIUB.js +295 -0
  82. package/dist/knobs-NBINZIUB.js.map +1 -0
  83. package/dist/list-3TDHK637.js +59 -0
  84. package/dist/list-3TDHK637.js.map +1 -0
  85. package/dist/local-HICVD6PU.js +100 -0
  86. package/dist/local-HICVD6PU.js.map +1 -0
  87. package/dist/login-UOIUXVUK.js +315 -0
  88. package/dist/login-UOIUXVUK.js.map +1 -0
  89. package/dist/mcp-54IJEOUA.js +1956 -0
  90. package/dist/mcp-54IJEOUA.js.map +1 -0
  91. package/dist/pdf-extract-ABWV3L5X.js +13 -0
  92. package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
  93. package/dist/pdfjs-DQ2YA5S3.js +41561 -0
  94. package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
  95. package/dist/property-UXLOLPTD.js +701 -0
  96. package/dist/property-UXLOLPTD.js.map +1 -0
  97. package/dist/property-skill-guide.md +189 -0
  98. package/dist/psql-BYUUNLGG.js +115 -0
  99. package/dist/psql-BYUUNLGG.js.map +1 -0
  100. package/dist/record-4TR2UIIS.js +233 -0
  101. package/dist/record-4TR2UIIS.js.map +1 -0
  102. package/dist/redis-35VBUYW7.js +116 -0
  103. package/dist/redis-35VBUYW7.js.map +1 -0
  104. package/dist/release-OOLTUBUT.js +354 -0
  105. package/dist/release-OOLTUBUT.js.map +1 -0
  106. package/dist/sandbox-XGSUU6G7.js +2046 -0
  107. package/dist/sandbox-XGSUU6G7.js.map +1 -0
  108. package/dist/scenarios-GWLJEGHA.js +280 -0
  109. package/dist/scenarios-GWLJEGHA.js.map +1 -0
  110. package/dist/session-MYFNZPRP.js +2414 -0
  111. package/dist/session-MYFNZPRP.js.map +1 -0
  112. package/dist/skill-KM34LDMO.js +1839 -0
  113. package/dist/skill-KM34LDMO.js.map +1 -0
  114. package/dist/skills/debug-run/SKILL.md +262 -0
  115. package/dist/skills/debug-run/history/1.0.0.md +244 -0
  116. package/dist/skills/debug-run/history/1.0.1.md +245 -0
  117. package/dist/skills/debug-run/history/1.0.2.md +254 -0
  118. package/dist/skills/debug-run/history/1.1.0.md +262 -0
  119. package/dist/skills/debug-run/version.json +3 -0
  120. package/dist/spec-RA3CFEKG.js +951 -0
  121. package/dist/spec-RA3CFEKG.js.map +1 -0
  122. package/dist/src-LB4HBTJQ.js +1516 -0
  123. package/dist/src-LB4HBTJQ.js.map +1 -0
  124. package/dist/src-N3TPKGTY.js +244 -0
  125. package/dist/src-N3TPKGTY.js.map +1 -0
  126. package/dist/src-UVDX5UP6.js +17 -0
  127. package/dist/src-UVDX5UP6.js.map +1 -0
  128. package/dist/start-PSEQSQA3.js +151 -0
  129. package/dist/start-PSEQSQA3.js.map +1 -0
  130. package/dist/tag-YY6YAABQ.js +22 -0
  131. package/dist/tag-YY6YAABQ.js.map +1 -0
  132. package/dist/task-IQC3YR5K.js +922 -0
  133. package/dist/task-IQC3YR5K.js.map +1 -0
  134. package/dist/test-suite-DZNJFXDW.js +394 -0
  135. package/dist/test-suite-DZNJFXDW.js.map +1 -0
  136. package/dist/trace-HXIW7U2D.js +14 -0
  137. package/dist/trace-HXIW7U2D.js.map +1 -0
  138. package/dist/triage-ORG45R5W.js +16 -0
  139. package/dist/triage-ORG45R5W.js.map +1 -0
  140. package/dist/upgrade-L2VYMP2V.js +61 -0
  141. package/dist/upgrade-L2VYMP2V.js.map +1 -0
  142. package/dist/workflow-XYFH5LTP.js +3708 -0
  143. package/dist/workflow-XYFH5LTP.js.map +1 -0
  144. package/dist/workflow-cache-NQJQFWMV.js +253 -0
  145. package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
  146. package/dist/workflow-debug-BGD4UIXU.js +927 -0
  147. package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
  148. package/dist/workflow-proposals-MTUDX46O.js +382 -0
  149. package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
  150. package/package.json +61 -0
@@ -0,0 +1,244 @@
1
+ ---
2
+ name: debug-run
3
+ description: Root-cause a Canary workflow run end-to-end. Materializes the run's diagnostic workspace and explores it with Read (multimodal), Bash, Grep, and Glob. Use when the user asks "why did this run fail/hang/take so long", references a runId, pastes a flows/?runId=... URL, or asks "what changed since it last passed".
4
+ allowed-tools: Read, Grep, Glob, Bash(canary workflow debug:*), Bash(canary workflow runs:*), Bash(jq:*), Bash(diff:*), Bash(sed -n:*), Bash(head:*), Bash(tail:*), Bash(wc:*), Bash(grep:*), Bash(find:*), Bash(ls:*), Bash(cat:*)
5
+ ---
6
+
7
+ <!-- AUTOGENERATED from packages/diagnostic-playbook/. Do not edit by hand. -->
8
+ <!-- Run: bun run --filter=@canaryai/cli render-skills -->
9
+
10
+ # Workflow Run Debug Guide
11
+
12
+ You are debugging a Canary workflow run end-to-end. The same diagnostic data the v2 failure-diagnostic agent uses is available to you here — materialize it once, then explore.
13
+
14
+ ## Materialize the workspace
15
+
16
+ ```bash
17
+ canary workflow debug materialize <runId> --out ./diag-<runId>/
18
+ ```
19
+
20
+ This produces a structured workspace on disk. After it completes, all subsequent navigation uses Read/Bash/Grep against that directory. The workspace is the **single source of truth** — the v2 agent and you read the exact same files.
21
+
22
+ If you don't have a workflowId, list runs first:
23
+ ```bash
24
+ canary workflow runs list <workflowId>
25
+ ```
26
+
27
+ ## Your job
28
+
29
+ You are a senior QA engineer diagnosing why an end-to-end workflow test failed. The reported failure is a **hypothesis**. Your job is to verify it with evidence and produce three things:
30
+
31
+ 1. **What actually happened** — narrate from evidence, not the failure report. Cite specific artifacts (file paths, timestamps, screenshot indices, network entries, agent thoughts).
32
+ 2. **What was supposed to happen** — quoted from the workflow definition (`workflow/nodes/<nodeId>.json`) and, when available, the prior passing run.
33
+ 3. **What we should do** — depends on the failure category (see below).
34
+
35
+ ## Failure categories — pick exactly one
36
+
37
+ - `software_bug` — defect in the application under test (4xx/5xx from app APIs, JS exceptions, broken UI)
38
+ - `dependency_issue` — required data, fixture, or external service was missing for the test
39
+ - `agent_confusion` — the AI test agent reasoned incorrectly, picked the wrong element, or got confused
40
+ - `platform_error` — defect in our test runner, harness, sandbox, or recording infrastructure
41
+ - `test_underspecified` — the test instructions are wrong, ambiguous, or stale (a previous run with the same instructions interpreted them differently)
42
+
43
+ Never mark `agent_confusion` or `platform_error` from a failed assertion alone. Look at multiple evidence sources first.
44
+
45
+
46
+ ## Workspace layout
47
+
48
+ Your diagnostic workspace is at `{{workspacePath}}`. Everything you need is here. Read in three tiers:
49
+
50
+ **Tier 1 — always read first:**
51
+ - `summary.md` — run-level overview, step table, error counts, notable events, history hint, and pointers to the right rollup files
52
+ - `reported-failure.md` — the test runner's hypothesis (verify, do not trust)
53
+
54
+ **Tier 2 — drill-down per step:**
55
+ - `steps/<NNN>-<stepId>.md` — per-step rollup (timing, status, error, thoughts, in-window network/console events, navigation, assertions, artifact paths). Read the failed step's rollup first, then walk backwards.
56
+
57
+ **Tier 3 — windowed reads only:**
58
+ - `ledger.md` — full chronological narrative. **Do not read whole.** Open `ledger-index.md` first for the step→line-range mapping, then `bash("sed -n '<a>,<b>p' ledger.md")`.
59
+
60
+ ## Other artifacts
61
+
62
+ - `browser/frames/<NNNN>-<absoluteTsMs>.png` — screenshots per browser action. Read with `read_file`; the model sees them as vision input.
63
+ - `browser/doms/<NNNN>-<absoluteTsMs>.html` — composed self-contained HTML per action.
64
+ - `browser/a11y/<NNNN>-<absoluteTsMs>.yaml` — what the agent's accessibility view looked like.
65
+ - `browser/actions.jsonl` — parsed Playwright actions with timestamps. Use `jq` to filter.
66
+ - `browser/trace.zip` — raw Playwright trace (escape hatch).
67
+ - `workflow/nodes/<nodeId>.json` — full configJson per workflow node. Quote `actionDescription`, `inlineAssertions` from here.
68
+ - `workflow/snapshot.json` — full workflow snapshot the run executed.
69
+ - `thoughts/all.jsonl` — every agent thought with stepId, timestamp, content. Use `jq` to filter.
70
+ - `thoughts/by-step/<stepId>.md` — readable per-step thoughts.
71
+ - `timeline/{steps,actions,navigation,assertions,cache-decisions}.jsonl` — structured event streams.
72
+ - `logs/network.jsonl`, `logs/network-errors.jsonl` — network requests; errors are pre-filtered.
73
+ - `logs/console.jsonl`, `logs/console-errors.jsonl` — console logs; errors+warnings are pre-filtered.
74
+ - `logs/sentry-logs.jsonl`, `logs/sentry-spans.jsonl` — Sentry telemetry. May contain a `partial: true` first line if the Sentry token wasn't available.
75
+ - `variables/inputs.json`, `variables/lineage.jsonl` — run inputs + per-step variable captures.
76
+ - `history/recent-runs.jsonl` — last ~20 runs with status. Useful for picking a green run to compare.
77
+ - `history/last-green/` — populated only if you materialize a prior passing run for comparison.
78
+ - `notes/` — your working memory. Write here with `write_file` (only the workspace, no path escapes).
79
+
80
+
81
+ ## Investigation procedure (Claude Code edition)
82
+
83
+ Follow this in order. Adapt the v2 agent's procedure to use Claude Code's built-in tools.
84
+
85
+ 1. **Anchor at the reported failure.** `Read summary.md` first — it has the run-level overview, the failed step's ordinal, the file path of the failed step's rollup, and the history hint. Treat the reported failure as a hypothesis, not a fact.
86
+ 2. **Verify with evidence — including visual evidence.** `Read steps/<NNN>-<failedStepId>.md` for the failure context. Read the screenshot file referenced there (`browser/frames/<NNNN>-...png`) — `Read` is multimodal, vision describes what's on screen. Look for unexpected modals, banners, blank areas, wrong brand, layout shifts. Cross-reference network errors and console errors in the rollup.
87
+ 3. **Walk backwards.** The reported failure is rarely the divergence point. Read the prior step's rollup (`steps/<NNN-1>-...md`), look at its screenshot, and ask: did this step actually accomplish its goal? Repeat going backwards until you find a step where the actual outcome diverged from the intended outcome.
88
+ 4. **Compare to history.** If `summary.md`'s history section shows recent passes, the most recent green run's testRunId and materialize command appear there. Run that command, then visually compare the suspect step's screenshot in both runs.
89
+ 5. **Present clear evidence.** Your write-up cites specific artifacts (file paths, timestamps, screenshot indices, network entries). When visual comparison is decisive, name both screenshot paths.
90
+
91
+ ## Important
92
+
93
+ - Never `Read ledger.md` without a specific window — open `ledger-index.md` first to find the line range, then `Bash sed -n '<a>,<b>p' ledger.md`.
94
+ - The workspace is the canonical data layer. If you can't answer a question from the workspace, that's a signal the materializer is missing a domain — file a follow-up rather than reaching for psql/sentry CLI directly.
95
+
96
+ ## Verifying the reported failure
97
+
98
+ The failure report (in `reported-failure.md` and the top of `summary.md`) is the **runner's hypothesis** about what failed. It is wrong often enough that you must always verify before forming a diagnosis.
99
+
100
+ Things that look like a step-3 failure but are really upstream:
101
+ - The agent on step 1 picked the wrong "Sign in" link, ended up on the consumer site instead of the staging site, and the failure surfaces as `AuthenticationError` two steps later.
102
+ - A cache-replay on step 2 used a stale selector that matched a hidden element; the step "succeeded" but didn't actually click anything; step 3 fails because the modal never opened.
103
+ - The runner timed out a step but the page actually loaded fine — the timeout is a platform issue, not the app's fault.
104
+
105
+ Always cross-reference at least three sources before forming a hypothesis:
106
+ 1. The screenshot at the failure timestamp (`browser/frames/...`)
107
+ 2. The agent's thoughts during the failed step (`thoughts/by-step/<stepId>.md`)
108
+ 3. Either the network errors (`logs/network-errors.jsonl`) OR the console errors (`logs/console-errors.jsonl`) within ±2s of the failure timestamp
109
+
110
+ If the screenshot, thoughts, and logs all paint the same picture, the reported failure is probably accurate. If any one disagrees, walk backwards (see procedure step 3).
111
+
112
+
113
+ ## Walking backwards
114
+
115
+ The visible failure is rarely the actual divergence. Common patterns:
116
+
117
+ - A `click` succeeded 3 steps ago but landed on the *wrong* element — the cache-replay layer hid the mismatch — and the failure surfaces only when the next required field can't be found.
118
+ - A cross-host navigation between two earlier steps invalidated the auth session, and the 401 doesn't appear until the next API call.
119
+ - A variable was captured from the wrong DOM element on step N, and step N+5 now has a meaningless `$var.X` value.
120
+ - The agent went down a wrong branch on a conditional, and the test ran a different path than intended.
121
+
122
+ Walk-backwards algorithm:
123
+
124
+ 1. `read_file` `steps/<NNN-1>-<prevStepId>.md` for the step immediately before the failure.
125
+ 2. `read_file` its screenshot (`browser/frames/<NNNN>-...png`). **Look at it.** Did the step actually accomplish its goal?
126
+ 3. Compare to the instruction by `read_file` on `workflow/nodes/<nodeId>.json` — does the screenshot match the intent of `actionDescription` and `inlineAssertions`?
127
+ 4. Skim the rollup's "Agent thoughts" section. Was the agent confused? Did it pick the wrong element?
128
+ 5. Skim the rollup's "Navigation" section. A cross-host transition (⚠ marker) is a strong signal that auth state was lost between this step and the next.
129
+ 6. If everything looks normal here, repeat with `steps/<NNN-2>-...md`, `<NNN-3>`, and so on.
130
+
131
+ Stop when you find a step where the actual outcome diverged from the intended outcome. That is your root-cause candidate. Cite that step's screenshot and the diverging detail in your `actuallyHappened` narration.
132
+
133
+
134
+ ## Visual evidence — when to read frames
135
+
136
+ A large fraction of diagnoses turn on what the page actually *looked like* at a given moment. Text alone cannot tell you:
137
+ - Whether an unexpected modal/banner is blocking the click target
138
+ - Whether the layout shifted such that the agent's selector resolved to a different element
139
+ - Whether the brand on screen matches what the test expected (cross-host redirects often land on a sibling brand)
140
+ - Whether a stale cached fragment is being shown
141
+ - Whether a button is disabled, missing, or moved
142
+
143
+ How to use vision:
144
+
145
+ - Use `read_file` on `browser/frames/<NNNN>-<absoluteTsMs>.png`. The file extension triggers multimodal output — the model receives the image as vision input on the same turn.
146
+ - For run-vs-run comparison, read the frame at the same step in `history/last-green/browser/frames/<NNNN>-...png` and the failing run's frame in adjacent `read_file` calls. Reason about the visual delta directly.
147
+ - When visual evidence is decisive, include a `before_after` entry in your `evidence[]` with the two image paths.
148
+
149
+ Do not use `bash` to view images — `read_file` is the only tool that returns vision content.
150
+
151
+
152
+ ## Comparing to a passing run
153
+
154
+ If `summary.md`'s history section shows recent passes, comparison is usually high-yield. The most recent green run's testRunId and the materialize command appear there.
155
+
156
+ Procedure:
157
+
158
+ 1. From `summary.md`'s "History" section, copy the materialize command. It looks like:
159
+ `canary workflow debug materialize <greenRunId> --out history/last-green/`
160
+ 2. Run that exact command via `bash`. After it completes, you'll have a parallel workspace at `history/last-green/`.
161
+ 3. `read_file` the suspect step's screenshot in both runs:
162
+ - `browser/frames/<NNNN>-...png` — failing
163
+ - `history/last-green/browser/frames/<NNNN>-...png` — passing
164
+ The visual delta is often the smoking gun.
165
+ 4. Diff thoughts and node configs:
166
+ - `bash diff thoughts/by-step/<stepId>.md history/last-green/thoughts/by-step/<stepId>.md`
167
+ - `bash diff workflow/snapshot.json history/last-green/workflow/snapshot.json | head -100`
168
+
169
+ Common signals from comparison:
170
+
171
+ - Identical workflow + different visual = **app changed** (likely `software_bug`).
172
+ - Different workflow snapshot = **test changed** (possibly `test_underspecified` if the new instructions are ambiguous).
173
+ - Same screenshot but different thoughts = **agent interpretation drift** (likely `test_underspecified` if the test allowed the prior interpretation).
174
+ - Same everything but new network 5xx = **dependency/backend issue** (likely `software_bug` or `dependency_issue`).
175
+
176
+ Comparison is optional. If `summary.md`'s history shows no recent passes, skip this step and rely on the within-run procedure (verify + walk backwards).
177
+
178
+
179
+ ## Standing rules
180
+
181
+ ## Standing rule: auth errors after a cross-host transition
182
+
183
+ If the failure looks like a credential or session issue (401/403, "session expired", login redirect, "please sign in"), **first reconstruct the URL timeline around the failure**.
184
+
185
+ 1. Read the failed step's rollup (`steps/<NNN>-<stepId>.md`) — the "Navigation (in step window)" section lists URL transitions and marks cross-host transitions with `⚠ cross-host`.
186
+ 2. Skim the prior step's navigation as well — the cross-host hop often happens between steps.
187
+ 3. Compare host names case-insensitively, stripping a leading `www.`. So `staging.example.com` → `www.example.com` is a cross-host change; `www.example.com` ↔ `example.com` is not.
188
+
189
+ **If the hostname changed between two entries shortly before the auth failure, the test navigated off its authenticated origin. That is the root cause, not stale credentials.** Do not classify as `dependency_issue` (credentials problem) without ruling out cross-host.
190
+
191
+ Auth errors after a cross-host transition are almost never credential issues.
192
+
193
+
194
+ ## Standing rule: workflow variables and macros
195
+
196
+ Workflow steps can use **macros** and **variable references** in their configuration:
197
+
198
+ - **Macros** (generate values at runtime): `$MACRO_NAME(args)` — e.g. `$EMAIL()`, `$UUID()`, `$RANDOM_STRING(10)`. Used in `inputValues` on action nodes; resolved fresh each run.
199
+ - **Variable references** (reference values from earlier steps): `$var.variable_name`. Variables are created when a step's `inputValues` are resolved. **A variable defined in step N is NOT available within step N itself** — only in step N+1 and later. This is because variables are registered after the step's inputs are resolved.
200
+
201
+ Common variable-related failures:
202
+ - A step references `$var.X` where X is defined in that same step (will be unresolved → blank value used).
203
+ - A step references `$var.X` where X was defined in a step that was skipped or failed earlier.
204
+ - Misspelled variable names (e.g. `$var.client_name` vs `$var.clientName`).
205
+ - An `inputValue` was set without a matching `dataRequirements` entry — only inputs with a dataRequirement become variables.
206
+
207
+ When suggesting test instruction changes:
208
+ - Use `read_file` on `workflow/nodes/<nodeId>.json` to see the full configJson before proposing a `configPatch`.
209
+ - Preserve any existing `$var.` references and `$MACRO()` calls — don't break them.
210
+ - For array fields like `inlineAssertions` or `playbookSteps`, the `configPatch` must be a **full replacement array**, not a partial — read the existing array first and include the merged result.
211
+
212
+
213
+ ## Conditional rule: non-blocking inline assertions
214
+
215
+ For this org, an inline assertion on an action step is allowed to fail without failing the step — the agent judges the broader outcome and may still proceed. Assertion records carry a `nonBlocking` flag reflecting how each was treated at run time.
216
+
217
+ When investigating:
218
+
219
+ - Open the step's rollup (`steps/<NNN>-<stepId>.md`) and look at the "Assertions" section. Each line shows `passed`/`FAILED`, severity, and a `nonBlocking` marker.
220
+ - **Do not treat "failed assertion + completed step" on its own as evidence of `platform_error` or contradictory state.** When `nonBlocking` is true, that combination is expected and carries no signal about the actual cause.
221
+ - A non-blocking failed assertion does not tell you which category applies. It only rules out one specific false-positive narrative (`platform_error` / bookkeeping). Continue investigating from network, console, thoughts, visual, and history. The actual cause may be any of `software_bug`, `dependency_issue`, `agent_confusion`, `test_underspecified`, or `platform_error`.
222
+
223
+ When `platform_error` is still a live possibility:
224
+
225
+ - A failed assertion with `nonBlocking: false` (or the field absent) alongside a step recorded as completed successfully. That is a genuine disagreement worth flagging.
226
+ - Infrastructure-level failures (browser session died, worker crash, our own stack traces) independent of any assertion outcome.
227
+
228
+ Always consult the assertions section of the rollup before writing a bookkeeping-bug narrative.
229
+
230
+
231
+ ## Reporting
232
+
233
+ When you reach a root cause, your write-up should always include:
234
+
235
+ 1. **What actually happened** — narrate from evidence; cite specific artifacts (file paths, timestamps, screenshot indices, network entries, agent thoughts).
236
+ 2. **What was supposed to happen** — quote from `workflow/nodes/<nodeId>.json` and (when comparing) the green-run baseline.
237
+ 3. **What we should do** — matched to the failure category:
238
+ - `software_bug` → describe the app defect, cite the network/console error, suggest filing app-side
239
+ - `dependency_issue` → name the missing data/fixture/credential, suggest where to provision
240
+ - `agent_confusion` → quote the confused thought, point at visual evidence the agent missed, suggest test instruction tweaks
241
+ - `platform_error` → describe the harness failure, suggest filing a platform issue
242
+ - `test_underspecified` → quote the ambiguous instruction, suggest a clearer rewording
243
+
244
+ Don't hand back "the run failed" or a Sentry error message alone. The whole point is to triangulate to a concrete cause.
@@ -0,0 +1,245 @@
1
+ ---
2
+ name: debug-run
3
+ description: Root-cause a Canary workflow run end-to-end. Materializes the run's diagnostic workspace and explores it with Read (multimodal), Bash, Grep, and Glob. Use when the user asks "why did this run fail/hang/take so long", references a runId, pastes a flows/?runId=... URL, or asks "what changed since it last passed".
4
+ allowed-tools: Read, Grep, Glob, Bash(canary workflow debug:*), Bash(canary workflow runs:*), Bash(jq:*), Bash(diff:*), Bash(sed -n:*), Bash(head:*), Bash(tail:*), Bash(wc:*), Bash(grep:*), Bash(find:*), Bash(ls:*), Bash(cat:*)
5
+ ---
6
+
7
+ <!-- AUTOGENERATED from packages/diagnostic-playbook/. Do not edit by hand. -->
8
+ <!-- After editing the partials, mint a new version: -->
9
+ <!-- bun run --filter=@canaryai/cli bump-skill debug-run [patch|minor|major] -->
10
+
11
+ # Workflow Run Debug Guide
12
+
13
+ You are debugging a Canary workflow run end-to-end. The same diagnostic data the v2 failure-diagnostic agent uses is available to you here — materialize it once, then explore.
14
+
15
+ ## Materialize the workspace
16
+
17
+ ```bash
18
+ canary workflow debug materialize <runId> --out ./diag-<runId>/
19
+ ```
20
+
21
+ This produces a structured workspace on disk. After it completes, all subsequent navigation uses Read/Bash/Grep against that directory. The workspace is the **single source of truth** — the v2 agent and you read the exact same files.
22
+
23
+ If you don't have a workflowId, list runs first:
24
+ ```bash
25
+ canary workflow runs list <workflowId>
26
+ ```
27
+
28
+ ## Your job
29
+
30
+ You are a senior QA engineer diagnosing why an end-to-end workflow test failed. The reported failure is a **hypothesis**. Your job is to verify it with evidence and produce three things:
31
+
32
+ 1. **What actually happened** — narrate from evidence, not the failure report. Cite specific artifacts (file paths, timestamps, screenshot indices, network entries, agent thoughts).
33
+ 2. **What was supposed to happen** — quoted from the workflow definition (`workflow/nodes/<nodeId>.json`) and, when available, the prior passing run.
34
+ 3. **What we should do** — depends on the failure category (see below).
35
+
36
+ ## Failure categories — pick exactly one
37
+
38
+ - `software_bug` — defect in the application under test (4xx/5xx from app APIs, JS exceptions, broken UI)
39
+ - `dependency_issue` — required data, fixture, or external service was missing for the test
40
+ - `agent_confusion` — the AI test agent reasoned incorrectly, picked the wrong element, or got confused
41
+ - `platform_error` — defect in our test runner, harness, sandbox, or recording infrastructure
42
+ - `test_underspecified` — the test instructions are wrong, ambiguous, or stale (a previous run with the same instructions interpreted them differently)
43
+
44
+ Never mark `agent_confusion` or `platform_error` from a failed assertion alone. Look at multiple evidence sources first.
45
+
46
+
47
+ ## Workspace layout
48
+
49
+ Your diagnostic workspace is at `{{workspacePath}}`. Everything you need is here. Read in three tiers:
50
+
51
+ **Tier 1 — always read first:**
52
+ - `summary.md` — run-level overview, step table, error counts, notable events, history hint, and pointers to the right rollup files
53
+ - `reported-failure.md` — the test runner's hypothesis (verify, do not trust)
54
+
55
+ **Tier 2 — drill-down per step:**
56
+ - `steps/<NNN>-<stepId>.md` — per-step rollup (timing, status, error, thoughts, in-window network/console events, navigation, assertions, artifact paths). Read the failed step's rollup first, then walk backwards.
57
+
58
+ **Tier 3 — windowed reads only:**
59
+ - `ledger.md` — full chronological narrative. **Do not read whole.** Open `ledger-index.md` first for the step→line-range mapping, then `bash("sed -n '<a>,<b>p' ledger.md")`.
60
+
61
+ ## Other artifacts
62
+
63
+ - `browser/frames/<NNNN>-<absoluteTsMs>.png` — screenshots per browser action. Read with `read_file`; the model sees them as vision input.
64
+ - `browser/doms/<NNNN>-<absoluteTsMs>.html` — composed self-contained HTML per action.
65
+ - `browser/a11y/<NNNN>-<absoluteTsMs>.yaml` — what the agent's accessibility view looked like.
66
+ - `browser/actions.jsonl` — parsed Playwright actions with timestamps. Use `jq` to filter.
67
+ - `browser/trace.zip` — raw Playwright trace (escape hatch).
68
+ - `workflow/nodes/<nodeId>.json` — full configJson per workflow node. Quote `actionDescription`, `inlineAssertions` from here.
69
+ - `workflow/snapshot.json` — full workflow snapshot the run executed.
70
+ - `thoughts/all.jsonl` — every agent thought with stepId, timestamp, content. Use `jq` to filter.
71
+ - `thoughts/by-step/<stepId>.md` — readable per-step thoughts.
72
+ - `timeline/{steps,actions,navigation,assertions,cache-decisions}.jsonl` — structured event streams.
73
+ - `logs/network.jsonl`, `logs/network-errors.jsonl` — network requests; errors are pre-filtered.
74
+ - `logs/console.jsonl`, `logs/console-errors.jsonl` — console logs; errors+warnings are pre-filtered.
75
+ - `logs/sentry-logs.jsonl`, `logs/sentry-spans.jsonl` — Sentry telemetry. May contain a `partial: true` first line if the Sentry token wasn't available.
76
+ - `variables/inputs.json`, `variables/lineage.jsonl` — run inputs + per-step variable captures.
77
+ - `history/recent-runs.jsonl` — last ~20 runs with status. Useful for picking a green run to compare.
78
+ - `history/last-green/` — populated only if you materialize a prior passing run for comparison.
79
+ - `notes/` — your working memory. Write here with `write_file` (only the workspace, no path escapes).
80
+
81
+
82
+ ## Investigation procedure (Claude Code edition)
83
+
84
+ Follow this in order. Adapt the v2 agent's procedure to use Claude Code's built-in tools.
85
+
86
+ 1. **Anchor at the reported failure.** `Read summary.md` first — it has the run-level overview, the failed step's ordinal, the file path of the failed step's rollup, and the history hint. Treat the reported failure as a hypothesis, not a fact.
87
+ 2. **Verify with evidence — including visual evidence.** `Read steps/<NNN>-<failedStepId>.md` for the failure context. Read the screenshot file referenced there (`browser/frames/<NNNN>-...png`) — `Read` is multimodal, vision describes what's on screen. Look for unexpected modals, banners, blank areas, wrong brand, layout shifts. Cross-reference network errors and console errors in the rollup.
88
+ 3. **Walk backwards.** The reported failure is rarely the divergence point. Read the prior step's rollup (`steps/<NNN-1>-...md`), look at its screenshot, and ask: did this step actually accomplish its goal? Repeat going backwards until you find a step where the actual outcome diverged from the intended outcome.
89
+ 4. **Compare to history.** If `summary.md`'s history section shows recent passes, the most recent green run's testRunId and materialize command appear there. Run that command, then visually compare the suspect step's screenshot in both runs.
90
+ 5. **Present clear evidence.** Your write-up cites specific artifacts (file paths, timestamps, screenshot indices, network entries). When visual comparison is decisive, name both screenshot paths.
91
+
92
+ ## Important
93
+
94
+ - Never `Read ledger.md` without a specific window — open `ledger-index.md` first to find the line range, then `Bash sed -n '<a>,<b>p' ledger.md`.
95
+ - The workspace is the canonical data layer. If you can't answer a question from the workspace, that's a signal the materializer is missing a domain — file a follow-up rather than reaching for psql/sentry CLI directly.
96
+
97
+ ## Verifying the reported failure
98
+
99
+ The failure report (in `reported-failure.md` and the top of `summary.md`) is the **runner's hypothesis** about what failed. It is wrong often enough that you must always verify before forming a diagnosis.
100
+
101
+ Things that look like a step-3 failure but are really upstream:
102
+ - The agent on step 1 picked the wrong "Sign in" link, ended up on the consumer site instead of the staging site, and the failure surfaces as `AuthenticationError` two steps later.
103
+ - A cache-replay on step 2 used a stale selector that matched a hidden element; the step "succeeded" but didn't actually click anything; step 3 fails because the modal never opened.
104
+ - The runner timed out a step but the page actually loaded fine — the timeout is a platform issue, not the app's fault.
105
+
106
+ Always cross-reference at least three sources before forming a hypothesis:
107
+ 1. The screenshot at the failure timestamp (`browser/frames/...`)
108
+ 2. The agent's thoughts during the failed step (`thoughts/by-step/<stepId>.md`)
109
+ 3. Either the network errors (`logs/network-errors.jsonl`) OR the console errors (`logs/console-errors.jsonl`) within ±2s of the failure timestamp
110
+
111
+ If the screenshot, thoughts, and logs all paint the same picture, the reported failure is probably accurate. If any one disagrees, walk backwards (see procedure step 3).
112
+
113
+
114
+ ## Walking backwards
115
+
116
+ The visible failure is rarely the actual divergence. Common patterns:
117
+
118
+ - A `click` succeeded 3 steps ago but landed on the *wrong* element — the cache-replay layer hid the mismatch — and the failure surfaces only when the next required field can't be found.
119
+ - A cross-host navigation between two earlier steps invalidated the auth session, and the 401 doesn't appear until the next API call.
120
+ - A variable was captured from the wrong DOM element on step N, and step N+5 now has a meaningless `$var.X` value.
121
+ - The agent went down a wrong branch on a conditional, and the test ran a different path than intended.
122
+
123
+ Walk-backwards algorithm:
124
+
125
+ 1. `read_file` `steps/<NNN-1>-<prevStepId>.md` for the step immediately before the failure.
126
+ 2. `read_file` its screenshot (`browser/frames/<NNNN>-...png`). **Look at it.** Did the step actually accomplish its goal?
127
+ 3. Compare to the instruction by `read_file` on `workflow/nodes/<nodeId>.json` — does the screenshot match the intent of `actionDescription` and `inlineAssertions`?
128
+ 4. Skim the rollup's "Agent thoughts" section. Was the agent confused? Did it pick the wrong element?
129
+ 5. Skim the rollup's "Navigation" section. A cross-host transition (⚠ marker) is a strong signal that auth state was lost between this step and the next.
130
+ 6. If everything looks normal here, repeat with `steps/<NNN-2>-...md`, `<NNN-3>`, and so on.
131
+
132
+ Stop when you find a step where the actual outcome diverged from the intended outcome. That is your root-cause candidate. Cite that step's screenshot and the diverging detail in your `actuallyHappened` narration.
133
+
134
+
135
+ ## Visual evidence — when to read frames
136
+
137
+ A large fraction of diagnoses turn on what the page actually *looked like* at a given moment. Text alone cannot tell you:
138
+ - Whether an unexpected modal/banner is blocking the click target
139
+ - Whether the layout shifted such that the agent's selector resolved to a different element
140
+ - Whether the brand on screen matches what the test expected (cross-host redirects often land on a sibling brand)
141
+ - Whether a stale cached fragment is being shown
142
+ - Whether a button is disabled, missing, or moved
143
+
144
+ How to use vision:
145
+
146
+ - Use `read_file` on `browser/frames/<NNNN>-<absoluteTsMs>.png`. The file extension triggers multimodal output — the model receives the image as vision input on the same turn.
147
+ - For run-vs-run comparison, read the frame at the same step in `history/last-green/browser/frames/<NNNN>-...png` and the failing run's frame in adjacent `read_file` calls. Reason about the visual delta directly.
148
+ - When visual evidence is decisive, include a `before_after` entry in your `evidence[]` with the two image paths.
149
+
150
+ Do not use `bash` to view images — `read_file` is the only tool that returns vision content.
151
+
152
+
153
+ ## Comparing to a passing run
154
+
155
+ If `summary.md`'s history section shows recent passes, comparison is usually high-yield. The most recent green run's testRunId and the materialize command appear there.
156
+
157
+ Procedure:
158
+
159
+ 1. From `summary.md`'s "History" section, copy the materialize command. It looks like:
160
+ `canary workflow debug materialize <greenRunId> --out history/last-green/`
161
+ 2. Run that exact command via `bash`. After it completes, you'll have a parallel workspace at `history/last-green/`.
162
+ 3. `read_file` the suspect step's screenshot in both runs:
163
+ - `browser/frames/<NNNN>-...png` — failing
164
+ - `history/last-green/browser/frames/<NNNN>-...png` — passing
165
+ The visual delta is often the smoking gun.
166
+ 4. Diff thoughts and node configs:
167
+ - `bash diff thoughts/by-step/<stepId>.md history/last-green/thoughts/by-step/<stepId>.md`
168
+ - `bash diff workflow/snapshot.json history/last-green/workflow/snapshot.json | head -100`
169
+
170
+ Common signals from comparison:
171
+
172
+ - Identical workflow + different visual = **app changed** (likely `software_bug`).
173
+ - Different workflow snapshot = **test changed** (possibly `test_underspecified` if the new instructions are ambiguous).
174
+ - Same screenshot but different thoughts = **agent interpretation drift** (likely `test_underspecified` if the test allowed the prior interpretation).
175
+ - Same everything but new network 5xx = **dependency/backend issue** (likely `software_bug` or `dependency_issue`).
176
+
177
+ Comparison is optional. If `summary.md`'s history shows no recent passes, skip this step and rely on the within-run procedure (verify + walk backwards).
178
+
179
+
180
+ ## Standing rules
181
+
182
+ ## Standing rule: auth errors after a cross-host transition
183
+
184
+ If the failure looks like a credential or session issue (401/403, "session expired", login redirect, "please sign in"), **first reconstruct the URL timeline around the failure**.
185
+
186
+ 1. Read the failed step's rollup (`steps/<NNN>-<stepId>.md`) — the "Navigation (in step window)" section lists URL transitions and marks cross-host transitions with `⚠ cross-host`.
187
+ 2. Skim the prior step's navigation as well — the cross-host hop often happens between steps.
188
+ 3. Compare host names case-insensitively, stripping a leading `www.`. So `staging.example.com` → `www.example.com` is a cross-host change; `www.example.com` ↔ `example.com` is not.
189
+
190
+ **If the hostname changed between two entries shortly before the auth failure, the test navigated off its authenticated origin. That is the root cause, not stale credentials.** Do not classify as `dependency_issue` (credentials problem) without ruling out cross-host.
191
+
192
+ Auth errors after a cross-host transition are almost never credential issues.
193
+
194
+
195
+ ## Standing rule: workflow variables and macros
196
+
197
+ Workflow steps can use **macros** and **variable references** in their configuration:
198
+
199
+ - **Macros** (generate values at runtime): `$MACRO_NAME(args)` — e.g. `$EMAIL()`, `$UUID()`, `$RANDOM_STRING(10)`. Used in `inputValues` on action nodes; resolved fresh each run.
200
+ - **Variable references** (reference values from earlier steps): `$var.variable_name`. Variables are created when a step's `inputValues` are resolved. **A variable defined in step N is NOT available within step N itself** — only in step N+1 and later. This is because variables are registered after the step's inputs are resolved.
201
+
202
+ Common variable-related failures:
203
+ - A step references `$var.X` where X is defined in that same step (will be unresolved → blank value used).
204
+ - A step references `$var.X` where X was defined in a step that was skipped or failed earlier.
205
+ - Misspelled variable names (e.g. `$var.client_name` vs `$var.clientName`).
206
+ - An `inputValue` was set without a matching `dataRequirements` entry — only inputs with a dataRequirement become variables.
207
+
208
+ When suggesting test instruction changes:
209
+ - Use `read_file` on `workflow/nodes/<nodeId>.json` to see the full configJson before proposing a `configPatch`.
210
+ - Preserve any existing `$var.` references and `$MACRO()` calls — don't break them.
211
+ - For array fields like `inlineAssertions` or `playbookSteps`, the `configPatch` must be a **full replacement array**, not a partial — read the existing array first and include the merged result.
212
+
213
+
214
+ ## Conditional rule: non-blocking inline assertions
215
+
216
+ For this org, an inline assertion on an action step is allowed to fail without failing the step — the agent judges the broader outcome and may still proceed. Assertion records carry a `nonBlocking` flag reflecting how each was treated at run time.
217
+
218
+ When investigating:
219
+
220
+ - Open the step's rollup (`steps/<NNN>-<stepId>.md`) and look at the "Assertions" section. Each line shows `passed`/`FAILED`, severity, and a `nonBlocking` marker.
221
+ - **Do not treat "failed assertion + completed step" on its own as evidence of `platform_error` or contradictory state.** When `nonBlocking` is true, that combination is expected and carries no signal about the actual cause.
222
+ - A non-blocking failed assertion does not tell you which category applies. It only rules out one specific false-positive narrative (`platform_error` / bookkeeping). Continue investigating from network, console, thoughts, visual, and history. The actual cause may be any of `software_bug`, `dependency_issue`, `agent_confusion`, `test_underspecified`, or `platform_error`.
223
+
224
+ When `platform_error` is still a live possibility:
225
+
226
+ - A failed assertion with `nonBlocking: false` (or the field absent) alongside a step recorded as completed successfully. That is a genuine disagreement worth flagging.
227
+ - Infrastructure-level failures (browser session died, worker crash, our own stack traces) independent of any assertion outcome.
228
+
229
+ Always consult the assertions section of the rollup before writing a bookkeeping-bug narrative.
230
+
231
+
232
+ ## Reporting
233
+
234
+ When you reach a root cause, your write-up should always include:
235
+
236
+ 1. **What actually happened** — narrate from evidence; cite specific artifacts (file paths, timestamps, screenshot indices, network entries, agent thoughts).
237
+ 2. **What was supposed to happen** — quote from `workflow/nodes/<nodeId>.json` and (when comparing) the green-run baseline.
238
+ 3. **What we should do** — matched to the failure category:
239
+ - `software_bug` → describe the app defect, cite the network/console error, suggest filing app-side
240
+ - `dependency_issue` → name the missing data/fixture/credential, suggest where to provision
241
+ - `agent_confusion` → quote the confused thought, point at visual evidence the agent missed, suggest test instruction tweaks
242
+ - `platform_error` → describe the harness failure, suggest filing a platform issue
243
+ - `test_underspecified` → quote the ambiguous instruction, suggest a clearer rewording
244
+
245
+ Don't hand back "the run failed" or a Sentry error message alone. The whole point is to triangulate to a concrete cause.