tinybeeai 0.0.0-stage → 0.16.1

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 (1034) hide show
  1. package/.railway/railway.ts +83 -0
  2. package/.railway/tsconfig.json +13 -0
  3. package/AGENTS.md +102 -0
  4. package/Dockerfile +108 -0
  5. package/LICENSE +21 -0
  6. package/README.md +275 -2
  7. package/bin/localdost.js +29 -0
  8. package/bin/tinybeeai.js +28 -0
  9. package/compose.yml +63 -0
  10. package/demo/payloads/ci_failure.json +46 -0
  11. package/demo/payloads/outage.json +18 -0
  12. package/demo/payloads/pr_comment_edited.json +50 -0
  13. package/demo/payloads/pr_merged.json +80 -0
  14. package/demo/payloads/pr_opened.json +69 -0
  15. package/demo/payloads/pr_synchronize.json +69 -0
  16. package/demo/payloads/ticket_created.json +138 -0
  17. package/demo/sample-app/playwright.config.ts +20 -0
  18. package/demo/sample-app/server.ts +163 -0
  19. package/demo/sample-app/tests/checkout.spec.ts +13 -0
  20. package/demo/sample-app/tests/smoke.spec.ts +8 -0
  21. package/dist/agent/approval-retries.js +59 -0
  22. package/dist/agent/approval-retries.js.map +1 -0
  23. package/dist/agent/approvals.js +390 -0
  24. package/dist/agent/approvals.js.map +1 -0
  25. package/dist/agent/chat-bridge.js +154 -0
  26. package/dist/agent/chat-bridge.js.map +1 -0
  27. package/dist/agent/chat-lead.js +475 -0
  28. package/dist/agent/chat-lead.js.map +1 -0
  29. package/dist/agent/chat-loop.js +106 -0
  30. package/dist/agent/chat-loop.js.map +1 -0
  31. package/dist/agent/chat-mcp.js +49 -0
  32. package/dist/agent/chat-mcp.js.map +1 -0
  33. package/dist/agent/chat-tool-blocks.js +453 -0
  34. package/dist/agent/chat-tool-blocks.js.map +1 -0
  35. package/dist/agent/chat-view.js +94 -0
  36. package/dist/agent/chat-view.js.map +1 -0
  37. package/dist/agent/chat-views.js +781 -0
  38. package/dist/agent/chat-views.js.map +1 -0
  39. package/dist/agent/chat.js +1703 -0
  40. package/dist/agent/chat.js.map +1 -0
  41. package/dist/agent/destinations.js +150 -0
  42. package/dist/agent/destinations.js.map +1 -0
  43. package/dist/agent/llm-cli.js +451 -0
  44. package/dist/agent/llm-cli.js.map +1 -0
  45. package/dist/agent/llm-codex.js +493 -0
  46. package/dist/agent/llm-codex.js.map +1 -0
  47. package/dist/agent/llm-openai.js +211 -0
  48. package/dist/agent/llm-openai.js.map +1 -0
  49. package/dist/agent/llm.js +1464 -0
  50. package/dist/agent/llm.js.map +1 -0
  51. package/dist/agent/memory.js +33 -0
  52. package/dist/agent/memory.js.map +1 -0
  53. package/dist/agent/mock-views.js +93 -0
  54. package/dist/agent/mock-views.js.map +1 -0
  55. package/dist/agent/model-availability.js +207 -0
  56. package/dist/agent/model-availability.js.map +1 -0
  57. package/dist/agent/model-errors.js +188 -0
  58. package/dist/agent/model-errors.js.map +1 -0
  59. package/dist/agent/model-guard.js +311 -0
  60. package/dist/agent/model-guard.js.map +1 -0
  61. package/dist/agent/prompts.js +374 -0
  62. package/dist/agent/prompts.js.map +1 -0
  63. package/dist/agent/qa-lenses/qa-auth.md +32 -0
  64. package/dist/agent/qa-lenses/qa-check-then-act.md +33 -0
  65. package/dist/agent/qa-lenses/qa-control-has-no-effect.md +32 -0
  66. package/dist/agent/qa-lenses/qa-dates.md +31 -0
  67. package/dist/agent/qa-lenses/qa-double-submit.md +34 -0
  68. package/dist/agent/qa-lenses/qa-feature-flag.md +29 -0
  69. package/dist/agent/qa-lenses/qa-migration.md +35 -0
  70. package/dist/agent/qa-lenses/qa-money.md +38 -0
  71. package/dist/agent/qa-lenses/qa-response-shape-break.md +33 -0
  72. package/dist/agent/qa-lenses/qa-validation.md +29 -0
  73. package/dist/agent/qa-prompts.js +660 -0
  74. package/dist/agent/qa-prompts.js.map +1 -0
  75. package/dist/agent/reasoning.js +55 -0
  76. package/dist/agent/reasoning.js.map +1 -0
  77. package/dist/agent/redact.js +48 -0
  78. package/dist/agent/redact.js.map +1 -0
  79. package/dist/agent/rules.js +927 -0
  80. package/dist/agent/rules.js.map +1 -0
  81. package/dist/agent/runs.js +440 -0
  82. package/dist/agent/runs.js.map +1 -0
  83. package/dist/agent/send-retry.js +62 -0
  84. package/dist/agent/send-retry.js.map +1 -0
  85. package/dist/agent/team-notes.js +288 -0
  86. package/dist/agent/team-notes.js.map +1 -0
  87. package/dist/agent/token-meter.js +31 -0
  88. package/dist/agent/token-meter.js.map +1 -0
  89. package/dist/agent/triage.js +506 -0
  90. package/dist/agent/triage.js.map +1 -0
  91. package/dist/api.js +1047 -0
  92. package/dist/api.js.map +1 -0
  93. package/dist/approval-targets.js +107 -0
  94. package/dist/approval-targets.js.map +1 -0
  95. package/dist/bee/cloudflared.js +108 -0
  96. package/dist/bee/cloudflared.js.map +1 -0
  97. package/dist/bee/health.js +99 -0
  98. package/dist/bee/health.js.map +1 -0
  99. package/dist/bee/hive-client.js +75 -0
  100. package/dist/bee/hive-client.js.map +1 -0
  101. package/dist/bee/identity.js +39 -0
  102. package/dist/bee/identity.js.map +1 -0
  103. package/dist/bee/models.js +510 -0
  104. package/dist/bee/models.js.map +1 -0
  105. package/dist/bee/pairing.js +351 -0
  106. package/dist/bee/pairing.js.map +1 -0
  107. package/dist/bee/relay-client.js +50 -0
  108. package/dist/bee/relay-client.js.map +1 -0
  109. package/dist/bee/routes.js +214 -0
  110. package/dist/bee/routes.js.map +1 -0
  111. package/dist/bee/setup-page.js +223 -0
  112. package/dist/bee/setup-page.js.map +1 -0
  113. package/dist/bee/state.js +41 -0
  114. package/dist/bee/state.js.map +1 -0
  115. package/dist/bee/status.js +117 -0
  116. package/dist/bee/status.js.map +1 -0
  117. package/dist/bee/tunnel-manager.js +245 -0
  118. package/dist/bee/tunnel-manager.js.map +1 -0
  119. package/dist/bee/updater.js +268 -0
  120. package/dist/bee/updater.js.map +1 -0
  121. package/dist/boot.js +41 -0
  122. package/dist/boot.js.map +1 -0
  123. package/dist/call/index.js +145 -0
  124. package/dist/call/index.js.map +1 -0
  125. package/dist/case-folders.js +294 -0
  126. package/dist/case-folders.js.map +1 -0
  127. package/dist/cases.js +554 -0
  128. package/dist/cases.js.map +1 -0
  129. package/dist/chat-blocks.js +709 -0
  130. package/dist/chat-blocks.js.map +1 -0
  131. package/dist/chat-parse-util.js +38 -0
  132. package/dist/chat-parse-util.js.map +1 -0
  133. package/dist/chat-results.js +96 -0
  134. package/dist/chat-results.js.map +1 -0
  135. package/dist/chat-stats.js +193 -0
  136. package/dist/chat-stats.js.map +1 -0
  137. package/dist/chat-view-specs.js +186 -0
  138. package/dist/chat-view-specs.js.map +1 -0
  139. package/dist/cli/doctor-ops.js +361 -0
  140. package/dist/cli/doctor-ops.js.map +1 -0
  141. package/dist/cli/doctor.js +289 -0
  142. package/dist/cli/doctor.js.map +1 -0
  143. package/dist/cli/dogfood.js +70 -0
  144. package/dist/cli/dogfood.js.map +1 -0
  145. package/dist/cli/env-file.js +34 -0
  146. package/dist/cli/env-file.js.map +1 -0
  147. package/dist/cli/eval-chat-cases.js +359 -0
  148. package/dist/cli/eval-chat-cases.js.map +1 -0
  149. package/dist/cli/eval-chat-results.js +85 -0
  150. package/dist/cli/eval-chat-results.js.map +1 -0
  151. package/dist/cli/eval-chat.js +508 -0
  152. package/dist/cli/eval-chat.js.map +1 -0
  153. package/dist/cli/eval-designer.js +67 -0
  154. package/dist/cli/eval-designer.js.map +1 -0
  155. package/dist/cli/eval-qa-review.js +284 -0
  156. package/dist/cli/eval-qa-review.js.map +1 -0
  157. package/dist/cli/golden-export.js +35 -0
  158. package/dist/cli/golden-export.js.map +1 -0
  159. package/dist/cli/index.js +90 -0
  160. package/dist/cli/index.js.map +1 -0
  161. package/dist/cli/init.js +746 -0
  162. package/dist/cli/init.js.map +1 -0
  163. package/dist/cli/scan-repo.js +199 -0
  164. package/dist/cli/scan-repo.js.map +1 -0
  165. package/dist/cli/seed.js +108 -0
  166. package/dist/cli/seed.js.map +1 -0
  167. package/dist/cli/tinybee.js +247 -0
  168. package/dist/cli/tinybee.js.map +1 -0
  169. package/dist/config.js +138 -0
  170. package/dist/config.js.map +1 -0
  171. package/dist/connect/aivision-local.js +833 -0
  172. package/dist/connect/aivision-local.js.map +1 -0
  173. package/dist/connect/aivision-token.js +84 -0
  174. package/dist/connect/aivision-token.js.map +1 -0
  175. package/dist/connect/crypto.js +65 -0
  176. package/dist/connect/crypto.js.map +1 -0
  177. package/dist/connect/deps.js +110 -0
  178. package/dist/connect/deps.js.map +1 -0
  179. package/dist/connect/engines.js +144 -0
  180. package/dist/connect/engines.js.map +1 -0
  181. package/dist/connect/github-access.js +74 -0
  182. package/dist/connect/github-access.js.map +1 -0
  183. package/dist/connect/github-app.js +129 -0
  184. package/dist/connect/github-app.js.map +1 -0
  185. package/dist/connect/index.js +9 -0
  186. package/dist/connect/index.js.map +1 -0
  187. package/dist/connect/model-choices.js +201 -0
  188. package/dist/connect/model-choices.js.map +1 -0
  189. package/dist/connect/providers.js +900 -0
  190. package/dist/connect/providers.js.map +1 -0
  191. package/dist/connect/readiness.js +232 -0
  192. package/dist/connect/readiness.js.map +1 -0
  193. package/dist/connect/redact.js +16 -0
  194. package/dist/connect/redact.js.map +1 -0
  195. package/dist/connect/registry.js +406 -0
  196. package/dist/connect/registry.js.map +1 -0
  197. package/dist/connect/store.js +283 -0
  198. package/dist/connect/store.js.map +1 -0
  199. package/dist/connect/tunnel.js +134 -0
  200. package/dist/connect/tunnel.js.map +1 -0
  201. package/dist/connect/types.js +8 -0
  202. package/dist/connect/types.js.map +1 -0
  203. package/dist/connections/index.js +5 -0
  204. package/dist/connections/index.js.map +1 -0
  205. package/dist/connections/manager.js +223 -0
  206. package/dist/connections/manager.js.map +1 -0
  207. package/dist/connections/presets.js +264 -0
  208. package/dist/connections/presets.js.map +1 -0
  209. package/dist/connections/store.js +132 -0
  210. package/dist/connections/store.js.map +1 -0
  211. package/dist/connections/tools.js +206 -0
  212. package/dist/connections/tools.js.map +1 -0
  213. package/dist/db-schema.js +355 -0
  214. package/dist/db-schema.js.map +1 -0
  215. package/dist/db.js +379 -0
  216. package/dist/db.js.map +1 -0
  217. package/dist/delivery.js +49 -0
  218. package/dist/delivery.js.map +1 -0
  219. package/dist/deploy-wait.js +701 -0
  220. package/dist/deploy-wait.js.map +1 -0
  221. package/dist/disk.js +243 -0
  222. package/dist/disk.js.map +1 -0
  223. package/dist/dot-health.js +966 -0
  224. package/dist/dot-health.js.map +1 -0
  225. package/dist/dot-remove.js +246 -0
  226. package/dist/dot-remove.js.map +1 -0
  227. package/dist/events.js +38 -0
  228. package/dist/events.js.map +1 -0
  229. package/dist/evidence-pack.js +423 -0
  230. package/dist/evidence-pack.js.map +1 -0
  231. package/dist/flows/answers.js +289 -0
  232. package/dist/flows/answers.js.map +1 -0
  233. package/dist/flows/change.js +811 -0
  234. package/dist/flows/change.js.map +1 -0
  235. package/dist/flows/checkStatus.js +524 -0
  236. package/dist/flows/checkStatus.js.map +1 -0
  237. package/dist/flows/ci.js +236 -0
  238. package/dist/flows/ci.js.map +1 -0
  239. package/dist/flows/ciFailure.js +76 -0
  240. package/dist/flows/ciFailure.js.map +1 -0
  241. package/dist/flows/common.js +522 -0
  242. package/dist/flows/common.js.map +1 -0
  243. package/dist/flows/default-branch.js +29 -0
  244. package/dist/flows/default-branch.js.map +1 -0
  245. package/dist/flows/defectDraft.js +447 -0
  246. package/dist/flows/defectDraft.js.map +1 -0
  247. package/dist/flows/defects.js +623 -0
  248. package/dist/flows/defects.js.map +1 -0
  249. package/dist/flows/digest.js +295 -0
  250. package/dist/flows/digest.js.map +1 -0
  251. package/dist/flows/impact.js +82 -0
  252. package/dist/flows/impact.js.map +1 -0
  253. package/dist/flows/index.js +23 -0
  254. package/dist/flows/index.js.map +1 -0
  255. package/dist/flows/intent-sources.js +72 -0
  256. package/dist/flows/intent-sources.js.map +1 -0
  257. package/dist/flows/mergeCases.js +169 -0
  258. package/dist/flows/mergeCases.js.map +1 -0
  259. package/dist/flows/nightlyRun.js +82 -0
  260. package/dist/flows/nightlyRun.js.map +1 -0
  261. package/dist/flows/outage.js +64 -0
  262. package/dist/flows/outage.js.map +1 -0
  263. package/dist/flows/postMerge.js +5 -0
  264. package/dist/flows/postMerge.js.map +1 -0
  265. package/dist/flows/prCheck.js +5 -0
  266. package/dist/flows/prCheck.js.map +1 -0
  267. package/dist/flows/prTarget.js +66 -0
  268. package/dist/flows/prTarget.js.map +1 -0
  269. package/dist/flows/qa.js +363 -0
  270. package/dist/flows/qa.js.map +1 -0
  271. package/dist/flows/questions.js +160 -0
  272. package/dist/flows/questions.js.map +1 -0
  273. package/dist/flows/recovery.js +64 -0
  274. package/dist/flows/recovery.js.map +1 -0
  275. package/dist/flows/rerun.js +50 -0
  276. package/dist/flows/rerun.js.map +1 -0
  277. package/dist/flows/testDesign.js +294 -0
  278. package/dist/flows/testDesign.js.map +1 -0
  279. package/dist/flows/testDesignJob.js +46 -0
  280. package/dist/flows/testDesignJob.js.map +1 -0
  281. package/dist/flows/testRepo.js +228 -0
  282. package/dist/flows/testRepo.js.map +1 -0
  283. package/dist/flows/testSavings.js +381 -0
  284. package/dist/flows/testSavings.js.map +1 -0
  285. package/dist/flows/testStatus.js +343 -0
  286. package/dist/flows/testStatus.js.map +1 -0
  287. package/dist/flows/ticketContext.js +425 -0
  288. package/dist/flows/ticketContext.js.map +1 -0
  289. package/dist/flows/ticketReview.js +249 -0
  290. package/dist/flows/ticketReview.js.map +1 -0
  291. package/dist/flows/ticks.js +73 -0
  292. package/dist/flows/ticks.js.map +1 -0
  293. package/dist/hive/admin.js +122 -0
  294. package/dist/hive/admin.js.map +1 -0
  295. package/dist/hive/auth.js +130 -0
  296. package/dist/hive/auth.js.map +1 -0
  297. package/dist/hive/billing.js +278 -0
  298. package/dist/hive/billing.js.map +1 -0
  299. package/dist/hive/config.js +63 -0
  300. package/dist/hive/config.js.map +1 -0
  301. package/dist/hive/db.js +186 -0
  302. package/dist/hive/db.js.map +1 -0
  303. package/dist/hive/embed.js +76 -0
  304. package/dist/hive/embed.js.map +1 -0
  305. package/dist/hive/errors.js +17 -0
  306. package/dist/hive/errors.js.map +1 -0
  307. package/dist/hive/google.js +75 -0
  308. package/dist/hive/google.js.map +1 -0
  309. package/dist/hive/index.js +25 -0
  310. package/dist/hive/index.js.map +1 -0
  311. package/dist/hive/jwt.js +57 -0
  312. package/dist/hive/jwt.js.map +1 -0
  313. package/dist/hive/keys.js +61 -0
  314. package/dist/hive/keys.js.map +1 -0
  315. package/dist/hive/mail.js +27 -0
  316. package/dist/hive/mail.js.map +1 -0
  317. package/dist/hive/native-push.js +255 -0
  318. package/dist/hive/native-push.js.map +1 -0
  319. package/dist/hive/pairing.js +342 -0
  320. package/dist/hive/pairing.js.map +1 -0
  321. package/dist/hive/presence.js +121 -0
  322. package/dist/hive/presence.js.map +1 -0
  323. package/dist/hive/push.js +185 -0
  324. package/dist/hive/push.js.map +1 -0
  325. package/dist/hive/relay.js +205 -0
  326. package/dist/hive/relay.js.map +1 -0
  327. package/dist/hive/routes.js +228 -0
  328. package/dist/hive/routes.js.map +1 -0
  329. package/dist/hive/server.js +12 -0
  330. package/dist/hive/server.js.map +1 -0
  331. package/dist/hive/session.js +28 -0
  332. package/dist/hive/session.js.map +1 -0
  333. package/dist/hive/tenants.js +287 -0
  334. package/dist/hive/tenants.js.map +1 -0
  335. package/dist/hive/tunnel/cloudflare.js +160 -0
  336. package/dist/hive/tunnel/cloudflare.js.map +1 -0
  337. package/dist/hive/tunnel/mock.js +52 -0
  338. package/dist/hive/tunnel/mock.js.map +1 -0
  339. package/dist/hive/tunnel/provider.js +19 -0
  340. package/dist/hive/tunnel/provider.js.map +1 -0
  341. package/dist/hive/updates.js +61 -0
  342. package/dist/hive/updates.js.map +1 -0
  343. package/dist/http-error.js +11 -0
  344. package/dist/http-error.js.map +1 -0
  345. package/dist/impact/classify.js +226 -0
  346. package/dist/impact/classify.js.map +1 -0
  347. package/dist/impact/find.js +259 -0
  348. package/dist/impact/find.js.map +1 -0
  349. package/dist/impact/pr.js +54 -0
  350. package/dist/impact/pr.js.map +1 -0
  351. package/dist/impact/store.js +365 -0
  352. package/dist/impact/store.js.map +1 -0
  353. package/dist/impact/text.js +158 -0
  354. package/dist/impact/text.js.map +1 -0
  355. package/dist/index.js +288 -0
  356. package/dist/index.js.map +1 -0
  357. package/dist/integrations/adf.js +397 -0
  358. package/dist/integrations/adf.js.map +1 -0
  359. package/dist/integrations/bot-marker.js +103 -0
  360. package/dist/integrations/bot-marker.js.map +1 -0
  361. package/dist/integrations/github-issues.js +705 -0
  362. package/dist/integrations/github-issues.js.map +1 -0
  363. package/dist/integrations/github.js +1284 -0
  364. package/dist/integrations/github.js.map +1 -0
  365. package/dist/integrations/issue-create.js +60 -0
  366. package/dist/integrations/issue-create.js.map +1 -0
  367. package/dist/integrations/jira.js +279 -0
  368. package/dist/integrations/jira.js.map +1 -0
  369. package/dist/integrations/linear.js +273 -0
  370. package/dist/integrations/linear.js.map +1 -0
  371. package/dist/integrations/own-identity-warm.js +47 -0
  372. package/dist/integrations/own-identity-warm.js.map +1 -0
  373. package/dist/integrations/own-identity.js +39 -0
  374. package/dist/integrations/own-identity.js.map +1 -0
  375. package/dist/integrations/status-change.js +42 -0
  376. package/dist/integrations/status-change.js.map +1 -0
  377. package/dist/lead-defects.js +202 -0
  378. package/dist/lead-defects.js.map +1 -0
  379. package/dist/lead-digest.js +333 -0
  380. package/dist/lead-digest.js.map +1 -0
  381. package/dist/lead-release.js +286 -0
  382. package/dist/lead-release.js.map +1 -0
  383. package/dist/lead.js +328 -0
  384. package/dist/lead.js.map +1 -0
  385. package/dist/legacy-names.js +51 -0
  386. package/dist/legacy-names.js.map +1 -0
  387. package/dist/limits.js +44 -0
  388. package/dist/limits.js.map +1 -0
  389. package/dist/link-trust.js +224 -0
  390. package/dist/link-trust.js.map +1 -0
  391. package/dist/links.js +219 -0
  392. package/dist/links.js.map +1 -0
  393. package/dist/loopback.js +35 -0
  394. package/dist/loopback.js.map +1 -0
  395. package/dist/model-cap.js +60 -0
  396. package/dist/model-cap.js.map +1 -0
  397. package/dist/model-usage.js +173 -0
  398. package/dist/model-usage.js.map +1 -0
  399. package/dist/monitor/backfill.js +39 -0
  400. package/dist/monitor/backfill.js.map +1 -0
  401. package/dist/monitor/browser-probe.js +198 -0
  402. package/dist/monitor/browser-probe.js.map +1 -0
  403. package/dist/monitor/catch-up.js +31 -0
  404. package/dist/monitor/catch-up.js.map +1 -0
  405. package/dist/monitor/pollers.js +1606 -0
  406. package/dist/monitor/pollers.js.map +1 -0
  407. package/dist/monitor/probes.js +178 -0
  408. package/dist/monitor/probes.js.map +1 -0
  409. package/dist/monitor/self-health.js +228 -0
  410. package/dist/monitor/self-health.js.map +1 -0
  411. package/dist/monitor/statuspage.js +105 -0
  412. package/dist/monitor/statuspage.js.map +1 -0
  413. package/dist/nightly-scheduler.js +127 -0
  414. package/dist/nightly-scheduler.js.map +1 -0
  415. package/dist/nightly.js +141 -0
  416. package/dist/nightly.js.map +1 -0
  417. package/dist/notify/headline.js +114 -0
  418. package/dist/notify/headline.js.map +1 -0
  419. package/dist/notify/push.js +174 -0
  420. package/dist/notify/push.js.map +1 -0
  421. package/dist/object-cards.js +585 -0
  422. package/dist/object-cards.js.map +1 -0
  423. package/dist/object-links.js +47 -0
  424. package/dist/object-links.js.map +1 -0
  425. package/dist/onboarding-checks.js +141 -0
  426. package/dist/onboarding-checks.js.map +1 -0
  427. package/dist/onboarding.js +401 -0
  428. package/dist/onboarding.js.map +1 -0
  429. package/dist/path-filters.js +62 -0
  430. package/dist/path-filters.js.map +1 -0
  431. package/dist/phone/alerts.js +67 -0
  432. package/dist/phone/alerts.js.map +1 -0
  433. package/dist/phone/auth.js +240 -0
  434. package/dist/phone/auth.js.map +1 -0
  435. package/dist/phone/pairing.js +442 -0
  436. package/dist/phone/pairing.js.map +1 -0
  437. package/dist/phone/prefs.js +27 -0
  438. package/dist/phone/prefs.js.map +1 -0
  439. package/dist/phone/tailscale.js +161 -0
  440. package/dist/phone/tailscale.js.map +1 -0
  441. package/dist/pr-scope.js +441 -0
  442. package/dist/pr-scope.js.map +1 -0
  443. package/dist/proc.js +156 -0
  444. package/dist/proc.js.map +1 -0
  445. package/dist/profile/cache.js +108 -0
  446. package/dist/profile/cache.js.map +1 -0
  447. package/dist/profile/ci.js +216 -0
  448. package/dist/profile/ci.js.map +1 -0
  449. package/dist/profile/index.js +8 -0
  450. package/dist/profile/index.js.map +1 -0
  451. package/dist/profile/job.js +135 -0
  452. package/dist/profile/job.js.map +1 -0
  453. package/dist/profile/queries/go-tags.scm +47 -0
  454. package/dist/profile/queries/java-tags.scm +25 -0
  455. package/dist/profile/queries/javascript-tags.scm +104 -0
  456. package/dist/profile/queries/python-tags.scm +19 -0
  457. package/dist/profile/queries/typescript-tags.scm +28 -0
  458. package/dist/profile/scan-thread.js +42 -0
  459. package/dist/profile/scan-thread.js.map +1 -0
  460. package/dist/profile/scan-worker.js +16 -0
  461. package/dist/profile/scan-worker.js.map +1 -0
  462. package/dist/profile/scan.js +351 -0
  463. package/dist/profile/scan.js.map +1 -0
  464. package/dist/profile/stack.js +528 -0
  465. package/dist/profile/stack.js.map +1 -0
  466. package/dist/profile/store.js +35 -0
  467. package/dist/profile/store.js.map +1 -0
  468. package/dist/profile/tests.js +399 -0
  469. package/dist/profile/tests.js.map +1 -0
  470. package/dist/queue.js +350 -0
  471. package/dist/queue.js.map +1 -0
  472. package/dist/refs.js +756 -0
  473. package/dist/refs.js.map +1 -0
  474. package/dist/release-notes.js +272 -0
  475. package/dist/release-notes.js.map +1 -0
  476. package/dist/reports/build.js +243 -0
  477. package/dist/reports/build.js.map +1 -0
  478. package/dist/reports/index.js +211 -0
  479. package/dist/reports/index.js.map +1 -0
  480. package/dist/reports/store.js +150 -0
  481. package/dist/reports/store.js.map +1 -0
  482. package/dist/reports/ticket-titles.js +124 -0
  483. package/dist/reports/ticket-titles.js.map +1 -0
  484. package/dist/reports/trace-map.js +1278 -0
  485. package/dist/reports/trace-map.js.map +1 -0
  486. package/dist/reports/traceability.js +422 -0
  487. package/dist/reports/traceability.js.map +1 -0
  488. package/dist/repos/mirror.js +356 -0
  489. package/dist/repos/mirror.js.map +1 -0
  490. package/dist/repos-github.js +108 -0
  491. package/dist/repos-github.js.map +1 -0
  492. package/dist/repos.js +891 -0
  493. package/dist/repos.js.map +1 -0
  494. package/dist/review/backend-anthropic.js +90 -0
  495. package/dist/review/backend-anthropic.js.map +1 -0
  496. package/dist/review/backend-cli.js +248 -0
  497. package/dist/review/backend-cli.js.map +1 -0
  498. package/dist/review/backend-codex.js +81 -0
  499. package/dist/review/backend-codex.js.map +1 -0
  500. package/dist/review/backend-mock.js +686 -0
  501. package/dist/review/backend-mock.js.map +1 -0
  502. package/dist/review/backend-only.js +168 -0
  503. package/dist/review/backend-only.js.map +1 -0
  504. package/dist/review/backend.js +105 -0
  505. package/dist/review/backend.js.map +1 -0
  506. package/dist/review/baseline/render-v1.js +483 -0
  507. package/dist/review/baseline/render-v1.js.map +1 -0
  508. package/dist/review/change-summary.js +197 -0
  509. package/dist/review/change-summary.js.map +1 -0
  510. package/dist/review/changelog.js +40 -0
  511. package/dist/review/changelog.js.map +1 -0
  512. package/dist/review/check.js +494 -0
  513. package/dist/review/check.js.map +1 -0
  514. package/dist/review/checkout.js +185 -0
  515. package/dist/review/checkout.js.map +1 -0
  516. package/dist/review/classify.js +178 -0
  517. package/dist/review/classify.js.map +1 -0
  518. package/dist/review/coverage.js +347 -0
  519. package/dist/review/coverage.js.map +1 -0
  520. package/dist/review/decision-eval.js +121 -0
  521. package/dist/review/decision-eval.js.map +1 -0
  522. package/dist/review/deliver.js +104 -0
  523. package/dist/review/deliver.js.map +1 -0
  524. package/dist/review/designer-eval.js +280 -0
  525. package/dist/review/designer-eval.js.map +1 -0
  526. package/dist/review/dogfood-digest.js +136 -0
  527. package/dist/review/dogfood-digest.js.map +1 -0
  528. package/dist/review/dogfood-eval.js +486 -0
  529. package/dist/review/dogfood-eval.js.map +1 -0
  530. package/dist/review/environment.js +109 -0
  531. package/dist/review/environment.js.map +1 -0
  532. package/dist/review/eval.js +405 -0
  533. package/dist/review/eval.js.map +1 -0
  534. package/dist/review/glob.js +110 -0
  535. package/dist/review/glob.js.map +1 -0
  536. package/dist/review/golden-export.js +219 -0
  537. package/dist/review/golden-export.js.map +1 -0
  538. package/dist/review/impact.js +406 -0
  539. package/dist/review/impact.js.map +1 -0
  540. package/dist/review/imports.js +542 -0
  541. package/dist/review/imports.js.map +1 -0
  542. package/dist/review/index.js +512 -0
  543. package/dist/review/index.js.map +1 -0
  544. package/dist/review/intent.js +128 -0
  545. package/dist/review/intent.js.map +1 -0
  546. package/dist/review/lenses.js +167 -0
  547. package/dist/review/lenses.js.map +1 -0
  548. package/dist/review/linked-tickets.js +293 -0
  549. package/dist/review/linked-tickets.js.map +1 -0
  550. package/dist/review/merge.js +370 -0
  551. package/dist/review/merge.js.map +1 -0
  552. package/dist/review/on-demand.js +218 -0
  553. package/dist/review/on-demand.js.map +1 -0
  554. package/dist/review/prompt-eval.js +299 -0
  555. package/dist/review/prompt-eval.js.map +1 -0
  556. package/dist/review/prompt-variants.js +37 -0
  557. package/dist/review/prompt-variants.js.map +1 -0
  558. package/dist/review/readability-eval.js +217 -0
  559. package/dist/review/readability-eval.js.map +1 -0
  560. package/dist/review/readability.js +295 -0
  561. package/dist/review/readability.js.map +1 -0
  562. package/dist/review/render.js +2409 -0
  563. package/dist/review/render.js.map +1 -0
  564. package/dist/review/repo.js +194 -0
  565. package/dist/review/repo.js.map +1 -0
  566. package/dist/review/report-plan.js +90 -0
  567. package/dist/review/report-plan.js.map +1 -0
  568. package/dist/review/routes.js +195 -0
  569. package/dist/review/routes.js.map +1 -0
  570. package/dist/review/run-summary.js +34 -0
  571. package/dist/review/run-summary.js.map +1 -0
  572. package/dist/review/run.js +245 -0
  573. package/dist/review/run.js.map +1 -0
  574. package/dist/review/scope.js +454 -0
  575. package/dist/review/scope.js.map +1 -0
  576. package/dist/review/security.js +432 -0
  577. package/dist/review/security.js.map +1 -0
  578. package/dist/review/signals.js +550 -0
  579. package/dist/review/signals.js.map +1 -0
  580. package/dist/review/specs.js +150 -0
  581. package/dist/review/specs.js.map +1 -0
  582. package/dist/review/ste.js +133 -0
  583. package/dist/review/ste.js.map +1 -0
  584. package/dist/review/test-repo-file.js +18 -0
  585. package/dist/review/test-repo-file.js.map +1 -0
  586. package/dist/review/test-repo-lines.js +53 -0
  587. package/dist/review/test-repo-lines.js.map +1 -0
  588. package/dist/review/ticket-on-demand.js +232 -0
  589. package/dist/review/ticket-on-demand.js.map +1 -0
  590. package/dist/review/yaml.js +298 -0
  591. package/dist/review/yaml.js.map +1 -0
  592. package/dist/room.js +361 -0
  593. package/dist/room.js.map +1 -0
  594. package/dist/routes/activity.js +219 -0
  595. package/dist/routes/activity.js.map +1 -0
  596. package/dist/routes/call.js +29 -0
  597. package/dist/routes/call.js.map +1 -0
  598. package/dist/routes/cards.js +40 -0
  599. package/dist/routes/cards.js.map +1 -0
  600. package/dist/routes/cases.js +133 -0
  601. package/dist/routes/cases.js.map +1 -0
  602. package/dist/routes/connect.js +268 -0
  603. package/dist/routes/connect.js.map +1 -0
  604. package/dist/routes/connection-presets.js +32 -0
  605. package/dist/routes/connection-presets.js.map +1 -0
  606. package/dist/routes/connections.js +177 -0
  607. package/dist/routes/connections.js.map +1 -0
  608. package/dist/routes/disk.js +19 -0
  609. package/dist/routes/disk.js.map +1 -0
  610. package/dist/routes/docs.js +71 -0
  611. package/dist/routes/docs.js.map +1 -0
  612. package/dist/routes/dot-suggest.js +1002 -0
  613. package/dist/routes/dot-suggest.js.map +1 -0
  614. package/dist/routes/evidence-pack.js +16 -0
  615. package/dist/routes/evidence-pack.js.map +1 -0
  616. package/dist/routes/health.js +121 -0
  617. package/dist/routes/health.js.map +1 -0
  618. package/dist/routes/impact.js +48 -0
  619. package/dist/routes/impact.js.map +1 -0
  620. package/dist/routes/lead.js +50 -0
  621. package/dist/routes/lead.js.map +1 -0
  622. package/dist/routes/links.js +13 -0
  623. package/dist/routes/links.js.map +1 -0
  624. package/dist/routes/markdown.js +62 -0
  625. package/dist/routes/markdown.js.map +1 -0
  626. package/dist/routes/onboarding.js +47 -0
  627. package/dist/routes/onboarding.js.map +1 -0
  628. package/dist/routes/phone.js +231 -0
  629. package/dist/routes/phone.js.map +1 -0
  630. package/dist/routes/release-notes.js +30 -0
  631. package/dist/routes/release-notes.js.map +1 -0
  632. package/dist/routes/reports.js +102 -0
  633. package/dist/routes/reports.js.map +1 -0
  634. package/dist/routes/repos.js +91 -0
  635. package/dist/routes/repos.js.map +1 -0
  636. package/dist/routes/review.js +283 -0
  637. package/dist/routes/review.js.map +1 -0
  638. package/dist/routes/roles.js +114 -0
  639. package/dist/routes/roles.js.map +1 -0
  640. package/dist/routes/room.js +21 -0
  641. package/dist/routes/room.js.map +1 -0
  642. package/dist/routes/runner.js +156 -0
  643. package/dist/routes/runner.js.map +1 -0
  644. package/dist/routes/runs.js +84 -0
  645. package/dist/routes/runs.js.map +1 -0
  646. package/dist/routes/setup.js +18 -0
  647. package/dist/routes/setup.js.map +1 -0
  648. package/dist/routes/test-runs.js +220 -0
  649. package/dist/routes/test-runs.js.map +1 -0
  650. package/dist/routes/ticket-status.js +17 -0
  651. package/dist/routes/ticket-status.js.map +1 -0
  652. package/dist/routes/traceability.js +143 -0
  653. package/dist/routes/traceability.js.map +1 -0
  654. package/dist/routes/true.js +142 -0
  655. package/dist/routes/true.js.map +1 -0
  656. package/dist/routes/updates.js +70 -0
  657. package/dist/routes/updates.js.map +1 -0
  658. package/dist/runner/adapters/index.js +12 -0
  659. package/dist/runner/adapters/index.js.map +1 -0
  660. package/dist/runner/adapters/playwright.js +68 -0
  661. package/dist/runner/adapters/playwright.js.map +1 -0
  662. package/dist/runner/aivision/cases.js +172 -0
  663. package/dist/runner/aivision/cases.js.map +1 -0
  664. package/dist/runner/aivision/cli.js +201 -0
  665. package/dist/runner/aivision/cli.js.map +1 -0
  666. package/dist/runner/aivision/index.js +281 -0
  667. package/dist/runner/aivision/index.js.map +1 -0
  668. package/dist/runner/aivision/server.js +394 -0
  669. package/dist/runner/aivision/server.js.map +1 -0
  670. package/dist/runner/aivision/shared.js +140 -0
  671. package/dist/runner/aivision/shared.js.map +1 -0
  672. package/dist/runner/artifact-cap.js +189 -0
  673. package/dist/runner/artifact-cap.js.map +1 -0
  674. package/dist/runner/artifacts.js +433 -0
  675. package/dist/runner/artifacts.js.map +1 -0
  676. package/dist/runner/command.js +564 -0
  677. package/dist/runner/command.js.map +1 -0
  678. package/dist/runner/copyfiles.js +221 -0
  679. package/dist/runner/copyfiles.js.map +1 -0
  680. package/dist/runner/engines.js +32 -0
  681. package/dist/runner/engines.js.map +1 -0
  682. package/dist/runner/evidence.js +114 -0
  683. package/dist/runner/evidence.js.map +1 -0
  684. package/dist/runner/host-env.js +160 -0
  685. package/dist/runner/host-env.js.map +1 -0
  686. package/dist/runner/index.js +1221 -0
  687. package/dist/runner/index.js.map +1 -0
  688. package/dist/runner/observe.js +603 -0
  689. package/dist/runner/observe.js.map +1 -0
  690. package/dist/runner/playwright-json.js +108 -0
  691. package/dist/runner/playwright-json.js.map +1 -0
  692. package/dist/runner/pwgen/exec.js +192 -0
  693. package/dist/runner/pwgen/exec.js.map +1 -0
  694. package/dist/runner/pwgen/explore.js +111 -0
  695. package/dist/runner/pwgen/explore.js.map +1 -0
  696. package/dist/runner/pwgen/index.js +423 -0
  697. package/dist/runner/pwgen/index.js.map +1 -0
  698. package/dist/runner/pwgen/propose.js +69 -0
  699. package/dist/runner/pwgen/propose.js.map +1 -0
  700. package/dist/runner/pwgen/source.js +632 -0
  701. package/dist/runner/pwgen/source.js.map +1 -0
  702. package/dist/runner/setup.js +222 -0
  703. package/dist/runner/setup.js.map +1 -0
  704. package/dist/runner/step-reporter.js +107 -0
  705. package/dist/runner/step-reporter.js.map +1 -0
  706. package/dist/runner/test-repo.js +326 -0
  707. package/dist/runner/test-repo.js.map +1 -0
  708. package/dist/runner/typed-value.js +46 -0
  709. package/dist/runner/typed-value.js.map +1 -0
  710. package/dist/runner/verify.js +133 -0
  711. package/dist/runner/verify.js.map +1 -0
  712. package/dist/runner/worktree.js +349 -0
  713. package/dist/runner/worktree.js.map +1 -0
  714. package/dist/sandbox.js +61 -0
  715. package/dist/sandbox.js.map +1 -0
  716. package/dist/server.js +262 -0
  717. package/dist/server.js.map +1 -0
  718. package/dist/shadow-week.js +126 -0
  719. package/dist/shadow-week.js.map +1 -0
  720. package/dist/shutdown.js +92 -0
  721. package/dist/shutdown.js.map +1 -0
  722. package/dist/slack/index.js +645 -0
  723. package/dist/slack/index.js.map +1 -0
  724. package/dist/stages/config.js +147 -0
  725. package/dist/stages/config.js.map +1 -0
  726. package/dist/stages/index.js +41 -0
  727. package/dist/stages/index.js.map +1 -0
  728. package/dist/suites.js +293 -0
  729. package/dist/suites.js.map +1 -0
  730. package/dist/target-url.js +116 -0
  731. package/dist/target-url.js.map +1 -0
  732. package/dist/test-runs.js +662 -0
  733. package/dist/test-runs.js.map +1 -0
  734. package/dist/ticket-keys.js +97 -0
  735. package/dist/ticket-keys.js.map +1 -0
  736. package/dist/ticket-supersede.js +105 -0
  737. package/dist/ticket-supersede.js.map +1 -0
  738. package/dist/tinybee/ed25519.js +99 -0
  739. package/dist/tinybee/ed25519.js.map +1 -0
  740. package/dist/tinybee/models-routes.js +19 -0
  741. package/dist/tinybee/models-routes.js.map +1 -0
  742. package/dist/tinybee/pair-payload.js +41 -0
  743. package/dist/tinybee/pair-payload.js.map +1 -0
  744. package/dist/tinybee/update-manifest.js +77 -0
  745. package/dist/tinybee/update-manifest.js.map +1 -0
  746. package/dist/tinybee/well-known.js +64 -0
  747. package/dist/tinybee/well-known.js.map +1 -0
  748. package/dist/tinybee/workflows/activity.js +23 -0
  749. package/dist/tinybee/workflows/activity.js.map +1 -0
  750. package/dist/tinybee/workflows/cron.js +210 -0
  751. package/dist/tinybee/workflows/cron.js.map +1 -0
  752. package/dist/tinybee/workflows/engine.js +371 -0
  753. package/dist/tinybee/workflows/engine.js.map +1 -0
  754. package/dist/tinybee/workflows/from-text.js +203 -0
  755. package/dist/tinybee/workflows/from-text.js.map +1 -0
  756. package/dist/tinybee/workflows/routes.js +189 -0
  757. package/dist/tinybee/workflows/routes.js.map +1 -0
  758. package/dist/tinybee/workflows/scheduler.js +100 -0
  759. package/dist/tinybee/workflows/scheduler.js.map +1 -0
  760. package/dist/tinybee/workflows/skills.js +227 -0
  761. package/dist/tinybee/workflows/skills.js.map +1 -0
  762. package/dist/tinybee/workflows/store.js +205 -0
  763. package/dist/tinybee/workflows/store.js.map +1 -0
  764. package/dist/tinybee/workflows/types.js +180 -0
  765. package/dist/tinybee/workflows/types.js.map +1 -0
  766. package/dist/tinybee/workflows/yaml.js +323 -0
  767. package/dist/tinybee/workflows/yaml.js.map +1 -0
  768. package/dist/true/api.js +495 -0
  769. package/dist/true/api.js.map +1 -0
  770. package/dist/true/client.js +292 -0
  771. package/dist/true/client.js.map +1 -0
  772. package/dist/true/clock.js +36 -0
  773. package/dist/true/clock.js.map +1 -0
  774. package/dist/true/events.js +125 -0
  775. package/dist/true/events.js.map +1 -0
  776. package/dist/true/hosts.js +98 -0
  777. package/dist/true/hosts.js.map +1 -0
  778. package/dist/true/index.js +29 -0
  779. package/dist/true/index.js.map +1 -0
  780. package/dist/true/key.js +54 -0
  781. package/dist/true/key.js.map +1 -0
  782. package/dist/true/line.js +69 -0
  783. package/dist/true/line.js.map +1 -0
  784. package/dist/true/mask.js +31 -0
  785. package/dist/true/mask.js.map +1 -0
  786. package/dist/true/names.js +114 -0
  787. package/dist/true/names.js.map +1 -0
  788. package/dist/true/outbox.js +233 -0
  789. package/dist/true/outbox.js.map +1 -0
  790. package/dist/true/replay.js +164 -0
  791. package/dist/true/replay.js.map +1 -0
  792. package/dist/true/settings.js +123 -0
  793. package/dist/true/settings.js.map +1 -0
  794. package/dist/true/status.js +189 -0
  795. package/dist/true/status.js.map +1 -0
  796. package/dist/true/sync-cases.js +222 -0
  797. package/dist/true/sync-cases.js.map +1 -0
  798. package/dist/true/sync-manual.js +295 -0
  799. package/dist/true/sync-manual.js.map +1 -0
  800. package/dist/true/sync-runs.js +109 -0
  801. package/dist/true/sync-runs.js.map +1 -0
  802. package/dist/true/worker.js +414 -0
  803. package/dist/true/worker.js.map +1 -0
  804. package/dist/types.js +32 -0
  805. package/dist/types.js.map +1 -0
  806. package/dist/updates/asks.js +38 -0
  807. package/dist/updates/asks.js.map +1 -0
  808. package/dist/updates/index.js +835 -0
  809. package/dist/updates/index.js.map +1 -0
  810. package/dist/updates/owner.js +24 -0
  811. package/dist/updates/owner.js.map +1 -0
  812. package/dist/updates/prefs.js +118 -0
  813. package/dist/updates/prefs.js.map +1 -0
  814. package/dist/updates/route.js +78 -0
  815. package/dist/updates/route.js.map +1 -0
  816. package/dist/updates/sources.js +345 -0
  817. package/dist/updates/sources.js.map +1 -0
  818. package/dist/updates/words.js +452 -0
  819. package/dist/updates/words.js.map +1 -0
  820. package/dist/version.js +53 -0
  821. package/dist/version.js.map +1 -0
  822. package/dist/view-compute.js +382 -0
  823. package/dist/view-compute.js.map +1 -0
  824. package/dist/view-spec.js +894 -0
  825. package/dist/view-spec.js.map +1 -0
  826. package/dist/web/apple-touch-icon.png +0 -0
  827. package/dist/web/assets/ApprovalCard-Br_z5z7G.css +1 -0
  828. package/dist/web/assets/ApprovalCard-CfGhGFo_.js +3 -0
  829. package/dist/web/assets/CardFromRef-BaTGmZ9c.js +2 -0
  830. package/dist/web/assets/CardFromRef-DO7i2uDd.css +1 -0
  831. package/dist/web/assets/Cases-8l_6UcLh.js +2 -0
  832. package/dist/web/assets/Cases-CpfED0uB.css +1 -0
  833. package/dist/web/assets/Chat-BKDiR0qt.js +3 -0
  834. package/dist/web/assets/Chat-DxjdyYUu.css +1 -0
  835. package/dist/web/assets/ConfirmDialog-CIMveD-b.js +2 -0
  836. package/dist/web/assets/ConnectSheet-Cm5vbZdR.js +4 -0
  837. package/dist/web/assets/Docs-HKGuY0WE.js +2 -0
  838. package/dist/web/assets/Docs-fodKx8S7.css +1 -0
  839. package/dist/web/assets/DotDetail-DskS3NWe.js +2 -0
  840. package/dist/web/assets/DotDetail-OWRSD_1x.css +1 -0
  841. package/dist/web/assets/DotStage-BZDclfzV.css +1 -0
  842. package/dist/web/assets/DotStage-CtMNzCN3.js +2 -0
  843. package/dist/web/assets/Dots-BqCsS34m.js +2 -0
  844. package/dist/web/assets/EvidencePack-DQ3kCJX4.js +2 -0
  845. package/dist/web/assets/EvidencePack-DV_9ETsA.css +1 -0
  846. package/dist/web/assets/FailedDeliveries-1F2kFcs9.js +2 -0
  847. package/dist/web/assets/FailedDeliveries-DXa2_VvI.css +1 -0
  848. package/dist/web/assets/Feed-5wiHRTFK.js +2 -0
  849. package/dist/web/assets/GfmView-C-NYaduC.js +4 -0
  850. package/dist/web/assets/ImpactList-C-RNuDB0.js +2 -0
  851. package/dist/web/assets/ImpactList-C612dFdw.css +1 -0
  852. package/dist/web/assets/Inbox-kc1bKVL_.js +2 -0
  853. package/dist/web/assets/JoinScreen-C3L4wmP3.js +2 -0
  854. package/dist/web/assets/JoinScreen-COeAUv5v.css +1 -0
  855. package/dist/web/assets/LeadDialog-N3Zul9Rw.js +8 -0
  856. package/dist/web/assets/LeadDialog-xyWjAuAS.css +1 -0
  857. package/dist/web/assets/ListeningLine-BRFNaczY.js +2 -0
  858. package/dist/web/assets/ListeningLine-pN8CgyiK.css +1 -0
  859. package/dist/web/assets/Mascots-pIyGpxtD.js +2 -0
  860. package/dist/web/assets/ModelChoices-BxO1zyyr.js +2 -0
  861. package/dist/web/assets/ModelChoices-DQJnVxfs.css +1 -0
  862. package/dist/web/assets/NewDotDialog-CDPUWmgN.js +2 -0
  863. package/dist/web/assets/NewDotDialog-DrPPqkSZ.css +1 -0
  864. package/dist/web/assets/NewTestRunDialog-BQBthVHE.js +2 -0
  865. package/dist/web/assets/NoBreakNames-Csxdqdt6.js +2 -0
  866. package/dist/web/assets/Pair-omex_K7H.js +2 -0
  867. package/dist/web/assets/PushSection-CmqHlE_2.js +2 -0
  868. package/dist/web/assets/ReleaseNotes-B6VqFewP.js +2 -0
  869. package/dist/web/assets/ReleaseNotes-DBJUL7Vm.css +1 -0
  870. package/dist/web/assets/ReportPage-BHS1xWEt.js +162 -0
  871. package/dist/web/assets/Reports-BEHnDIb1.js +2 -0
  872. package/dist/web/assets/ReviewChangeDialog-BVSt-cw-.js +2 -0
  873. package/dist/web/assets/ReviewChangeDialog-BbIlHRx0.css +1 -0
  874. package/dist/web/assets/Room-BoG_uge4.js +2 -0
  875. package/dist/web/assets/Room-evAfiW_e.css +1 -0
  876. package/dist/web/assets/RunActions-ZY7yf1AF.js +2 -0
  877. package/dist/web/assets/RunDetail-C8St20GQ.css +1 -0
  878. package/dist/web/assets/RunDetail-qADXjBvd.js +9 -0
  879. package/dist/web/assets/RunRow-BKEJv8ib.js +2 -0
  880. package/dist/web/assets/RunnerTry-Dgpp67-s.js +6 -0
  881. package/dist/web/assets/RunnerTry-DsweWOfO.css +1 -0
  882. package/dist/web/assets/Settings-fs-QJwNM.js +2 -0
  883. package/dist/web/assets/Setup-DI6hBEP-.js +2 -0
  884. package/dist/web/assets/TestRows-wh03T5Li.js +4 -0
  885. package/dist/web/assets/TestRun-DTOyF-Pv.js +2 -0
  886. package/dist/web/assets/TestRuns-ggDjm1Q8.js +2 -0
  887. package/dist/web/assets/TinyBeeAddLaptop-bc3pmh3T.js +2 -0
  888. package/dist/web/assets/TinyBeeAi-CkyOzhm5.js +2 -0
  889. package/dist/web/assets/TinyBeeConnections-B2K_P38u.js +2 -0
  890. package/dist/web/assets/TinyBeeHome-DSpxX5KS.js +3 -0
  891. package/dist/web/assets/TinyBeePlan-BamiLziu.js +2 -0
  892. package/dist/web/assets/TinyBeeSignup-vHcz0Wen.js +2 -0
  893. package/dist/web/assets/TinyBeeSkills-By9RLUse.js +2 -0
  894. package/dist/web/assets/TinyBeeWorkflow-DeNO7Jsh.js +2 -0
  895. package/dist/web/assets/TinyBeeWorkflowEditor-B6OGC2OT.js +2 -0
  896. package/dist/web/assets/TinyBeeWorkflows-BN4-h6lt.js +2 -0
  897. package/dist/web/assets/Trace-BBCI1aIB.css +1 -0
  898. package/dist/web/assets/Trace-aF92UWaH.js +2 -0
  899. package/dist/web/assets/UpdatesSection-CCWEbkue.js +2 -0
  900. package/dist/web/assets/Welcome-CCcy558Q.js +2 -0
  901. package/dist/web/assets/activity-C3qilrDm.css +1 -0
  902. package/dist/web/assets/activity-CBfTSxqw.js +2 -0
  903. package/dist/web/assets/authedMedia-BTYt_tyu.js +2 -0
  904. package/dist/web/assets/beeApi-BHW8Tx1s.js +2 -0
  905. package/dist/web/assets/data-CmXvx3Mj.js +2 -0
  906. package/dist/web/assets/engines-CfdJODFj.css +1 -0
  907. package/dist/web/assets/format-BBZ8vFyT.js +2 -0
  908. package/dist/web/assets/forms-Coc7p2UF.css +1 -0
  909. package/dist/web/assets/hivePush-DZJDokj7.js +2 -0
  910. package/dist/web/assets/impactModel-MY1OFuiP.js +2 -0
  911. package/dist/web/assets/index-B6qKm1NW.js +13 -0
  912. package/dist/web/assets/index-BvKyT1X7.css +1 -0
  913. package/dist/web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  914. package/dist/web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  915. package/dist/web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  916. package/dist/web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  917. package/dist/web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  918. package/dist/web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  919. package/dist/web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  920. package/dist/web/assets/lead-BL_P_kri.css +1 -0
  921. package/dist/web/assets/model-BIQy5IVG.js +2 -0
  922. package/dist/web/assets/modelsApi-PUSySRQw.js +2 -0
  923. package/dist/web/assets/newDotModel-BaLLyw57.js +2 -0
  924. package/dist/web/assets/onboarding-bfKqnM4Z.css +1 -0
  925. package/dist/web/assets/phone-Rs7FoyG0.css +1 -0
  926. package/dist/web/assets/phoneApi-BG_1-M-D.js +3 -0
  927. package/dist/web/assets/releaseModel-EynYMVOC.js +2 -0
  928. package/dist/web/assets/releaseNotesModel-A1Rtv3cV.js +2 -0
  929. package/dist/web/assets/reports-BWaA1HhM.js +37 -0
  930. package/dist/web/assets/reports-DXwdWQsB.css +1 -0
  931. package/dist/web/assets/router-W6nZsQ33.js +2 -0
  932. package/dist/web/assets/runs-BY0Owv93.css +1 -0
  933. package/dist/web/assets/shadowWeekModel-BUUiww09.js +2 -0
  934. package/dist/web/assets/storage-yvL36AWt.js +2 -0
  935. package/dist/web/assets/store-IqrqHuFR.js +2 -0
  936. package/dist/web/assets/testruns-BzIZ0cR0.css +1 -0
  937. package/dist/web/assets/testruns-DyaqX4ji.js +2 -0
  938. package/dist/web/assets/true-9Q68cs5b.js +2 -0
  939. package/dist/web/assets/true-DPGBpoir.css +1 -0
  940. package/dist/web/assets/ui-DcmhYyYp.js +13 -0
  941. package/dist/web/assets/ui-DxEDgbIx.css +1 -0
  942. package/dist/web/assets/usePauseDot-BV60ZVy1.js +2 -0
  943. package/dist/web/assets/usePauseDot-NrSzMI1C.css +1 -0
  944. package/dist/web/assets/usePush-Dsm-TjlG.js +2 -0
  945. package/dist/web/assets/useRefChips-CbafNx59.js +68 -0
  946. package/dist/web/assets/useRestoreDot-D0B6W82H.js +2 -0
  947. package/dist/web/assets/view-worker-pyeVAhUT.js +2 -0
  948. package/dist/web/assets/workflowUi-QYsd3n9J.js +2 -0
  949. package/dist/web/favicon.png +0 -0
  950. package/dist/web/icon-192.png +0 -0
  951. package/dist/web/icon-512.png +0 -0
  952. package/dist/web/icon-maskable-512.png +0 -0
  953. package/dist/web/index.html +45 -0
  954. package/dist/web/manifest.webmanifest +23 -0
  955. package/dist/web/mascots/argus-attention.svg +7 -0
  956. package/dist/web/mascots/argus-ok.svg +7 -0
  957. package/dist/web/mascots/argus-outage.svg +7 -0
  958. package/dist/web/mascots/argus-running.svg +7 -0
  959. package/dist/web/mascots/bolt-attention.svg +7 -0
  960. package/dist/web/mascots/bolt-ok.svg +7 -0
  961. package/dist/web/mascots/bolt-outage.svg +7 -0
  962. package/dist/web/mascots/bolt-running.svg +7 -0
  963. package/dist/web/mascots/echo-attention.svg +7 -0
  964. package/dist/web/mascots/echo-ok.svg +7 -0
  965. package/dist/web/mascots/echo-outage.svg +7 -0
  966. package/dist/web/mascots/echo-running.svg +7 -0
  967. package/dist/web/mascots/lens-attention.svg +7 -0
  968. package/dist/web/mascots/lens-ok.svg +7 -0
  969. package/dist/web/mascots/lens-outage.svg +7 -0
  970. package/dist/web/mascots/lens-running.svg +7 -0
  971. package/dist/web/mascots/moss-attention.svg +7 -0
  972. package/dist/web/mascots/moss-ok.svg +7 -0
  973. package/dist/web/mascots/moss-outage.svg +7 -0
  974. package/dist/web/mascots/moss-running.svg +7 -0
  975. package/dist/web/mascots/nit-attention.svg +7 -0
  976. package/dist/web/mascots/nit-ok.svg +7 -0
  977. package/dist/web/mascots/nit-outage.svg +7 -0
  978. package/dist/web/mascots/nit-running.svg +7 -0
  979. package/dist/web/mascots/nova-attention.svg +7 -0
  980. package/dist/web/mascots/nova-ok.svg +7 -0
  981. package/dist/web/mascots/nova-outage.svg +7 -0
  982. package/dist/web/mascots/nova-running.svg +7 -0
  983. package/dist/web/mascots/penn-attention.svg +7 -0
  984. package/dist/web/mascots/penn-ok.svg +7 -0
  985. package/dist/web/mascots/penn-outage.svg +7 -0
  986. package/dist/web/mascots/penn-running.svg +7 -0
  987. package/dist/web/mascots/pip-attention.svg +7 -0
  988. package/dist/web/mascots/pip-ok.svg +7 -0
  989. package/dist/web/mascots/pip-outage.svg +7 -0
  990. package/dist/web/mascots/pip-running.svg +7 -0
  991. package/dist/web/mascots/ward-attention.svg +7 -0
  992. package/dist/web/mascots/ward-ok.svg +7 -0
  993. package/dist/web/mascots/ward-outage.svg +7 -0
  994. package/dist/web/mascots/ward-running.svg +7 -0
  995. package/dist/web/sw.js +98 -0
  996. package/dist/webhook-seen.js +53 -0
  997. package/dist/webhook-seen.js.map +1 -0
  998. package/dist/webhooks.js +625 -0
  999. package/dist/webhooks.js.map +1 -0
  1000. package/dist/zip.js +63 -0
  1001. package/dist/zip.js.map +1 -0
  1002. package/docs/API-V2.md +532 -0
  1003. package/docs/CHAT-EVAL.md +130 -0
  1004. package/docs/CHAT-UI.md +416 -0
  1005. package/docs/CONNECTIONS.md +89 -0
  1006. package/docs/DATA-MODEL.md +518 -0
  1007. package/docs/DEPLOY.md +577 -0
  1008. package/docs/DOGFOOD-LEDGER.md +81 -0
  1009. package/docs/GITHUB.md +148 -0
  1010. package/docs/INTEGRATION-MODEL.md +200 -0
  1011. package/docs/LEAD-DOT.md +553 -0
  1012. package/docs/LIST-PATTERNS.md +52 -0
  1013. package/docs/MULTI-REPO.md +766 -0
  1014. package/docs/PARITY.md +276 -0
  1015. package/docs/PR-REVIEW-QA.md +1266 -0
  1016. package/docs/PR-REVIEW.md +357 -0
  1017. package/docs/SANDBOX.md +320 -0
  1018. package/docs/SETUP.md +776 -0
  1019. package/docs/SLACK.md +80 -0
  1020. package/docs/STAGES.md +619 -0
  1021. package/docs/TRACE-MAP.md +89 -0
  1022. package/docs/TRACKERS.md +225 -0
  1023. package/docs/VOICE.md +36 -0
  1024. package/docs/tinybee/00-README.md +45 -0
  1025. package/docs/tinybee/01-PRD.md +216 -0
  1026. package/docs/tinybee/02-architecture-pairing.md +199 -0
  1027. package/docs/tinybee/03-local-agent.md +222 -0
  1028. package/docs/tinybee/04-local-setup-ui.md +128 -0
  1029. package/docs/tinybee/05-mobile-app-ux.md +199 -0
  1030. package/docs/tinybee/06-environments-and-delivery.md +148 -0
  1031. package/docs/tinybee/07-coding-agent-handoff.md +116 -0
  1032. package/docs/tinybee/OPEN-QUESTIONS.md +26 -0
  1033. package/docs/tinybee/PROGRESS.md +134 -0
  1034. package/package.json +111 -4
@@ -0,0 +1,518 @@
1
+ # Data model review
2
+
3
+ This review compares the data that localdost stores today with the data a QA team needs. Stage 1 of the test management epic (KAT-223) is the goal: the dot manages tests on its own. Sync with Jira, Xray, Linear, TestRail, and Katalon True Platform comes after stage 1.
4
+
5
+ The first version of this review mapped Xray Test Executions and TestRail runs onto localdost runs. That was wrong. A localdost run (a **dot run**, the `runs` table) is one automated flow job: one `pr_check`, `post_merge`, or `rerun` that the queue ran. A **test run** is a planned pass over a set of cases. One test run can take results from several dot runs (one per browser, or a rerun after a fix), and a manual test run has no dot run at all because a person works it by hand. Section 2.3 describes the corrected model, and sections 3 to 5 follow it.
6
+
7
+ Scope: section 1 describes `main` at `c7d7c60` (2026-10-09). Sources read: `SCHEMA` (in `src/db.ts` at that commit, now `src/db-schema.ts`) and `INDEXES` in `src/db.ts`, `src/types.ts`, `src/cases.ts`, `src/links.ts`, the tables that other modules create, and [STAGES.md](STAGES.md), [TRACE-MAP.md](TRACE-MAP.md), [MULTI-REPO.md](MULTI-REPO.md), [TRACKERS.md](TRACKERS.md). Items marked "to confirm" were not checked on a primary source.
8
+
9
+ ## Contents
10
+
11
+ 1. Today's model
12
+ 2. The QA domain a tester expects
13
+ 3. Gaps
14
+ 4. External sync
15
+ 5. Phased plan
16
+
17
+ ---
18
+
19
+ ## 1. Today's model
20
+
21
+ ### 1.1 How storage works
22
+
23
+ | Rule | Effect |
24
+ |---|---|
25
+ | One SQLite file, WAL mode | One writer. Good for one server, no sharding |
26
+ | Every `SCHEMA` table has `id TEXT PRIMARY KEY`, `createdAt TEXT`, `extra TEXT` (JSON) | A field that `SCHEMA` does not declare goes into `extra`. Filters on it use `json_extract` and have no index |
27
+ | `migrate()` creates tables and adds columns only | It never renames, drops, or changes a column type. Rollback to an older build is safe |
28
+ | No foreign keys, no `NOT NULL`, no checks | Links between rows are text ids. A deleted row leaves dangling ids. Code, not the database, keeps the rules |
29
+ | JSON columns hold nested entities | Runs, reports, verdicts, and test results are not rows. A query across runs reads and parses every run |
30
+ | Ids from `newId()` sort by time | Some tables use natural ids: `repos` (`owner/name`), `issue_state` (`owner/name#N`), `links` (`lk_` + hash), `ticket_titles` (lower-case ref), `phone_prefs` (`phone`) |
31
+ | Five tables live outside `SCHEMA` | `pages`, `connections`, `connect_values`, `connect_audit`, `poll_cursors`. Each module creates its own |
32
+ | Two names for one key | Older tables use `watchId`. `test_cases` and `case_results` use `dotId`. Both hold `watches.id` |
33
+
34
+ ### 1.2 Stored entities
35
+
36
+ The request names "updates", "asks", and "observations". None of them is a table:
37
+
38
+ - An "ask" is an `approvals` row with status `pending`.
39
+ - An "update" is a live event on the in-memory bus (`LiveEventV2`). It is not stored. The lasting record is `runs.steps`.
40
+ - An "observation" is a line in `artifacts/<runId>/observations.jsonl` (`PageObservation`). The Traceability map reads the files of recent runs on each request.
41
+
42
+ | Table | Holds | Key fields | Links to | Notes |
43
+ |---|---|---|---|---|
44
+ | `watches` | One dot | `name`, `mission`, `notifyWhen`, `mustNot`, `repo`, `repos` (json `WatchRepo[]`), `tracker` (json), `baseUrl`, `probes`, `statusPages`, `runner` (json), `rules` (json), `digestHour`, `paused`; in `extra`: `role`, `instructions`, `mascot`, `connections`, `slackChannel`, `archived`, `review`, `waitForPreviewSec`, `waitForDeploySec`, `deployEnvironment`, `stages`, `stageModels`, `stagesNotice` | `repos.id` through `repos[].repo`; `connections.id` | The product area. Stages: STAGES.md section 5 |
45
+ | `repos` | Workspace repo | id `owner/name`, `defaultBranch`, `private`, `scan` (json state), `intake`, `lastEventAt` | `repo_profiles.repoId` | Shared by dots |
46
+ | `repo_profiles` | One scan of a repo | `repoId`, `sha`, `profile` (json `RepoProfile`: apps, routes, areas, specs, CI, owners), `overrides`, `version`, `mode` | `repos` | Newest row is live; last 5 kept |
47
+ | `events` | One trigger as received | `watchId`, `source`, `kind`, `dedupeKey`, `title`, `url`, `jobId`, `trigger` (json `TriggerEvent`) | `jobs` | Raw intake log |
48
+ | `jobs` | Queue item | `kind` (`JobKind`), `watchId`, `eventId`, `dedupeKey` (unique), `payload`, `status`, `attempts`, `error`, `runAfter`; in `extra`: `checkStatus`, `heldBy` (`model_cap` or `deploy_wait`), `deployWait` (a merge job that waits for the deploy of its commit: `state`, `since`, `environment`, `sha`, `repo`, `runId`, `outcome`) | `events`, `runs.jobId` | |
49
+ | `runs` | One flow execution | `watchId`, `kind`, `trigger` (json, holds a ticket snapshot in `inlineTicket`), `status`, `steps` (json `RunStep[]`), `report` (json `TestReport` with `cases[]` and `evidence`), `verdict` (json, holds `qa: QaReview` with risks and `whatToTest`), `actions` (json), `finishedAt`; in `extra`: `jobId`, `rerunOf`, `diff`, `leaseUntil`, `interruptReason` (`deploy_wait` with `deployWait` while a merge run waits for a deploy), `deployWaitedMs` (the time a merge run waited, which its duration leaves out) | `jobs`, `approvals`, `case_results`, artifacts folder | The largest row. Test results, What to test items, and verdicts live only here |
50
+ | `approvals` | An outward action that waits for a person (an "ask") | `watchId`, `runId`, `action` (json `OutwardAction`), `reason`, `status`, `decidedAt`, `decidedBy`; in `extra`: `expiresAt`, `executedAt`, `error`, `escalation`, `supersededBy`, `closedReason` | `runs` | `decidedBy` names the person when one decided it: a paired device's name, the Tailscale owner's login, or a Slack user as `Slack <name>` (`Slack <user id>` when Slack sends no name); the shared admin token and a server close store none. An edit replaces `action.body`, so the first draft is lost |
51
+ | `outbox` | An action that went nowhere (demo, no credentials) | `watchId`, `runId`, `action` | `runs` | |
52
+ | `memory` | Dot notes | `watchId`, `kind` (`flaky_spec`, `env_quirk`, `convention`, `decision`, `note`), `text`, `source` (`agent`, `user`) | `watches` | Flaky marks are free text |
53
+ | `messages` | Chat and call turns | `watchId`, `role`, `content`, `runId`; in `extra`: `blocks` | `watches`, `runs` | |
54
+ | `links` | Traceability edge | `kind` (`closes`, `references`, `parent`, `blocks`, `tests`, `covers`), `fromRef`, `toRef`, `source`, `watchId`, `meta` | Text refs: `owner/name#N`, `shop-12` | No `defect` kind yet; defects use `references` with source `defect` |
55
+ | `issue_state` | GitHub issue as last read | id `owner/name#N`, `repoId`, `number`, `title`, `bodyHash`, `scopeSig` (labels, type, milestone as JSON text), `state`, `updatedAt`, `testStatus` | `links` by ref | GitHub only. Jira and Linear have no such row |
56
+ | `ticket_titles` | Title cache for refs | id lower-case ref, `title`, `url`, `fetchedAt`, `failedAt`, `error` | refs | One-day cache |
57
+ | `test_cases` | Stored case (KAT-163) | `dotId`, `key` (`TC-n`, unique per dot), `title`, `steps` (json `{action, expected?}[]`), `kind` (`manual`, `playwright`, `aivision`), `requirementRefs` (json), `specPath`, `priority`, `status` (`draft`, `ready`, `retired`), `source`, `updatedAt` | refs; `case_results` | An edit overwrites the row. No revision, no history |
58
+ | `case_results` | Result of a case, append only | `caseId`, `dotId`, `runId`, `result` (`passed`, `failed`, `skipped`, `blocked`), `notes`, `evidence` (json artifact names), `source` (`run`, `manual`), `at` | `test_cases`, `runs` | One row per case per run. No step results, no environment, no build |
59
+ | `probe_state` | Probe health per URL | `watchId`, `url`, `kind`, `down`, `consecutiveFailures`, `lastStatus`, `lastError`, `lastLatencyMs`, `downSince` | `watches` | Current state only, no history |
60
+ | `model_calls` | One answered model call (KAT-362) | `watchId`, `runId`, `stage` (a stage key, `chat`, or `other`), `backend` (`claude`, `codex`, `anthropic`), `inputTokens`, `outputTokens` (empty when the backend sent no count) | `watches`, `runs` | Behind the daily model cap and the Model use card. Rows older than 35 days are removed |
61
+ | `push_subs` | Web push subscription | `endpoint` (unique), `keys`, `subscription`, `deviceId` | `devices` | |
62
+ | `devices` | Paired phone, or a teammate's device | `name`, `platform`, `tokenHash`, `lastSeenAt`, `lastIp`, `revokedAt`, `pairedBy`; in `extra`: `viaInvite`, `role` (`member` or `editor`, unset is a member) | | The named actor behind `decidedBy`. A teammate types the name when joining |
63
+ | `pair_invites` | Invite code for a teammate (KAT-356) | `hash` (sha256 of the code), `expiresAt`, `createdBy`; in `extra`: `role` | | One use: the row is removed when the code is used, cancelled, burned, or past `expiresAt` |
64
+ | `device_audit` | Pairing log | `action`, `deviceId`, `deviceName`, `actor`, `detail` | `devices` | |
65
+ | `phone_prefs` | One row, alert choices | `prefs` (json) | | |
66
+ | `pages` | Report page | `watchId`, `parentId`, `title`, `kind` (`test_plan`, `readiness`, `incident`, `digest`, `note`), `markdown`, `revision`, `sourceRunId` | `runs`, `pages` | Has a revision check (409) |
67
+ | `connections` | MCP server | in `extra`: `name`, `transport`, `tools`, `status`, `preset`, `envRefs` | `watches.connections` | |
68
+ | `connect_values` | Saved setting, encrypted | `key`, `provider`, `enc`, `secret`, `last4`, `updatedBy` | | |
69
+ | `connect_audit` | Settings log | `at`, `provider`, `key`, `action`, `actor`, `last4` | | |
70
+ | `poll_cursors` | Poller position | `id` (for example `github:<repo>:<branch>`), `value` | | |
71
+
72
+ Files in the data folder: `artifacts/<runId>/` (screenshots, videos, traces, logs, JSON reports, `observations.jsonl`), `mirrors/`, `checkouts/`, `repo-cache/`, `graph-cache/`, `runner-cache/`, `eval-candidates/`, `vapid.json`, `secret.key`. The artifact cap (`src/runner/artifact-cap.ts`, 2 GB per dot) deletes screenshots, videos, and traces of the oldest runs first. `case_results.evidence` can then name files that are gone.
73
+
74
+ In memory only: deployment previews (`rememberPreview` in `src/integrations/github.ts`, 500 entries, lost on restart) and live events.
75
+
76
+ ### 1.3 Entities that live inside JSON
77
+
78
+ | Entity | Lives in | Identity | Effect |
79
+ |---|---|---|---|
80
+ | Ticket (title, description, AC, type, milestone, labels) | `runs.trigger.inlineTicket`, `events.trigger` | Key string | The current ticket of Jira and Linear is the snapshot in the newest `ticket_review` run. `ticketCatalog` reads the last 1000 such runs |
81
+ | Automated test result | `runs.report.cases[]` (`TestCaseResult`) | `file` + `title`; the Playwright project is a `[project]` prefix in `title` | No stable test id. Flaky history needs a scan of all runs |
82
+ | Evidence per test | `runs.report.cases[].evidence` | Artifact names | |
83
+ | What to test item | `runs.verdict.qa.whatToTest[]` (`QaTestToRun`) | `t1`, `t2` per review | Not a case. Ids repeat across reviews |
84
+ | Risk, impact area | `runs.verdict.qa.risks[]`, `impactAreas[]` | `r1`, `a1` per review | Area ids are not stable |
85
+ | Feature area | `repo_profiles.profile.areas[]` | Slug, for example `checkout` | Stable per repo. No case points to it |
86
+ | Defect | `approvals.action` with kind `file_defect` or `issue_create`; `action.meta.bugKey`, `meta.filedUrl`; `links` with source `defect` | Bug key or signature hash | No row per defect. State (open or closed) comes from a tracker read |
87
+ | Change (PR, commit) | `runs.trigger.pr`, `push`; `events` | PR number, sha | No row per PR or commit |
88
+ | Page and state | `observations.jsonl`; map nodes built on read | Hash of kind and route | A case cannot point to a page |
89
+ | Stage | Not built | | STAGES.md task 1 adds `RunRecord.stage` |
90
+
91
+ ### 1.4 Diagram
92
+
93
+ Solid lines are id columns. Dotted lines are text refs or JSON. No line is a foreign key in SQLite.
94
+
95
+ ```mermaid
96
+ erDiagram
97
+ watches ||--o{ events : "watchId"
98
+ watches ||--o{ jobs : "watchId"
99
+ events ||--o| jobs : "jobId"
100
+ jobs ||--o{ runs : "jobId"
101
+ watches ||--o{ runs : "watchId"
102
+ runs ||--o{ approvals : "runId"
103
+ runs ||--o{ outbox : "runId"
104
+ runs ||--o{ case_results : "runId"
105
+ runs ||--o{ pages : "sourceRunId"
106
+ runs ||--o{ messages : "runId"
107
+ watches ||--o{ memory : "watchId"
108
+ watches ||--o{ messages : "watchId"
109
+ watches ||--o{ probe_state : "watchId"
110
+ watches ||--o{ links : "watchId"
111
+ watches ||--o{ test_cases : "dotId"
112
+ watches }o--o{ repos : "repos[].repo (json)"
113
+ watches }o--o{ connections : "connections (json)"
114
+ repos ||--o{ repo_profiles : "repoId"
115
+ repos ||--o{ issue_state : "repoId"
116
+ test_cases ||--o{ case_results : "caseId"
117
+ test_cases }o..o{ issue_state : "requirementRefs (text)"
118
+ links }o..o{ issue_state : "fromRef, toRef (text)"
119
+ ticket_titles |o..o{ links : "ref (text)"
120
+ pages ||--o{ pages : "parentId"
121
+ devices ||--o{ push_subs : "deviceId"
122
+ devices ||--o{ device_audit : "deviceId"
123
+
124
+ watches { text id PK
125
+ text name
126
+ json repos
127
+ json tracker
128
+ json runner
129
+ json rules }
130
+ runs { text id PK
131
+ text watchId
132
+ text kind
133
+ json trigger
134
+ json steps
135
+ json report
136
+ json verdict
137
+ json actions }
138
+ test_cases { text id PK
139
+ text dotId
140
+ text key
141
+ json steps
142
+ json requirementRefs
143
+ text specPath
144
+ text status }
145
+ case_results { text id PK
146
+ text caseId
147
+ text runId
148
+ text result
149
+ json evidence }
150
+ links { text id PK
151
+ text kind
152
+ text fromRef
153
+ text toRef
154
+ text source }
155
+ approvals { text id PK
156
+ text runId
157
+ json action
158
+ text status }
159
+ ```
160
+
161
+ ### 1.5 Findings that matter for stage 1
162
+
163
+ | Finding | Detail | Evidence |
164
+ |---|---|---|
165
+ | Small case type | The built `TestCase` is smaller than the STAGES.md design. It has no `covers`, `preconditions`, `data`, `revision`, `origin`, `waitsOn`, AI-Vision form, or Playwright form | `src/types.ts` Test case store vs STAGES.md 4.2 |
166
+ | Spec-only linking | A case links to automation by `specPath` only. Every test in that file sets the case result | `linkRunResults` in `src/cases.ts` |
167
+ | Thin case results | `CaseResult` has no `stage`, `engine`, `sha`, `prRef`, environment, or step results. STAGES.md 4.2 lists the first four | `src/types.ts` |
168
+ | String test identity | Test identity is a string. The Playwright project (browser or device) is a title prefix | `src/runner/playwright-json.ts` |
169
+ | No tracker tables | No table holds Jira or Linear tickets, acceptance criteria, or releases | Section 1.3 |
170
+ | Defects without rows | Defects have no row. Severity, state, and the failing step are not stored | `src/flows/defects.ts` |
171
+ | History lost on edit | Edits lose history: case edits overwrite, approval edits replace the draft, and no row records who decided | `updateCase`, `approveAction` |
172
+ | Flakiness as notes | Flakiness is a free-text memory note plus a scan of recent runs | `memory.kind = flaky_spec`, `src/agent/triage.ts` |
173
+ | Previews in memory | Deploy previews are in memory only | `rememberPreview` |
174
+ | Stages not built | `RunRecord.stage` and `Watch.stages` are not built | grep for `StageKey` in `src/` finds none |
175
+
176
+ ---
177
+
178
+ ## 2. The QA domain a tester expects
179
+
180
+ ### 2.1 Concepts
181
+
182
+ | Concept | What a tester means | Key fields | Relates to |
183
+ |---|---|---|---|
184
+ | Product | What the company ships | name | Has apps |
185
+ | App | One deployable unit under test: web, API, mobile | name, kind, host or base URL per environment, repo | Has areas and pages |
186
+ | Area | A feature area in user words: "Checkout and payment" | stable id, name, paths, routes | Has pages, requirements, cases |
187
+ | Page | A route pattern a user visits: `/checkout` | app, route, title | Has states; cases visit it |
188
+ | State | A distinct view on one page: a dialog, an empty cart | page, heading set or dialog name | Cases visit it |
189
+ | Requirement | A ticket that asks for behavior: story, feature, bug fix | external key, title, type, status, release, text | Has acceptance criteria; cases cover it |
190
+ | Acceptance criterion | One checkable statement of a requirement | requirement, ordinal, text | Cases cover it |
191
+ | Folder | A place in the case tree: "Checkout / Coupons" | name, parent folder, position | Holds cases and folders |
192
+ | Test case | A repeatable check | key, title, preconditions, steps (action, data, expected), priority, type, status, revision, owner, folder | Covers criteria; has automation forms; belongs to suites |
193
+ | Case version | The case as it was at one revision | case, revision, snapshot of title and steps, who, when | Run items pin one |
194
+ | Test step | One action with its expected result | order, action, data, expected | Step results point to it through the pinned version |
195
+ | Test data | Inputs a case needs: users, cards, coupons | name, values or a secret ref, environment | Cases and steps use it |
196
+ | Test suite | A named set of cases: smoke, checkout regression | name, a static list of cases or a saved query (folder, kind, priority, requirement, words) | Plans and test runs use it |
197
+ | Test plan | What to run for a goal, where, by when | name, release, suites or cases, environment, configurations, dates, status | Has test runs, one per configuration |
198
+ | Environment | Where the app runs: local, preview, staging, prod | name, base URL, kind | Test runs run in it |
199
+ | Configuration | How the test runs: browser, OS, device, viewport | browser, version, OS, device, project name | Test runs run with it |
200
+ | Build | The exact code under test | repo, sha, version label, deploy id | Test runs test it |
201
+ | Dot run | One automated flow job of a dot: a PR check, a post-merge run, a rerun | kind, trigger, steps, report, verdict | Produces automated results; never a test run itself |
202
+ | Test run | A planned pass over a set of cases | name, source (manual or automated), plan, suite, environment, configuration, build sha, assignee, status | Has run items |
203
+ | Run item | One case inside one test run | test run, case, pinned case version, state, assignee | Has results |
204
+ | Result | One attempt on a run item; the newest attempt sets the item state | run item, attempt, result, engine, duration, sha, environment, configuration, executed by a person or a dot run | Has step results, evidence, defects |
205
+ | Step result | The outcome of one step of the pinned version | step position, result, actual result | Defects point to it |
206
+ | Evidence | Proof: screenshot, video, trace, log, HAR | kind, file, step, kept until | Belongs to a result or step result |
207
+ | Defect | A product fault found by a test | external key, title, severity, priority, status, steps to reproduce, signature | Points to the failing result or step result, build, environment, requirement |
208
+ | Change | A PR, a commit, or a deploy | repo, number or sha, author, state, merged at, deployed to | Builds come from it; requirements link to it |
209
+ | Release and milestone | A target that groups requirements and builds | name, kind (release, milestone, sprint, cycle), due date, state | Has requirements, plans, readiness |
210
+ | Coverage | Which criteria, requirements, areas, and pages have cases, and which passed | computed per scope and build | Read model |
211
+ | Flakiness history | Pass and fail over time per test and configuration | test key, configuration, window counts, last flip, quarantine state | Read model over results |
212
+ | Audit | Who did what, when, from where | actor, action, entity, before, after, time | Every write |
213
+
214
+ ### 2.2 Target diagram
215
+
216
+ ```mermaid
217
+ erDiagram
218
+ APP ||--o{ AREA : has
219
+ AREA ||--o{ PAGE : has
220
+ PAGE ||--o{ STATE : has
221
+ RELEASE ||--o{ REQUIREMENT : groups
222
+ REQUIREMENT ||--o{ CRITERION : has
223
+ CRITERION }o--o{ TEST_CASE : "covered by"
224
+ FOLDER ||--o{ FOLDER : contains
225
+ FOLDER ||--o{ TEST_CASE : holds
226
+ TEST_CASE ||--o{ CASE_VERSION : "snapshot per edit"
227
+ TEST_CASE }o--o{ PAGE : visits
228
+ TEST_CASE }o--o{ SUITE : "member of (list or query)"
229
+ TEST_CASE }o--o{ TEST_DATA : uses
230
+ PLAN }o--o{ SUITE : runs
231
+ PLAN }o--|| RELEASE : for
232
+ PLAN ||--o{ TEST_RUN : "one per configuration"
233
+ SUITE ||--o{ TEST_RUN : "source (optional)"
234
+ TEST_RUN }o--|| ENVIRONMENT : in
235
+ TEST_RUN }o--|| CONFIGURATION : with
236
+ TEST_RUN }o--|| BUILD : tests
237
+ BUILD }o--|| CHANGE : "built from"
238
+ TEST_RUN ||--o{ RUN_ITEM : has
239
+ RUN_ITEM }o--|| CASE_VERSION : pins
240
+ RUN_ITEM ||--o{ RESULT : "attempts, newest wins"
241
+ DOT_RUN ||--o{ RESULT : "produced (automated)"
242
+ DOT_RUN ||--o{ TEST_RUN : "automated, one per configuration"
243
+ RESULT ||--o{ STEP_RESULT : has
244
+ RESULT ||--o{ EVIDENCE : has
245
+ DEFECT }o--o| RESULT : "found in"
246
+ DEFECT }o--o| STEP_RESULT : "found at"
247
+ DEFECT }o--o{ REQUIREMENT : affects
248
+ CHANGE }o--o{ REQUIREMENT : implements
249
+ ```
250
+
251
+ ### 2.3 Dot runs and test runs
252
+
253
+ A dot run and a test run are different things, and neither one is the other's parent in every case.
254
+
255
+ | Question | Dot run | Test run |
256
+ |---|---|---|
257
+ | What it is | One automated flow job the queue ran | A planned pass over a set of cases |
258
+ | Who starts it | A trigger: a PR, a merge, a schedule, a rerun | A person (from a suite, a selection, or a plan) or a dot run that reported case results |
259
+ | What it holds | Steps, a test report, a verdict, outward actions | Run items, one per case, each with its results |
260
+ | Where it runs | One runner, one command | One environment and one configuration |
261
+ | How many per pass | One | One per configuration: a plan for Chrome and Safari makes two test runs |
262
+
263
+ Three shapes follow from this:
264
+
265
+ - **Manual test run.** A person creates it, works the items one by one, and records results with step results. No dot run takes part.
266
+ - **Automated test run.** A dot run reports results for cases that point to its specs. The dot run creates one automated test run per configuration (Playwright project) it ran, and updates it when its retry pass saves the report again. The test run links back by `dotRunId`, and each result points at the same dot run, so the evidence is one click away. People read it; they do not edit it.
267
+ - **Mixed later.** A manual test run can take an automated result when a person reruns one item's spec. The result then points at that dot run, and the item stays in the manual test run. This is later work.
268
+
269
+ #### Entities
270
+
271
+ | Entity | Fields | Rules |
272
+ |---|---|---|
273
+ | Folder | `dotId`, `name`, `parentId` (none for a top folder), `position`, `repo` (the repo of the GitHub issue a ticket folder was made for, set by the designer only) | A tree per dot. A name is unique among its siblings. Deleting a folder moves its cases and subfolders to its parent, and a query suite on it becomes a static list of the cases it held. A suite or plan never fails on a missing folder: the reference is dropped with a note. `test_cases.folderId` places a case; none means unfiled |
274
+ | Case version | `caseId`, `version`, `snapshot` (title, steps, kind, spec file, priority, status, requirements), `actor`, `at` | Written on create and on every edit. `test_cases.revision` is the newest version. Rows are never changed |
275
+ | Suite | `dotId`, `name`, `kind` (`static` or `query`), `caseIds` for a static list, `query` (folder with or without subfolders, kind, priority, requirement, words) | A query suite is read when a test run starts, so it picks up new cases. Retired cases never join |
276
+ | Plan | `dotId`, `name`, `release`, `suiteIds`, `caseIds`, `environment`, `configs` (list of configurations), `status` | Starting a plan makes one test run per configuration, each with `planId` |
277
+ | Test run | `dotId`, `name`, `source` (`manual` or `automated`), `status` (`open`, `in_progress`, `done`, `cancelled`), `environment`, `config` (browser, OS, device, viewport, project), `buildSha`, `assignee`, `planId`, `suiteId`, `dotRunId` (automated only), `startedAt`, `finishedAt` | A manual test run moves to `in_progress` at its first result. A person closes it. An automated test run is `done` when its dot run saves the report |
278
+ | Run item | `testRunId`, `caseId`, `caseVersion`, `position`, `state` (`untested`, `passed`, `failed`, `blocked`, `retest`, `skipped`), `assignee` | One per case per test run. The pinned version decides which steps the tester sees, so a case edit after the start does not move results |
279
+ | Result | `runItemId`, `testRunId`, `caseId`, `attempt`, `result` (`passed`, `failed`, `blocked`, `skipped`), `notes`, `stage`, `engine`, `durationMs`, `sha`, `environment`, `config`, `executedBy` (a person) or `dotRunId` (automated), `steps` (step results), `evidence`, `defects`, `at` | Every attempt is kept. The newest attempt sets the item state. Retest marks the item `retest`, and the next result is the next attempt |
280
+ | Step result | Inside `result.steps`: `index` (position in the pinned version), `result`, `actual` | A result cannot be `passed` when one of its steps failed |
281
+ | Evidence | Inside `result.evidence`: artifact names of the dot run (screenshots, video, trace) | Manual results carry notes and step actual results for now; uploads are later work |
282
+ | Defect | Inside `result.defects`: `ref` (tracker key or `owner/name#N`), optional `stepIndex` | The defect row of section 3 points at the result and the step |
283
+ | Draft version | A `case_versions` row with `draft` set to `draft` (or `rejected`), plus `ticket` and `impactId` | Proposed by a ticket review (KAT-304). It is not part of the case's history: `caseVersions` and run items ignore it. Accepting it writes a normal next version through the usual edit path and removes the draft row; rejecting keeps it as `rejected` |
284
+ | Impact row | `dotId`, `ticket`, `runId`, `subject` (`case` or `spec`), `caseId`, `specPath`, `title`, `verdict` (`valid`, `update`, `obsolete`), `confidence`, `ticketLine`, `note`, `changes` (the new steps), `signals`, `state` (`open`, `accepted`, `rejected`, `expired`, `none`), `ticketHash`, `draftVersion`, `approvalId`, `decidedAt`, `decidedBy` | One per dot, ticket, and subject (table `case_impacts`). An obsolete row follows its Inbox approval (`case_retire`): executed means accepted, rejected means rejected, expired or superseded means expired, and a case retired by hand accepts it. `ticketHash` is a hash of the ticket title, description, and acceptance criteria the row was checked against, and so of the text a person decided on. A flagged case (`state` open, verdict not `valid`) carries "Needs review". See [STAGES.md](STAGES.md) section 3.8 |
285
+
286
+ `case_results` becomes the results table: it keeps its rows and gains the new columns, so no data moves. A case's latest result is still the newest row for that case, from any test run or none.
287
+
288
+ #### Later work
289
+
290
+ - **Shared steps.** A step list that several cases call, with its own versions. A case version then pins the shared step versions too.
291
+ - **Data-driven iterations.** One case run once per data row (Xray iterations, TestRail parameters). A result then has one entry per iteration, each with its own step results.
292
+ - **Uploads on manual results.** Screenshots and files from the phone, stored next to run artifacts.
293
+
294
+ ---
295
+
296
+ ## 3. Gaps
297
+
298
+ Risk words: Low means a new table or an optional field, with no change to old reads. Medium means a backfill from JSON or a change to how existing code writes. High means a change to an existing field's meaning.
299
+
300
+ | Gap | Today | What breaks without it | Proposed table or field | Migration risk |
301
+ |---|---|---|---|---|
302
+ | Case versions | Missing. `updateCase` overwrites | A result cannot say which steps it ran. Two writers (designer and person) overwrite each other. STAGES.md 3.5 retire and revise rules cannot work | `test_cases.revision` (int, starts at 1); new `case_versions` (append only: `caseId`, `version`, `snapshot` json, `actor`, `at`), written on create and every edit; run items pin `caseVersion`. Later: 409 on a stale revision, as `pages` does | Low. Existing cases get version 1 on first use |
303
+ | Folders | Missing. Cases are one flat list | A team with 300 cases cannot find them. TestRail sections, Xray folders, and True Platform folders have no source | New `folders` (`dotId`, `name`, `parentId`, `position`); `test_cases.folderId` | Low |
304
+ | Step results | Missing. Only `runs.steps` (flow log) and `PageObservation.steps` | The tester cannot see which step failed and what happened. Xray and TestRail step results have no source | `case_results.steps` json: `{ index, result, actual? }[]`, where `index` is the step position in the pinned case version. Step ids that survive a reorder are later work | Low |
305
+ | Test identity | `file` + `title` string; project in the title | Flaky history, case links, and sync keys change when a title or a project changes | `testKey` = `<repo>:<file>::<describe › title>`, plus `project` as its own field on `TestCaseResult`; `test_cases.specTitle` to pick one test inside `specPath` | Medium. New field on new reports; old reports keep the prefix |
306
+ | Test result rows | Missing. `runs.report.cases[]` JSON | Flakiness, history per test, and coverage need a scan and parse of every run | New `test_results`: `dotId`, `runId`, `testKey`, `file`, `title`, `project`, `status`, `retries`, `durationMs`, `error` (first line), `sha`, `environment`, `at`. Index on `(dotId, testKey, at)` | Medium. Backfill from `runs.report`; volume grows with runs (cap by age) |
307
+ | Test runs | Missing. Dot runs stand in for them | A manual pass has nowhere to live. A pass over Chrome and Safari cannot be one plan with two test runs. Xray Test Executions and TestRail runs map to the wrong thing | New `test_runs`: `dotId`, `name`, `source` (`manual`, `automated`), `status`, `environment`, `config` json, `buildSha`, `assignee`, `planId`, `suiteId`, `dotRunId`, `startedAt`, `finishedAt` | Medium. Backfill: one automated test run per dot run that wrote case results |
308
+ | Run items | Missing | A test run cannot list its cases, their state, or who works them | New `run_items`: `testRunId`, `dotId`, `caseId`, `caseVersion`, `position`, `state` (`untested`, `passed`, `failed`, `blocked`, `retest`, `skipped`), `assignee` | Medium. Backfill: one item per case in each backfilled test run, latest result wins |
309
+ | Result context | `result`, `notes`, `evidence`, `source` | The guard cannot say "passed on staging in Chrome at 9be0d11". Duplicate results from two engines mix. A retest overwrites the first attempt | `case_results` gains `runItemId`, `testRunId`, `attempt`, `stage`, `engine` (`playwright`, `aivision`, `manual`), `durationMs`, `sha`, `environment`, `config` json, `executedBy`, `dotRunId`, `steps` json, `defects` json | Low. New columns; existing rows keep their meaning |
310
+ | Requirement store | GitHub only (`issue_state`); Jira and Linear in run snapshots; titles in `ticket_titles` | A case points to a key the dot may not know. Coverage per release is wrong for Jira and Linear. The designer has no current AC to read | New `requirements`: id lower-case ref, `tracker`, `key`, `externalId`, `title`, `type`, `status`, `statusCategory`, `releaseIds`, `description`, `acText`, `bodyHash`, `url`, `fetchedAt`. `issue_state` and `ticket_titles` stay and feed it | Medium. Backfill from `issue_state`, `ticket_titles`, and the newest `ticket_review` run per key |
311
+ | Acceptance criteria | One text field on `Ticket` | A case cannot cover one criterion. Coverage per criterion is not possible | New `criteria`: `requirementRef`, `ordinal`, `text`, `hash`, `status` (`active`, `removed`). `test_cases.covers` json of criterion ids or idea text | Low |
312
+ | Defect records | Approvals and links | No severity, no state, no link to the failing case, step, build, or environment. Readiness counts defects by guess | New `defects`: `dotId`, `ref`, `tracker`, `externalId`, `url`, `title`, `severity` (`critical`, `high`, `medium`, `low`), `priority`, `state`, `sig`, `dotRunId`, `testRunId`, `caseId`, `resultId`, `stepIndex`, `testKey`, `sha`, `environmentId`, `approvalId`, `filedAt`, `closedAt`. `links.kind` adds `defect` (STAGES.md 4.1) | Medium. Backfill from executed `file_defect` and `issue_create` approvals |
313
+ | Test suites | Missing. `smokeGrep` and spec picks per run | The team cannot name "checkout regression" and start a test run from it again. Sync to TestRail suites, Xray Test Sets, and True Platform test suites has no source | New `suites`: `dotId`, `name`, `kind` (`static`, `query`), `caseIds` json, `query` json (folder, subfolders, kind, priority, requirement, words) | Low |
314
+ | Test plans | Missing. `pages.kind = test_plan` is Markdown | No "run these suites on staging in Chrome and Safari for 2026.11". No progress per plan | New `plans`: `dotId`, `name`, `release`, `suiteIds`, `caseIds`, `environment`, `configs` json, `status`, `dueAt`. A plan starts one test run per configuration | Low |
315
+ | Environments | `Watch.baseUrl`, preview URL in memory | Results do not say where they ran. A preview result and a staging result count the same | New `environments`: `dotId`, `name`, `kind` (`local`, `preview`, `staging`, `production`), `baseUrl`. `runs.environment` (snapshot: id, name, baseUrl) | Low |
316
+ | Configurations | Playwright project in the title prefix | Flaky in Safari and stable in Chrome look the same. Xray and TestRail configurations cannot map | `config` json on `test_runs`, `test_results`, and `case_results`: `{ project, browser, browserVersion, os, device, viewport }`, read from the Playwright JSON report | Low |
317
+ | Builds and deploys | `trigger.pr.headSha`, `mergeSha`; previews in memory | "Which build did we test" needs the trigger JSON. Previews vanish on restart | `runs.build` json: `{ repo, sha, ref, version?, deployId?, url? }`. New `deploys`: `repo`, `sha`, `environment`, `url`, `state`, `at` from `deployment_status` | Low |
318
+ | Change records | `runs.trigger`, `events` | "Out of date" and release contents need run scans. A PR has no title or state of its own | New `changes`: id `owner/name#N` or `owner/name@sha`, `kind` (`pr`, `commit`), `title`, `author`, `state`, `headSha`, `baseRef`, `mergedSha`, `mergedAt`, `url` | Low |
319
+ | Releases and milestones | GitHub milestone string on the issue only | Readiness per release works only for GitHub. Jira `fixVersions`, Linear cycles and project milestones are not read | New `releases`: `dotId`, `name`, `kind` (`release`, `milestone`, `sprint`, `cycle`), `tracker`, `externalId`, `dueAt`, `state`. `requirements.releaseIds` | Low |
320
+ | Case areas | Profile areas exist; cases have none | Coverage by area and the map cannot count cases | `test_cases.areaId` (profile area slug), `test_cases.tags` json | Low |
321
+ | Page identity | Map nodes built on read from `observations.jsonl` | A case cannot say which page it checks. Gap nodes cannot list the cases that should cover them | New `app_pages`: `dotId`, `host`, `route`, `stateKey`, `title`, `firstSeenAt`, `lastSeenAt`, `lastRunId`, filled when a run ends. `test_cases.pages` json of `app_pages.id` | Low |
322
+ | Test data | `QaTestToRun.data` free text; `passEnv` for secrets | Cases cannot share a "guest with a coupon" set. Data-driven runs (Xray iterations, TestRail parameters) cannot map | Stage 1: `test_cases.preconditions`, `test_cases.data` (text). Later: `data_sets` (`dotId`, `name`, `rows` json, `secretRefs` as env names only) | Low |
323
+ | Flakiness history | `memory` free text; triage over recent runs | No flake rate, no quarantine, no trend | Read model over `test_results` (Test result rows). New `test_flags`: `dotId`, `testKey`, `config`, `state` (`quarantined`, `known_flaky`), `reason`, `actor`, `at` | Low after Test result rows |
324
+ | Coverage history | Computed on read in traceability and the map | No coverage at a past build or release. Reports change after the fact | Read model first. Later `coverage_snapshots`: `dotId`, `scope` (`release`, `area`, `requirement`), `scopeId`, `sha`, `counts` json, `at`, written by the Release guard | Low |
325
+ | Audit trail | `device_audit`, `connect_audit`, `source` fields; no decider on approvals | No answer to "who approved this defect" or "who changed this case". Sync conflicts cannot be explained | New `audit`: `at`, `actor` (`device:<id>`, `token`, `dot:<id>/<stage>`, `github:<login>`, `system`), `action`, `entity`, `entityId`, `before` hash, `after` json, `runId`. `approvals.decidedBy`, `approvals.originalBody` | Low |
326
+ | Run stage | Missing | Results and timeline rows cannot say which specialist did the work | `RunRecord.stage` (STAGES.md task 1), copied into `case_results.stage` | Low |
327
+ | Sync references | Refs are text in `links`; filed URL in `approvals.action.meta` | Sync cannot tell a local case from an imported one, find the remote id, or detect a conflict | New `external_refs` (section 4.6) | Low |
328
+ | Referential checks | None | Deleted dots leave orphan cases, results, and links | Keep no foreign keys (the migrator cannot add them). Add a boot check that counts orphans and a delete path per dot | Low |
329
+
330
+ ---
331
+
332
+ ## 4. External sync
333
+
334
+ Direction words: Pull means the tool is the source and localdost reads. Push means localdost is the source and writes. Both means each side owns some fields. Field names come from public docs as known on 2026-10-09; rows marked "to confirm" need a check against the API before the sync task starts.
335
+
336
+ ### 4.1 Ownership rules
337
+
338
+ | Rule | Why |
339
+ |---|---|
340
+ | One owner per field. The other side treats it as read-only | No merge of free text, no edit wars |
341
+ | The tracker owns requirements, criteria text, releases, defect state | People work there |
342
+ | localdost owns automated results, evidence, flakiness, and coverage it computes | It runs the tests |
343
+ | Cases: the side that created the case owns its title and steps. The other side gets a copy | A designer case pushes; an imported TestRail case pulls |
344
+ | Every push carries the localdost marker (`<!-- localdost:bot sig=... -->`) or an external id field, as the loop guard does today | No echo loops |
345
+ | Every push passes the rules gate as `mcp_tool` or a new `test_sync` action kind, default `ask` | Same as other outward actions |
346
+
347
+ ### 4.2 Jira and Xray
348
+
349
+ Xray adds issue types to Jira: Test, Pre-Condition, Test Set, Test Plan, Test Execution. A Test Execution is a test run: it lists Tests, and each Test inside it is a Test Run with its own status and step results. Results import through `POST /api/v2/import/execution` (Xray JSON) or JUnit import. Xray Cloud also has a GraphQL API (to confirm per edition: Cloud or Data Center). Xray Cloud organizes Tests in a folder tree in the Test Repository of each project.
350
+
351
+ | localdost entity | Jira or Xray entity | Id kept | Fields and owner | Direction |
352
+ |---|---|---|---|---|
353
+ | Requirement | Jira issue (Story, Epic, Bug) | `id` (numeric), `key` | summary, description, status, priority, labels, components: Jira | Pull |
354
+ | Acceptance criterion | Description section or a custom field (`JIRA_AC_FIELD`) | requirement key + ordinal | text: Jira | Pull |
355
+ | Release | Version (`fixVersions`), sprint field | version `id` | name, releaseDate, released: Jira | Pull |
356
+ | Folder | Test Repository folder | folder path and id | name, parent: owner of the case tree | Both |
357
+ | Test case | Xray Test issue, type Manual or Generic | issue `id`, `key` | summary, steps (action, data, result): case owner. Test type Generic carries the `testKey` as its definition | Both |
358
+ | Case version | Test version (Xray Cloud test versioning, to confirm per edition) | version id | case owner | Both |
359
+ | Case covers requirement | Issue link "tests" (Xray coverage) | link `id` | localdost for its cases | Push |
360
+ | Precondition | Pre-Condition issue | `key` | text: case owner | Push |
361
+ | Suite | Test Set issue | `key` | members: localdost for its suites. A query suite pushes its members at the time of the push | Push |
362
+ | Plan | Test Plan issue | `key` | tests, fixVersion: localdost or Jira, per plan. Each test run of the plan is a Test Execution linked to the Test Plan | Both |
363
+ | Test run | Test Execution issue | `id`, `key` | summary, `testEnvironments` (environment and configuration), revision (build sha), fixVersion, assignee: localdost | Push |
364
+ | Run item | Test Run (one Test inside one Test Execution) | Test Run id | status, assignee: localdost | Push |
365
+ | Result | The Test Run's status and comment; earlier attempts as the Test Run history | Test Run id | status (`PASSED`, `FAILED`, `TODO`, `EXECUTING`, `ABORTED`), comment, start, finish, executedBy: localdost | Push |
366
+ | Step result | Test Run step | step id, mapped by position in the pinned version | status, actualResult, evidences, defects: localdost | Push |
367
+ | Evidence | Attachment on the Test Run or step | attachment id | localdost | Push |
368
+ | Defect | Jira issue type Bug, linked to the Test Run or step | `id`, `key` | summary, steps, environment: localdost at create; status, resolution: Jira | Push, then Pull |
369
+ | Environment and configuration | `testEnvironments` values (strings), one Test Execution per configuration | name | localdost | Push |
370
+ | Dot run | None. A link in the Test Run comment and a remote link on the ticket point at it | `globalId` = dot run id | localdost | Push |
371
+
372
+ Item state map: `passed` to PASSED, `failed` to FAILED, `blocked` to ABORTED or a custom BLOCKED status (to confirm per project), `untested` and `skipped` to TODO, `retest` to TODO with the earlier attempt kept in history.
373
+
374
+ ### 4.3 Linear
375
+
376
+ Linear has no test management objects. localdost keeps folders, cases, suites, plans, test runs, and results, and Linear holds requirements, defects, and links back.
377
+
378
+ | localdost entity | Linear entity | Id kept | Fields and owner | Direction |
379
+ |---|---|---|---|---|
380
+ | Requirement | Issue | `id` (UUID), `identifier` (`ENG-12`) | title, description, state, priority (0 to 4), labels, parent: Linear | Pull |
381
+ | Acceptance criterion | Description section or checklist | identifier + ordinal | Linear | Pull |
382
+ | Release | Cycle, project milestone, project | `id` | name, dates: Linear | Pull |
383
+ | Requirement links | Issue relations (`blocks`, `related`, `duplicate`), parent and sub-issues | relation `id` | Linear | Pull |
384
+ | Defect | Issue with label `localdost` (exists today) | `id`, `identifier` | title, body: localdost at create; state: Linear | Push, then Pull |
385
+ | Test status on a requirement | Attachment (URL link to the test run or the case list) and one comment | attachment `id` | localdost | Push |
386
+ | Folder, case, suite, plan, test run, run item, result | None | | localdost only | None |
387
+
388
+ ### 4.4 TestRail
389
+
390
+ TestRail API v2. Ids: project `P`, suite `S`, section, case `C`, plan, run `R`, test `T` (a case inside a run), result, milestone `M`, configuration. A TestRail run is a test run, and a TestRail test is a run item. A TestRail suite is a case repository (in multi-suite mode), not a localdost suite.
391
+
392
+ | localdost entity | TestRail entity | Id kept | Fields and owner | Direction |
393
+ |---|---|---|---|---|
394
+ | Dot or product | Project, plus the suite that holds its cases (single or multi-suite mode) | `project_id`, `suite_id` | TestRail | Pull |
395
+ | Folder | Section (nested through `parent_id`) | `section_id` | name, parent: owner of the case tree | Both |
396
+ | Test case | Case | `case_id` | title, `custom_preconds`, `custom_steps_separated` (content, expected), `priority_id`, `type_id`, `refs` (requirement keys as text), `estimate`, `section_id`: case owner | Both |
397
+ | Case version | Case history (`get_history_for_case`) | change id | TestRail keeps it; localdost reads it | Pull |
398
+ | Requirement link | `refs` field on the case | text | case owner | Both |
399
+ | Release | Milestone (with parent milestones) | `milestone_id` | TestRail or Jira, per team | Pull |
400
+ | Suite | No direct match. A static suite becomes the `case_ids` of the run it starts; a query suite is resolved first | | localdost | Push as case lists |
401
+ | Plan | Plan with entries; each entry has one run per configuration | `plan_id`, `entry_id` | localdost for plans it makes | Push |
402
+ | Configuration | Configuration group and config (browser, OS) | `config_id` | TestRail admin | Pull |
403
+ | Test run | Run (`add_run` with `case_ids`, or a run inside a plan entry with `config_ids`) | `run_id` | name, milestone, description (build sha, environment), `assignedto_id`: localdost | Push |
404
+ | Run item | Test | `test_id` | status, `assignedto_id`: localdost | Push |
405
+ | Result | Result (`add_results_for_cases`), one per attempt; TestRail shows the newest | `result_id` | `status_id` (1 Passed, 2 Blocked, 3 Untested, 4 Retest, 5 Failed), `comment`, `version` (build sha), `elapsed`, `defects` (keys as text): localdost | Push |
406
+ | Step result | `custom_step_results` (content, expected, actual, `status_id`) | position | localdost | Push |
407
+ | Evidence | Attachment on the result (`add_attachment_to_result`) | `attachment_id` | localdost | Push |
408
+ | Defect | `defects` text on the result; the defect itself in Jira or another tracker | key | Tracker | Push the key |
409
+ | Dot run | None. A link in the result comment points at it | | localdost | Push |
410
+
411
+ Item state map: `passed` 1, `blocked` 2, `untested` 3, `retest` 4, `failed` 5, `skipped` to a custom status or Untested with a comment (to confirm per instance). TestRail steps have no step ids. localdost maps by position in the pinned case version, so a reorder after a test run started does not move its step results.
412
+
413
+ ### 4.5 Katalon True Platform
414
+
415
+ True Platform has releases and sprints, requirements synced from Jira or Azure DevOps, test cases in folders with versions, test suites, manual and automated test runs with an executor and a configuration (for example "Windows 11 + Chrome 143"), step-level evidence, and defects linked to Jira (docs read 2026-10-09: Manual Test Run, Manage Releases and Requirements). It accepts JUnit and Playwright reports through the Katalon report uploader, and it has an MCP server. API endpoint and field names: to confirm in the True Platform API docs.
416
+
417
+ | localdost entity | True Platform entity | Id kept | Fields and owner | Direction |
418
+ |---|---|---|---|---|
419
+ | Requirement | Requirement (synced from Jira or ADO) | requirement id + the Jira key | True Platform mirrors Jira; localdost reads the Jira key | Pull (or read through Jira) |
420
+ | Release and plan | Release or sprint, with its build | release id, sprint id | True Platform | Pull |
421
+ | Folder | Test case folder | folder id | owner of the case tree | Both |
422
+ | Test case and version | Test case (manual or automated) and its version | test case id, version | name, steps: case owner | Both |
423
+ | Suite | Test suite | suite id | owner of the suite | Both |
424
+ | Test run | Test run (manual or automated), in a release or sprint | test run id | name, release, sprint, configuration, executor: localdost for its test runs | Push |
425
+ | Run item and result | Test result inside the test run, with step results, screenshots, video | result id | localdost | Push (report upload for automated test runs) |
426
+ | Configuration | Configuration (OS, browser) | config id | True Platform | Pull |
427
+ | Defect | Defect linked to Jira | Jira key | Jira | Pull state |
428
+ | Dot run | None. The uploaded report names it | | localdost | Push |
429
+
430
+ Two paths, smallest first: (1) upload the JUnit or Playwright report of each automated test run with the uploader, which needs no case mapping; (2) map folders, cases, and test runs one to one through the API or the MCP server for manual test runs and step results.
431
+
432
+ ### 4.6 The external ref shape
433
+
434
+ Every syncable entity (requirement, criterion, release, folder, case, case version, suite, plan, test run, run item, result, defect, environment, configuration) gets zero or more rows in one table. No sync field goes on the entity rows, so a new tool adds no columns.
435
+
436
+ ```ts
437
+ // src/types.ts (add only). Table external_refs, index on (entity, entityId) and (system, externalId).
438
+ export interface ExternalRef {
439
+ id: string;
440
+ dotId: string;
441
+ /** Local table and row: 'test_cases' + case id. */
442
+ entity: string;
443
+ entityId: string;
444
+ /** 'jira' | 'xray' | 'linear' | 'testrail' | 'katalon' | 'github'. */
445
+ system: string;
446
+ /** Site or tenant: 'acme.atlassian.net', TestRail host, True Platform project id. */
447
+ instance: string;
448
+ /** Remote type: 'issue', 'test', 'test_execution', 'test_run', 'section', 'case', 'run', 'test'. */
449
+ externalType: string;
450
+ /** Immutable remote id: Jira numeric id, Linear UUID, TestRail case id. */
451
+ externalId: string;
452
+ /** Human key, can change on a move: SHOP-12, C123. */
453
+ externalKey?: string;
454
+ url?: string;
455
+ /** Who owns the content fields of this pair. */
456
+ owner: 'local' | 'remote';
457
+ direction: 'pull' | 'push' | 'both';
458
+ /** Remote version or updated time at the last sync, for conflict checks. */
459
+ remoteVersion?: string;
460
+ /** Hash of the local fields at the last push. */
461
+ localHash?: string;
462
+ syncedAt?: string;
463
+ state: 'linked' | 'pending' | 'conflict' | 'error' | 'unlinked';
464
+ error?: string;
465
+ }
466
+ ```
467
+
468
+ Rules: `externalId` is the join key, never `externalKey`. A conflict is a change on the non-owner side since `syncedAt`; it stays in state `conflict` and shows in the Inbox. A delete on either side sets `unlinked` and deletes nothing.
469
+
470
+ ---
471
+
472
+ ## 5. Phased plan
473
+
474
+ Each row is one PR that leaves the product working. All changes are add only: new tables through `SCHEMA` and new optional fields, so `migrate()` handles them and an older build ignores them. Sizes: S is one table or a few fields, with no backfill. M is several fields plus a backfill, or a new flow. L is an external sync with mapping both ways.
475
+
476
+ ### Phase 1: stage 1, the dot manages tests on its own
477
+
478
+ | Name | Change | Gaps | Size | Depends on | Unblocks |
479
+ |---|---|---|---|---|---|
480
+ | Run context fields | `RunRecord.stage` (STAGES.md task 1); `runs.environment` and `runs.build` snapshots | Run stage, Environments, Builds and deploys (fields) | S | | Every result knows stage, place, and build |
481
+ | Case versions and folders | `test_cases.revision` and `case_versions` written on every create and edit; `folders` table and `test_cases.folderId`, with create, rename, move, and delete | Case versions, Folders | M | | A test run can pin what it ran; a large case set has a tree |
482
+ | Case details | `origin`, `preconditions`, `covers`, `areaId`, `tags`, `specTitle`, step `data`; 409 on a stale revision | Case areas, Test data (text) | M | Case versions and folders | Designer writes and person edits stop overwriting each other |
483
+ | Test runs and results | `test_runs` and `run_items` tables; `case_results` gains `runItemId`, `testRunId`, `attempt`, `stage`, `engine`, `durationMs`, `sha`, `environment`, `config`, `executedBy`, `dotRunId`, `steps`, `defects`; manual result and retest API; a dot run that reports case results creates its automated test run per configuration; backfill of one automated test run per dot run from existing case results | Test runs, Run items, Result context, Step results, Configurations | M | Case versions and folders | A person works a manual test run step by step; automated passes show as read-only test runs with their dot run evidence |
484
+ | Test result table | `test_results` table written at report save, with `testKey` and `project` as fields; backfill job from `runs.report` (last 90 days) | Test identity, Test result rows, Configurations | M | | Flakiness and history queries |
485
+ | Requirement tables | `requirements` and `criteria` tables, filled by ticket review, pollers, and `issue_state`; backfill from the newest `ticket_review` run per key | Requirement store, Acceptance criteria | M | | Designer input, coverage per criterion |
486
+ | Defect table | `defects` table and `links.kind = 'defect'`; the defect flows write a row; severity from the review; `resultId` and `stepIndex` set when a case step failed; `case_results.defects` refs become rows; backfill from executed approvals | Defect records | M | Test runs and results | Defect with severity, linked to the failing step |
487
+ | Suite and plan tables | `suites` (static list or saved query) and `plans` tables with their API; a test run starts from a suite, a selection, or a plan (one test run per plan configuration) | Test suites, Test plans | M | Test runs and results | Named regression sets and planned passes |
488
+ | Run a suite automatically | "Run with the dot": a `rerun` with the specs of an automated suite's cases, which fills an automated test run with the suite's `suiteId` | Test suites | S | Suite and plan tables | Regression sets on demand |
489
+ | Environment table | `environments` table; preview URLs stored in `deploys` instead of memory | Environments, Builds and deploys | S | Run context fields | Results per environment survive a restart |
490
+ | Audit log | `audit` table; `approvals.decidedBy` and `approvals.originalBody`; actor on case writes | Audit trail | S | | Who did what |
491
+ | App page records | `app_pages` written at run end from `observations.jsonl`; `test_cases.pages` | Page identity | S | | Cases on the map |
492
+ | Read models | Read models: flake rate and `test_flags` (quarantine), coverage per criterion, requirement, area, and page | Flakiness history, Coverage history | M | Test result table, Requirement tables, App page records | Release guard input |
493
+
494
+ Order: Case versions and folders, Test runs and results, Suite and plan tables first: they fix the model the sync maps onto. Then Run context fields, Audit log, Case details, Test result table, Requirement tables. Then Defect table, Run a suite automatically, Environment table, App page records. Read models last. After Defect table the dot can design cases, file them in folders, group them in suites and plans, work manual test runs, record automated test runs per configuration with step results and evidence, and file a defect that points to the failing step, with no outside tool.
495
+
496
+ ### Phase 2: sync
497
+
498
+ | Name | Change | Size | Depends on |
499
+ |---|---|---|---|
500
+ | External ref table | `external_refs` table; backfill from `issue_state` ids, `requirements.externalId`, and `defects.externalId` | S | Requirement tables, Defect table |
501
+ | Release table | `releases` table: Jira `fixVersions` and sprints, Linear cycles and project milestones, GitHub milestones; `requirements.releaseIds` | M | Requirement tables |
502
+ | Sync action kind | `test_sync` action kind (default `ask`) through the rules gate; conflict state in the Inbox | S | External ref table |
503
+ | Katalon report upload | Katalon True Platform, path 1: upload the JUnit or Playwright report of each automated test run | S | Sync action kind |
504
+ | Xray sync | Xray: push folders and Test issues for designer cases, Test Sets for suites, Test Plans for plans, one Test Execution per test run and its Test Runs per run item with step results and evidence; pull coverage links | L | External ref table, Sync action kind, Test runs and results |
505
+ | TestRail sync | TestRail: map sections and cases both ways, push plans with one run per configuration, tests per run item, and one result per attempt with step results and attachments | L | External ref table, Sync action kind, Test runs and results |
506
+ | Linear status link | Linear: attachment link and one status comment per requirement | S | External ref table, Sync action kind |
507
+ | Katalon case mapping | Katalon True Platform, path 2: folder, case, test suite, and test run mapping through the API or the MCP server, with manual results and step results | M | External ref table, Sync action kind, Katalon report upload (API to confirm) |
508
+ | Coverage snapshots | `coverage_snapshots` per release, written by the Release guard | S | Release table, Read models |
509
+
510
+ ### Risks for the whole plan
511
+
512
+ | Risk | Mitigation |
513
+ |---|---|
514
+ | Backfills read every run row and parse JSON | Run them as a queued job in batches of 200, once, with a marker in `poll_cursors` |
515
+ | `test_results` grows with every run | Keep 180 days or the cap per dot, like artifacts |
516
+ | New union values (item states such as `retest` and `untested`) break exhaustive client maps | Change the server and client maps in the same PR, as STAGES.md asks for `JobKind` |
517
+ | Two writers for one case (designer, person, sync) | Case versions on every write, a revision check (Case details), owner field on `external_refs` |
518
+ | Evidence names point to files the artifact cap deleted | Mark the evidence `pruned` when the cap deletes it, and push evidence to the external tool before the cap runs |