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.
- package/.railway/railway.ts +83 -0
- package/.railway/tsconfig.json +13 -0
- package/AGENTS.md +102 -0
- package/Dockerfile +108 -0
- package/LICENSE +21 -0
- package/README.md +275 -2
- package/bin/localdost.js +29 -0
- package/bin/tinybeeai.js +28 -0
- package/compose.yml +63 -0
- package/demo/payloads/ci_failure.json +46 -0
- package/demo/payloads/outage.json +18 -0
- package/demo/payloads/pr_comment_edited.json +50 -0
- package/demo/payloads/pr_merged.json +80 -0
- package/demo/payloads/pr_opened.json +69 -0
- package/demo/payloads/pr_synchronize.json +69 -0
- package/demo/payloads/ticket_created.json +138 -0
- package/demo/sample-app/playwright.config.ts +20 -0
- package/demo/sample-app/server.ts +163 -0
- package/demo/sample-app/tests/checkout.spec.ts +13 -0
- package/demo/sample-app/tests/smoke.spec.ts +8 -0
- package/dist/agent/approval-retries.js +59 -0
- package/dist/agent/approval-retries.js.map +1 -0
- package/dist/agent/approvals.js +390 -0
- package/dist/agent/approvals.js.map +1 -0
- package/dist/agent/chat-bridge.js +154 -0
- package/dist/agent/chat-bridge.js.map +1 -0
- package/dist/agent/chat-lead.js +475 -0
- package/dist/agent/chat-lead.js.map +1 -0
- package/dist/agent/chat-loop.js +106 -0
- package/dist/agent/chat-loop.js.map +1 -0
- package/dist/agent/chat-mcp.js +49 -0
- package/dist/agent/chat-mcp.js.map +1 -0
- package/dist/agent/chat-tool-blocks.js +453 -0
- package/dist/agent/chat-tool-blocks.js.map +1 -0
- package/dist/agent/chat-view.js +94 -0
- package/dist/agent/chat-view.js.map +1 -0
- package/dist/agent/chat-views.js +781 -0
- package/dist/agent/chat-views.js.map +1 -0
- package/dist/agent/chat.js +1703 -0
- package/dist/agent/chat.js.map +1 -0
- package/dist/agent/destinations.js +150 -0
- package/dist/agent/destinations.js.map +1 -0
- package/dist/agent/llm-cli.js +451 -0
- package/dist/agent/llm-cli.js.map +1 -0
- package/dist/agent/llm-codex.js +493 -0
- package/dist/agent/llm-codex.js.map +1 -0
- package/dist/agent/llm-openai.js +211 -0
- package/dist/agent/llm-openai.js.map +1 -0
- package/dist/agent/llm.js +1464 -0
- package/dist/agent/llm.js.map +1 -0
- package/dist/agent/memory.js +33 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/mock-views.js +93 -0
- package/dist/agent/mock-views.js.map +1 -0
- package/dist/agent/model-availability.js +207 -0
- package/dist/agent/model-availability.js.map +1 -0
- package/dist/agent/model-errors.js +188 -0
- package/dist/agent/model-errors.js.map +1 -0
- package/dist/agent/model-guard.js +311 -0
- package/dist/agent/model-guard.js.map +1 -0
- package/dist/agent/prompts.js +374 -0
- package/dist/agent/prompts.js.map +1 -0
- package/dist/agent/qa-lenses/qa-auth.md +32 -0
- package/dist/agent/qa-lenses/qa-check-then-act.md +33 -0
- package/dist/agent/qa-lenses/qa-control-has-no-effect.md +32 -0
- package/dist/agent/qa-lenses/qa-dates.md +31 -0
- package/dist/agent/qa-lenses/qa-double-submit.md +34 -0
- package/dist/agent/qa-lenses/qa-feature-flag.md +29 -0
- package/dist/agent/qa-lenses/qa-migration.md +35 -0
- package/dist/agent/qa-lenses/qa-money.md +38 -0
- package/dist/agent/qa-lenses/qa-response-shape-break.md +33 -0
- package/dist/agent/qa-lenses/qa-validation.md +29 -0
- package/dist/agent/qa-prompts.js +660 -0
- package/dist/agent/qa-prompts.js.map +1 -0
- package/dist/agent/reasoning.js +55 -0
- package/dist/agent/reasoning.js.map +1 -0
- package/dist/agent/redact.js +48 -0
- package/dist/agent/redact.js.map +1 -0
- package/dist/agent/rules.js +927 -0
- package/dist/agent/rules.js.map +1 -0
- package/dist/agent/runs.js +440 -0
- package/dist/agent/runs.js.map +1 -0
- package/dist/agent/send-retry.js +62 -0
- package/dist/agent/send-retry.js.map +1 -0
- package/dist/agent/team-notes.js +288 -0
- package/dist/agent/team-notes.js.map +1 -0
- package/dist/agent/token-meter.js +31 -0
- package/dist/agent/token-meter.js.map +1 -0
- package/dist/agent/triage.js +506 -0
- package/dist/agent/triage.js.map +1 -0
- package/dist/api.js +1047 -0
- package/dist/api.js.map +1 -0
- package/dist/approval-targets.js +107 -0
- package/dist/approval-targets.js.map +1 -0
- package/dist/bee/cloudflared.js +108 -0
- package/dist/bee/cloudflared.js.map +1 -0
- package/dist/bee/health.js +99 -0
- package/dist/bee/health.js.map +1 -0
- package/dist/bee/hive-client.js +75 -0
- package/dist/bee/hive-client.js.map +1 -0
- package/dist/bee/identity.js +39 -0
- package/dist/bee/identity.js.map +1 -0
- package/dist/bee/models.js +510 -0
- package/dist/bee/models.js.map +1 -0
- package/dist/bee/pairing.js +351 -0
- package/dist/bee/pairing.js.map +1 -0
- package/dist/bee/relay-client.js +50 -0
- package/dist/bee/relay-client.js.map +1 -0
- package/dist/bee/routes.js +214 -0
- package/dist/bee/routes.js.map +1 -0
- package/dist/bee/setup-page.js +223 -0
- package/dist/bee/setup-page.js.map +1 -0
- package/dist/bee/state.js +41 -0
- package/dist/bee/state.js.map +1 -0
- package/dist/bee/status.js +117 -0
- package/dist/bee/status.js.map +1 -0
- package/dist/bee/tunnel-manager.js +245 -0
- package/dist/bee/tunnel-manager.js.map +1 -0
- package/dist/bee/updater.js +268 -0
- package/dist/bee/updater.js.map +1 -0
- package/dist/boot.js +41 -0
- package/dist/boot.js.map +1 -0
- package/dist/call/index.js +145 -0
- package/dist/call/index.js.map +1 -0
- package/dist/case-folders.js +294 -0
- package/dist/case-folders.js.map +1 -0
- package/dist/cases.js +554 -0
- package/dist/cases.js.map +1 -0
- package/dist/chat-blocks.js +709 -0
- package/dist/chat-blocks.js.map +1 -0
- package/dist/chat-parse-util.js +38 -0
- package/dist/chat-parse-util.js.map +1 -0
- package/dist/chat-results.js +96 -0
- package/dist/chat-results.js.map +1 -0
- package/dist/chat-stats.js +193 -0
- package/dist/chat-stats.js.map +1 -0
- package/dist/chat-view-specs.js +186 -0
- package/dist/chat-view-specs.js.map +1 -0
- package/dist/cli/doctor-ops.js +361 -0
- package/dist/cli/doctor-ops.js.map +1 -0
- package/dist/cli/doctor.js +289 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/dogfood.js +70 -0
- package/dist/cli/dogfood.js.map +1 -0
- package/dist/cli/env-file.js +34 -0
- package/dist/cli/env-file.js.map +1 -0
- package/dist/cli/eval-chat-cases.js +359 -0
- package/dist/cli/eval-chat-cases.js.map +1 -0
- package/dist/cli/eval-chat-results.js +85 -0
- package/dist/cli/eval-chat-results.js.map +1 -0
- package/dist/cli/eval-chat.js +508 -0
- package/dist/cli/eval-chat.js.map +1 -0
- package/dist/cli/eval-designer.js +67 -0
- package/dist/cli/eval-designer.js.map +1 -0
- package/dist/cli/eval-qa-review.js +284 -0
- package/dist/cli/eval-qa-review.js.map +1 -0
- package/dist/cli/golden-export.js +35 -0
- package/dist/cli/golden-export.js.map +1 -0
- package/dist/cli/index.js +90 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.js +746 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/scan-repo.js +199 -0
- package/dist/cli/scan-repo.js.map +1 -0
- package/dist/cli/seed.js +108 -0
- package/dist/cli/seed.js.map +1 -0
- package/dist/cli/tinybee.js +247 -0
- package/dist/cli/tinybee.js.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/connect/aivision-local.js +833 -0
- package/dist/connect/aivision-local.js.map +1 -0
- package/dist/connect/aivision-token.js +84 -0
- package/dist/connect/aivision-token.js.map +1 -0
- package/dist/connect/crypto.js +65 -0
- package/dist/connect/crypto.js.map +1 -0
- package/dist/connect/deps.js +110 -0
- package/dist/connect/deps.js.map +1 -0
- package/dist/connect/engines.js +144 -0
- package/dist/connect/engines.js.map +1 -0
- package/dist/connect/github-access.js +74 -0
- package/dist/connect/github-access.js.map +1 -0
- package/dist/connect/github-app.js +129 -0
- package/dist/connect/github-app.js.map +1 -0
- package/dist/connect/index.js +9 -0
- package/dist/connect/index.js.map +1 -0
- package/dist/connect/model-choices.js +201 -0
- package/dist/connect/model-choices.js.map +1 -0
- package/dist/connect/providers.js +900 -0
- package/dist/connect/providers.js.map +1 -0
- package/dist/connect/readiness.js +232 -0
- package/dist/connect/readiness.js.map +1 -0
- package/dist/connect/redact.js +16 -0
- package/dist/connect/redact.js.map +1 -0
- package/dist/connect/registry.js +406 -0
- package/dist/connect/registry.js.map +1 -0
- package/dist/connect/store.js +283 -0
- package/dist/connect/store.js.map +1 -0
- package/dist/connect/tunnel.js +134 -0
- package/dist/connect/tunnel.js.map +1 -0
- package/dist/connect/types.js +8 -0
- package/dist/connect/types.js.map +1 -0
- package/dist/connections/index.js +5 -0
- package/dist/connections/index.js.map +1 -0
- package/dist/connections/manager.js +223 -0
- package/dist/connections/manager.js.map +1 -0
- package/dist/connections/presets.js +264 -0
- package/dist/connections/presets.js.map +1 -0
- package/dist/connections/store.js +132 -0
- package/dist/connections/store.js.map +1 -0
- package/dist/connections/tools.js +206 -0
- package/dist/connections/tools.js.map +1 -0
- package/dist/db-schema.js +355 -0
- package/dist/db-schema.js.map +1 -0
- package/dist/db.js +379 -0
- package/dist/db.js.map +1 -0
- package/dist/delivery.js +49 -0
- package/dist/delivery.js.map +1 -0
- package/dist/deploy-wait.js +701 -0
- package/dist/deploy-wait.js.map +1 -0
- package/dist/disk.js +243 -0
- package/dist/disk.js.map +1 -0
- package/dist/dot-health.js +966 -0
- package/dist/dot-health.js.map +1 -0
- package/dist/dot-remove.js +246 -0
- package/dist/dot-remove.js.map +1 -0
- package/dist/events.js +38 -0
- package/dist/events.js.map +1 -0
- package/dist/evidence-pack.js +423 -0
- package/dist/evidence-pack.js.map +1 -0
- package/dist/flows/answers.js +289 -0
- package/dist/flows/answers.js.map +1 -0
- package/dist/flows/change.js +811 -0
- package/dist/flows/change.js.map +1 -0
- package/dist/flows/checkStatus.js +524 -0
- package/dist/flows/checkStatus.js.map +1 -0
- package/dist/flows/ci.js +236 -0
- package/dist/flows/ci.js.map +1 -0
- package/dist/flows/ciFailure.js +76 -0
- package/dist/flows/ciFailure.js.map +1 -0
- package/dist/flows/common.js +522 -0
- package/dist/flows/common.js.map +1 -0
- package/dist/flows/default-branch.js +29 -0
- package/dist/flows/default-branch.js.map +1 -0
- package/dist/flows/defectDraft.js +447 -0
- package/dist/flows/defectDraft.js.map +1 -0
- package/dist/flows/defects.js +623 -0
- package/dist/flows/defects.js.map +1 -0
- package/dist/flows/digest.js +295 -0
- package/dist/flows/digest.js.map +1 -0
- package/dist/flows/impact.js +82 -0
- package/dist/flows/impact.js.map +1 -0
- package/dist/flows/index.js +23 -0
- package/dist/flows/index.js.map +1 -0
- package/dist/flows/intent-sources.js +72 -0
- package/dist/flows/intent-sources.js.map +1 -0
- package/dist/flows/mergeCases.js +169 -0
- package/dist/flows/mergeCases.js.map +1 -0
- package/dist/flows/nightlyRun.js +82 -0
- package/dist/flows/nightlyRun.js.map +1 -0
- package/dist/flows/outage.js +64 -0
- package/dist/flows/outage.js.map +1 -0
- package/dist/flows/postMerge.js +5 -0
- package/dist/flows/postMerge.js.map +1 -0
- package/dist/flows/prCheck.js +5 -0
- package/dist/flows/prCheck.js.map +1 -0
- package/dist/flows/prTarget.js +66 -0
- package/dist/flows/prTarget.js.map +1 -0
- package/dist/flows/qa.js +363 -0
- package/dist/flows/qa.js.map +1 -0
- package/dist/flows/questions.js +160 -0
- package/dist/flows/questions.js.map +1 -0
- package/dist/flows/recovery.js +64 -0
- package/dist/flows/recovery.js.map +1 -0
- package/dist/flows/rerun.js +50 -0
- package/dist/flows/rerun.js.map +1 -0
- package/dist/flows/testDesign.js +294 -0
- package/dist/flows/testDesign.js.map +1 -0
- package/dist/flows/testDesignJob.js +46 -0
- package/dist/flows/testDesignJob.js.map +1 -0
- package/dist/flows/testRepo.js +228 -0
- package/dist/flows/testRepo.js.map +1 -0
- package/dist/flows/testSavings.js +381 -0
- package/dist/flows/testSavings.js.map +1 -0
- package/dist/flows/testStatus.js +343 -0
- package/dist/flows/testStatus.js.map +1 -0
- package/dist/flows/ticketContext.js +425 -0
- package/dist/flows/ticketContext.js.map +1 -0
- package/dist/flows/ticketReview.js +249 -0
- package/dist/flows/ticketReview.js.map +1 -0
- package/dist/flows/ticks.js +73 -0
- package/dist/flows/ticks.js.map +1 -0
- package/dist/hive/admin.js +122 -0
- package/dist/hive/admin.js.map +1 -0
- package/dist/hive/auth.js +130 -0
- package/dist/hive/auth.js.map +1 -0
- package/dist/hive/billing.js +278 -0
- package/dist/hive/billing.js.map +1 -0
- package/dist/hive/config.js +63 -0
- package/dist/hive/config.js.map +1 -0
- package/dist/hive/db.js +186 -0
- package/dist/hive/db.js.map +1 -0
- package/dist/hive/embed.js +76 -0
- package/dist/hive/embed.js.map +1 -0
- package/dist/hive/errors.js +17 -0
- package/dist/hive/errors.js.map +1 -0
- package/dist/hive/google.js +75 -0
- package/dist/hive/google.js.map +1 -0
- package/dist/hive/index.js +25 -0
- package/dist/hive/index.js.map +1 -0
- package/dist/hive/jwt.js +57 -0
- package/dist/hive/jwt.js.map +1 -0
- package/dist/hive/keys.js +61 -0
- package/dist/hive/keys.js.map +1 -0
- package/dist/hive/mail.js +27 -0
- package/dist/hive/mail.js.map +1 -0
- package/dist/hive/native-push.js +255 -0
- package/dist/hive/native-push.js.map +1 -0
- package/dist/hive/pairing.js +342 -0
- package/dist/hive/pairing.js.map +1 -0
- package/dist/hive/presence.js +121 -0
- package/dist/hive/presence.js.map +1 -0
- package/dist/hive/push.js +185 -0
- package/dist/hive/push.js.map +1 -0
- package/dist/hive/relay.js +205 -0
- package/dist/hive/relay.js.map +1 -0
- package/dist/hive/routes.js +228 -0
- package/dist/hive/routes.js.map +1 -0
- package/dist/hive/server.js +12 -0
- package/dist/hive/server.js.map +1 -0
- package/dist/hive/session.js +28 -0
- package/dist/hive/session.js.map +1 -0
- package/dist/hive/tenants.js +287 -0
- package/dist/hive/tenants.js.map +1 -0
- package/dist/hive/tunnel/cloudflare.js +160 -0
- package/dist/hive/tunnel/cloudflare.js.map +1 -0
- package/dist/hive/tunnel/mock.js +52 -0
- package/dist/hive/tunnel/mock.js.map +1 -0
- package/dist/hive/tunnel/provider.js +19 -0
- package/dist/hive/tunnel/provider.js.map +1 -0
- package/dist/hive/updates.js +61 -0
- package/dist/hive/updates.js.map +1 -0
- package/dist/http-error.js +11 -0
- package/dist/http-error.js.map +1 -0
- package/dist/impact/classify.js +226 -0
- package/dist/impact/classify.js.map +1 -0
- package/dist/impact/find.js +259 -0
- package/dist/impact/find.js.map +1 -0
- package/dist/impact/pr.js +54 -0
- package/dist/impact/pr.js.map +1 -0
- package/dist/impact/store.js +365 -0
- package/dist/impact/store.js.map +1 -0
- package/dist/impact/text.js +158 -0
- package/dist/impact/text.js.map +1 -0
- package/dist/index.js +288 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/adf.js +397 -0
- package/dist/integrations/adf.js.map +1 -0
- package/dist/integrations/bot-marker.js +103 -0
- package/dist/integrations/bot-marker.js.map +1 -0
- package/dist/integrations/github-issues.js +705 -0
- package/dist/integrations/github-issues.js.map +1 -0
- package/dist/integrations/github.js +1284 -0
- package/dist/integrations/github.js.map +1 -0
- package/dist/integrations/issue-create.js +60 -0
- package/dist/integrations/issue-create.js.map +1 -0
- package/dist/integrations/jira.js +279 -0
- package/dist/integrations/jira.js.map +1 -0
- package/dist/integrations/linear.js +273 -0
- package/dist/integrations/linear.js.map +1 -0
- package/dist/integrations/own-identity-warm.js +47 -0
- package/dist/integrations/own-identity-warm.js.map +1 -0
- package/dist/integrations/own-identity.js +39 -0
- package/dist/integrations/own-identity.js.map +1 -0
- package/dist/integrations/status-change.js +42 -0
- package/dist/integrations/status-change.js.map +1 -0
- package/dist/lead-defects.js +202 -0
- package/dist/lead-defects.js.map +1 -0
- package/dist/lead-digest.js +333 -0
- package/dist/lead-digest.js.map +1 -0
- package/dist/lead-release.js +286 -0
- package/dist/lead-release.js.map +1 -0
- package/dist/lead.js +328 -0
- package/dist/lead.js.map +1 -0
- package/dist/legacy-names.js +51 -0
- package/dist/legacy-names.js.map +1 -0
- package/dist/limits.js +44 -0
- package/dist/limits.js.map +1 -0
- package/dist/link-trust.js +224 -0
- package/dist/link-trust.js.map +1 -0
- package/dist/links.js +219 -0
- package/dist/links.js.map +1 -0
- package/dist/loopback.js +35 -0
- package/dist/loopback.js.map +1 -0
- package/dist/model-cap.js +60 -0
- package/dist/model-cap.js.map +1 -0
- package/dist/model-usage.js +173 -0
- package/dist/model-usage.js.map +1 -0
- package/dist/monitor/backfill.js +39 -0
- package/dist/monitor/backfill.js.map +1 -0
- package/dist/monitor/browser-probe.js +198 -0
- package/dist/monitor/browser-probe.js.map +1 -0
- package/dist/monitor/catch-up.js +31 -0
- package/dist/monitor/catch-up.js.map +1 -0
- package/dist/monitor/pollers.js +1606 -0
- package/dist/monitor/pollers.js.map +1 -0
- package/dist/monitor/probes.js +178 -0
- package/dist/monitor/probes.js.map +1 -0
- package/dist/monitor/self-health.js +228 -0
- package/dist/monitor/self-health.js.map +1 -0
- package/dist/monitor/statuspage.js +105 -0
- package/dist/monitor/statuspage.js.map +1 -0
- package/dist/nightly-scheduler.js +127 -0
- package/dist/nightly-scheduler.js.map +1 -0
- package/dist/nightly.js +141 -0
- package/dist/nightly.js.map +1 -0
- package/dist/notify/headline.js +114 -0
- package/dist/notify/headline.js.map +1 -0
- package/dist/notify/push.js +174 -0
- package/dist/notify/push.js.map +1 -0
- package/dist/object-cards.js +585 -0
- package/dist/object-cards.js.map +1 -0
- package/dist/object-links.js +47 -0
- package/dist/object-links.js.map +1 -0
- package/dist/onboarding-checks.js +141 -0
- package/dist/onboarding-checks.js.map +1 -0
- package/dist/onboarding.js +401 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/path-filters.js +62 -0
- package/dist/path-filters.js.map +1 -0
- package/dist/phone/alerts.js +67 -0
- package/dist/phone/alerts.js.map +1 -0
- package/dist/phone/auth.js +240 -0
- package/dist/phone/auth.js.map +1 -0
- package/dist/phone/pairing.js +442 -0
- package/dist/phone/pairing.js.map +1 -0
- package/dist/phone/prefs.js +27 -0
- package/dist/phone/prefs.js.map +1 -0
- package/dist/phone/tailscale.js +161 -0
- package/dist/phone/tailscale.js.map +1 -0
- package/dist/pr-scope.js +441 -0
- package/dist/pr-scope.js.map +1 -0
- package/dist/proc.js +156 -0
- package/dist/proc.js.map +1 -0
- package/dist/profile/cache.js +108 -0
- package/dist/profile/cache.js.map +1 -0
- package/dist/profile/ci.js +216 -0
- package/dist/profile/ci.js.map +1 -0
- package/dist/profile/index.js +8 -0
- package/dist/profile/index.js.map +1 -0
- package/dist/profile/job.js +135 -0
- package/dist/profile/job.js.map +1 -0
- package/dist/profile/queries/go-tags.scm +47 -0
- package/dist/profile/queries/java-tags.scm +25 -0
- package/dist/profile/queries/javascript-tags.scm +104 -0
- package/dist/profile/queries/python-tags.scm +19 -0
- package/dist/profile/queries/typescript-tags.scm +28 -0
- package/dist/profile/scan-thread.js +42 -0
- package/dist/profile/scan-thread.js.map +1 -0
- package/dist/profile/scan-worker.js +16 -0
- package/dist/profile/scan-worker.js.map +1 -0
- package/dist/profile/scan.js +351 -0
- package/dist/profile/scan.js.map +1 -0
- package/dist/profile/stack.js +528 -0
- package/dist/profile/stack.js.map +1 -0
- package/dist/profile/store.js +35 -0
- package/dist/profile/store.js.map +1 -0
- package/dist/profile/tests.js +399 -0
- package/dist/profile/tests.js.map +1 -0
- package/dist/queue.js +350 -0
- package/dist/queue.js.map +1 -0
- package/dist/refs.js +756 -0
- package/dist/refs.js.map +1 -0
- package/dist/release-notes.js +272 -0
- package/dist/release-notes.js.map +1 -0
- package/dist/reports/build.js +243 -0
- package/dist/reports/build.js.map +1 -0
- package/dist/reports/index.js +211 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/store.js +150 -0
- package/dist/reports/store.js.map +1 -0
- package/dist/reports/ticket-titles.js +124 -0
- package/dist/reports/ticket-titles.js.map +1 -0
- package/dist/reports/trace-map.js +1278 -0
- package/dist/reports/trace-map.js.map +1 -0
- package/dist/reports/traceability.js +422 -0
- package/dist/reports/traceability.js.map +1 -0
- package/dist/repos/mirror.js +356 -0
- package/dist/repos/mirror.js.map +1 -0
- package/dist/repos-github.js +108 -0
- package/dist/repos-github.js.map +1 -0
- package/dist/repos.js +891 -0
- package/dist/repos.js.map +1 -0
- package/dist/review/backend-anthropic.js +90 -0
- package/dist/review/backend-anthropic.js.map +1 -0
- package/dist/review/backend-cli.js +248 -0
- package/dist/review/backend-cli.js.map +1 -0
- package/dist/review/backend-codex.js +81 -0
- package/dist/review/backend-codex.js.map +1 -0
- package/dist/review/backend-mock.js +686 -0
- package/dist/review/backend-mock.js.map +1 -0
- package/dist/review/backend-only.js +168 -0
- package/dist/review/backend-only.js.map +1 -0
- package/dist/review/backend.js +105 -0
- package/dist/review/backend.js.map +1 -0
- package/dist/review/baseline/render-v1.js +483 -0
- package/dist/review/baseline/render-v1.js.map +1 -0
- package/dist/review/change-summary.js +197 -0
- package/dist/review/change-summary.js.map +1 -0
- package/dist/review/changelog.js +40 -0
- package/dist/review/changelog.js.map +1 -0
- package/dist/review/check.js +494 -0
- package/dist/review/check.js.map +1 -0
- package/dist/review/checkout.js +185 -0
- package/dist/review/checkout.js.map +1 -0
- package/dist/review/classify.js +178 -0
- package/dist/review/classify.js.map +1 -0
- package/dist/review/coverage.js +347 -0
- package/dist/review/coverage.js.map +1 -0
- package/dist/review/decision-eval.js +121 -0
- package/dist/review/decision-eval.js.map +1 -0
- package/dist/review/deliver.js +104 -0
- package/dist/review/deliver.js.map +1 -0
- package/dist/review/designer-eval.js +280 -0
- package/dist/review/designer-eval.js.map +1 -0
- package/dist/review/dogfood-digest.js +136 -0
- package/dist/review/dogfood-digest.js.map +1 -0
- package/dist/review/dogfood-eval.js +486 -0
- package/dist/review/dogfood-eval.js.map +1 -0
- package/dist/review/environment.js +109 -0
- package/dist/review/environment.js.map +1 -0
- package/dist/review/eval.js +405 -0
- package/dist/review/eval.js.map +1 -0
- package/dist/review/glob.js +110 -0
- package/dist/review/glob.js.map +1 -0
- package/dist/review/golden-export.js +219 -0
- package/dist/review/golden-export.js.map +1 -0
- package/dist/review/impact.js +406 -0
- package/dist/review/impact.js.map +1 -0
- package/dist/review/imports.js +542 -0
- package/dist/review/imports.js.map +1 -0
- package/dist/review/index.js +512 -0
- package/dist/review/index.js.map +1 -0
- package/dist/review/intent.js +128 -0
- package/dist/review/intent.js.map +1 -0
- package/dist/review/lenses.js +167 -0
- package/dist/review/lenses.js.map +1 -0
- package/dist/review/linked-tickets.js +293 -0
- package/dist/review/linked-tickets.js.map +1 -0
- package/dist/review/merge.js +370 -0
- package/dist/review/merge.js.map +1 -0
- package/dist/review/on-demand.js +218 -0
- package/dist/review/on-demand.js.map +1 -0
- package/dist/review/prompt-eval.js +299 -0
- package/dist/review/prompt-eval.js.map +1 -0
- package/dist/review/prompt-variants.js +37 -0
- package/dist/review/prompt-variants.js.map +1 -0
- package/dist/review/readability-eval.js +217 -0
- package/dist/review/readability-eval.js.map +1 -0
- package/dist/review/readability.js +295 -0
- package/dist/review/readability.js.map +1 -0
- package/dist/review/render.js +2409 -0
- package/dist/review/render.js.map +1 -0
- package/dist/review/repo.js +194 -0
- package/dist/review/repo.js.map +1 -0
- package/dist/review/report-plan.js +90 -0
- package/dist/review/report-plan.js.map +1 -0
- package/dist/review/routes.js +195 -0
- package/dist/review/routes.js.map +1 -0
- package/dist/review/run-summary.js +34 -0
- package/dist/review/run-summary.js.map +1 -0
- package/dist/review/run.js +245 -0
- package/dist/review/run.js.map +1 -0
- package/dist/review/scope.js +454 -0
- package/dist/review/scope.js.map +1 -0
- package/dist/review/security.js +432 -0
- package/dist/review/security.js.map +1 -0
- package/dist/review/signals.js +550 -0
- package/dist/review/signals.js.map +1 -0
- package/dist/review/specs.js +150 -0
- package/dist/review/specs.js.map +1 -0
- package/dist/review/ste.js +133 -0
- package/dist/review/ste.js.map +1 -0
- package/dist/review/test-repo-file.js +18 -0
- package/dist/review/test-repo-file.js.map +1 -0
- package/dist/review/test-repo-lines.js +53 -0
- package/dist/review/test-repo-lines.js.map +1 -0
- package/dist/review/ticket-on-demand.js +232 -0
- package/dist/review/ticket-on-demand.js.map +1 -0
- package/dist/review/yaml.js +298 -0
- package/dist/review/yaml.js.map +1 -0
- package/dist/room.js +361 -0
- package/dist/room.js.map +1 -0
- package/dist/routes/activity.js +219 -0
- package/dist/routes/activity.js.map +1 -0
- package/dist/routes/call.js +29 -0
- package/dist/routes/call.js.map +1 -0
- package/dist/routes/cards.js +40 -0
- package/dist/routes/cards.js.map +1 -0
- package/dist/routes/cases.js +133 -0
- package/dist/routes/cases.js.map +1 -0
- package/dist/routes/connect.js +268 -0
- package/dist/routes/connect.js.map +1 -0
- package/dist/routes/connection-presets.js +32 -0
- package/dist/routes/connection-presets.js.map +1 -0
- package/dist/routes/connections.js +177 -0
- package/dist/routes/connections.js.map +1 -0
- package/dist/routes/disk.js +19 -0
- package/dist/routes/disk.js.map +1 -0
- package/dist/routes/docs.js +71 -0
- package/dist/routes/docs.js.map +1 -0
- package/dist/routes/dot-suggest.js +1002 -0
- package/dist/routes/dot-suggest.js.map +1 -0
- package/dist/routes/evidence-pack.js +16 -0
- package/dist/routes/evidence-pack.js.map +1 -0
- package/dist/routes/health.js +121 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/impact.js +48 -0
- package/dist/routes/impact.js.map +1 -0
- package/dist/routes/lead.js +50 -0
- package/dist/routes/lead.js.map +1 -0
- package/dist/routes/links.js +13 -0
- package/dist/routes/links.js.map +1 -0
- package/dist/routes/markdown.js +62 -0
- package/dist/routes/markdown.js.map +1 -0
- package/dist/routes/onboarding.js +47 -0
- package/dist/routes/onboarding.js.map +1 -0
- package/dist/routes/phone.js +231 -0
- package/dist/routes/phone.js.map +1 -0
- package/dist/routes/release-notes.js +30 -0
- package/dist/routes/release-notes.js.map +1 -0
- package/dist/routes/reports.js +102 -0
- package/dist/routes/reports.js.map +1 -0
- package/dist/routes/repos.js +91 -0
- package/dist/routes/repos.js.map +1 -0
- package/dist/routes/review.js +283 -0
- package/dist/routes/review.js.map +1 -0
- package/dist/routes/roles.js +114 -0
- package/dist/routes/roles.js.map +1 -0
- package/dist/routes/room.js +21 -0
- package/dist/routes/room.js.map +1 -0
- package/dist/routes/runner.js +156 -0
- package/dist/routes/runner.js.map +1 -0
- package/dist/routes/runs.js +84 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/setup.js +18 -0
- package/dist/routes/setup.js.map +1 -0
- package/dist/routes/test-runs.js +220 -0
- package/dist/routes/test-runs.js.map +1 -0
- package/dist/routes/ticket-status.js +17 -0
- package/dist/routes/ticket-status.js.map +1 -0
- package/dist/routes/traceability.js +143 -0
- package/dist/routes/traceability.js.map +1 -0
- package/dist/routes/true.js +142 -0
- package/dist/routes/true.js.map +1 -0
- package/dist/routes/updates.js +70 -0
- package/dist/routes/updates.js.map +1 -0
- package/dist/runner/adapters/index.js +12 -0
- package/dist/runner/adapters/index.js.map +1 -0
- package/dist/runner/adapters/playwright.js +68 -0
- package/dist/runner/adapters/playwright.js.map +1 -0
- package/dist/runner/aivision/cases.js +172 -0
- package/dist/runner/aivision/cases.js.map +1 -0
- package/dist/runner/aivision/cli.js +201 -0
- package/dist/runner/aivision/cli.js.map +1 -0
- package/dist/runner/aivision/index.js +281 -0
- package/dist/runner/aivision/index.js.map +1 -0
- package/dist/runner/aivision/server.js +394 -0
- package/dist/runner/aivision/server.js.map +1 -0
- package/dist/runner/aivision/shared.js +140 -0
- package/dist/runner/aivision/shared.js.map +1 -0
- package/dist/runner/artifact-cap.js +189 -0
- package/dist/runner/artifact-cap.js.map +1 -0
- package/dist/runner/artifacts.js +433 -0
- package/dist/runner/artifacts.js.map +1 -0
- package/dist/runner/command.js +564 -0
- package/dist/runner/command.js.map +1 -0
- package/dist/runner/copyfiles.js +221 -0
- package/dist/runner/copyfiles.js.map +1 -0
- package/dist/runner/engines.js +32 -0
- package/dist/runner/engines.js.map +1 -0
- package/dist/runner/evidence.js +114 -0
- package/dist/runner/evidence.js.map +1 -0
- package/dist/runner/host-env.js +160 -0
- package/dist/runner/host-env.js.map +1 -0
- package/dist/runner/index.js +1221 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/observe.js +603 -0
- package/dist/runner/observe.js.map +1 -0
- package/dist/runner/playwright-json.js +108 -0
- package/dist/runner/playwright-json.js.map +1 -0
- package/dist/runner/pwgen/exec.js +192 -0
- package/dist/runner/pwgen/exec.js.map +1 -0
- package/dist/runner/pwgen/explore.js +111 -0
- package/dist/runner/pwgen/explore.js.map +1 -0
- package/dist/runner/pwgen/index.js +423 -0
- package/dist/runner/pwgen/index.js.map +1 -0
- package/dist/runner/pwgen/propose.js +69 -0
- package/dist/runner/pwgen/propose.js.map +1 -0
- package/dist/runner/pwgen/source.js +632 -0
- package/dist/runner/pwgen/source.js.map +1 -0
- package/dist/runner/setup.js +222 -0
- package/dist/runner/setup.js.map +1 -0
- package/dist/runner/step-reporter.js +107 -0
- package/dist/runner/step-reporter.js.map +1 -0
- package/dist/runner/test-repo.js +326 -0
- package/dist/runner/test-repo.js.map +1 -0
- package/dist/runner/typed-value.js +46 -0
- package/dist/runner/typed-value.js.map +1 -0
- package/dist/runner/verify.js +133 -0
- package/dist/runner/verify.js.map +1 -0
- package/dist/runner/worktree.js +349 -0
- package/dist/runner/worktree.js.map +1 -0
- package/dist/sandbox.js +61 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/server.js +262 -0
- package/dist/server.js.map +1 -0
- package/dist/shadow-week.js +126 -0
- package/dist/shadow-week.js.map +1 -0
- package/dist/shutdown.js +92 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/slack/index.js +645 -0
- package/dist/slack/index.js.map +1 -0
- package/dist/stages/config.js +147 -0
- package/dist/stages/config.js.map +1 -0
- package/dist/stages/index.js +41 -0
- package/dist/stages/index.js.map +1 -0
- package/dist/suites.js +293 -0
- package/dist/suites.js.map +1 -0
- package/dist/target-url.js +116 -0
- package/dist/target-url.js.map +1 -0
- package/dist/test-runs.js +662 -0
- package/dist/test-runs.js.map +1 -0
- package/dist/ticket-keys.js +97 -0
- package/dist/ticket-keys.js.map +1 -0
- package/dist/ticket-supersede.js +105 -0
- package/dist/ticket-supersede.js.map +1 -0
- package/dist/tinybee/ed25519.js +99 -0
- package/dist/tinybee/ed25519.js.map +1 -0
- package/dist/tinybee/models-routes.js +19 -0
- package/dist/tinybee/models-routes.js.map +1 -0
- package/dist/tinybee/pair-payload.js +41 -0
- package/dist/tinybee/pair-payload.js.map +1 -0
- package/dist/tinybee/update-manifest.js +77 -0
- package/dist/tinybee/update-manifest.js.map +1 -0
- package/dist/tinybee/well-known.js +64 -0
- package/dist/tinybee/well-known.js.map +1 -0
- package/dist/tinybee/workflows/activity.js +23 -0
- package/dist/tinybee/workflows/activity.js.map +1 -0
- package/dist/tinybee/workflows/cron.js +210 -0
- package/dist/tinybee/workflows/cron.js.map +1 -0
- package/dist/tinybee/workflows/engine.js +371 -0
- package/dist/tinybee/workflows/engine.js.map +1 -0
- package/dist/tinybee/workflows/from-text.js +203 -0
- package/dist/tinybee/workflows/from-text.js.map +1 -0
- package/dist/tinybee/workflows/routes.js +189 -0
- package/dist/tinybee/workflows/routes.js.map +1 -0
- package/dist/tinybee/workflows/scheduler.js +100 -0
- package/dist/tinybee/workflows/scheduler.js.map +1 -0
- package/dist/tinybee/workflows/skills.js +227 -0
- package/dist/tinybee/workflows/skills.js.map +1 -0
- package/dist/tinybee/workflows/store.js +205 -0
- package/dist/tinybee/workflows/store.js.map +1 -0
- package/dist/tinybee/workflows/types.js +180 -0
- package/dist/tinybee/workflows/types.js.map +1 -0
- package/dist/tinybee/workflows/yaml.js +323 -0
- package/dist/tinybee/workflows/yaml.js.map +1 -0
- package/dist/true/api.js +495 -0
- package/dist/true/api.js.map +1 -0
- package/dist/true/client.js +292 -0
- package/dist/true/client.js.map +1 -0
- package/dist/true/clock.js +36 -0
- package/dist/true/clock.js.map +1 -0
- package/dist/true/events.js +125 -0
- package/dist/true/events.js.map +1 -0
- package/dist/true/hosts.js +98 -0
- package/dist/true/hosts.js.map +1 -0
- package/dist/true/index.js +29 -0
- package/dist/true/index.js.map +1 -0
- package/dist/true/key.js +54 -0
- package/dist/true/key.js.map +1 -0
- package/dist/true/line.js +69 -0
- package/dist/true/line.js.map +1 -0
- package/dist/true/mask.js +31 -0
- package/dist/true/mask.js.map +1 -0
- package/dist/true/names.js +114 -0
- package/dist/true/names.js.map +1 -0
- package/dist/true/outbox.js +233 -0
- package/dist/true/outbox.js.map +1 -0
- package/dist/true/replay.js +164 -0
- package/dist/true/replay.js.map +1 -0
- package/dist/true/settings.js +123 -0
- package/dist/true/settings.js.map +1 -0
- package/dist/true/status.js +189 -0
- package/dist/true/status.js.map +1 -0
- package/dist/true/sync-cases.js +222 -0
- package/dist/true/sync-cases.js.map +1 -0
- package/dist/true/sync-manual.js +295 -0
- package/dist/true/sync-manual.js.map +1 -0
- package/dist/true/sync-runs.js +109 -0
- package/dist/true/sync-runs.js.map +1 -0
- package/dist/true/worker.js +414 -0
- package/dist/true/worker.js.map +1 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/dist/updates/asks.js +38 -0
- package/dist/updates/asks.js.map +1 -0
- package/dist/updates/index.js +835 -0
- package/dist/updates/index.js.map +1 -0
- package/dist/updates/owner.js +24 -0
- package/dist/updates/owner.js.map +1 -0
- package/dist/updates/prefs.js +118 -0
- package/dist/updates/prefs.js.map +1 -0
- package/dist/updates/route.js +78 -0
- package/dist/updates/route.js.map +1 -0
- package/dist/updates/sources.js +345 -0
- package/dist/updates/sources.js.map +1 -0
- package/dist/updates/words.js +452 -0
- package/dist/updates/words.js.map +1 -0
- package/dist/version.js +53 -0
- package/dist/version.js.map +1 -0
- package/dist/view-compute.js +382 -0
- package/dist/view-compute.js.map +1 -0
- package/dist/view-spec.js +894 -0
- package/dist/view-spec.js.map +1 -0
- package/dist/web/apple-touch-icon.png +0 -0
- package/dist/web/assets/ApprovalCard-Br_z5z7G.css +1 -0
- package/dist/web/assets/ApprovalCard-CfGhGFo_.js +3 -0
- package/dist/web/assets/CardFromRef-BaTGmZ9c.js +2 -0
- package/dist/web/assets/CardFromRef-DO7i2uDd.css +1 -0
- package/dist/web/assets/Cases-8l_6UcLh.js +2 -0
- package/dist/web/assets/Cases-CpfED0uB.css +1 -0
- package/dist/web/assets/Chat-BKDiR0qt.js +3 -0
- package/dist/web/assets/Chat-DxjdyYUu.css +1 -0
- package/dist/web/assets/ConfirmDialog-CIMveD-b.js +2 -0
- package/dist/web/assets/ConnectSheet-Cm5vbZdR.js +4 -0
- package/dist/web/assets/Docs-HKGuY0WE.js +2 -0
- package/dist/web/assets/Docs-fodKx8S7.css +1 -0
- package/dist/web/assets/DotDetail-DskS3NWe.js +2 -0
- package/dist/web/assets/DotDetail-OWRSD_1x.css +1 -0
- package/dist/web/assets/DotStage-BZDclfzV.css +1 -0
- package/dist/web/assets/DotStage-CtMNzCN3.js +2 -0
- package/dist/web/assets/Dots-BqCsS34m.js +2 -0
- package/dist/web/assets/EvidencePack-DQ3kCJX4.js +2 -0
- package/dist/web/assets/EvidencePack-DV_9ETsA.css +1 -0
- package/dist/web/assets/FailedDeliveries-1F2kFcs9.js +2 -0
- package/dist/web/assets/FailedDeliveries-DXa2_VvI.css +1 -0
- package/dist/web/assets/Feed-5wiHRTFK.js +2 -0
- package/dist/web/assets/GfmView-C-NYaduC.js +4 -0
- package/dist/web/assets/ImpactList-C-RNuDB0.js +2 -0
- package/dist/web/assets/ImpactList-C612dFdw.css +1 -0
- package/dist/web/assets/Inbox-kc1bKVL_.js +2 -0
- package/dist/web/assets/JoinScreen-C3L4wmP3.js +2 -0
- package/dist/web/assets/JoinScreen-COeAUv5v.css +1 -0
- package/dist/web/assets/LeadDialog-N3Zul9Rw.js +8 -0
- package/dist/web/assets/LeadDialog-xyWjAuAS.css +1 -0
- package/dist/web/assets/ListeningLine-BRFNaczY.js +2 -0
- package/dist/web/assets/ListeningLine-pN8CgyiK.css +1 -0
- package/dist/web/assets/Mascots-pIyGpxtD.js +2 -0
- package/dist/web/assets/ModelChoices-BxO1zyyr.js +2 -0
- package/dist/web/assets/ModelChoices-DQJnVxfs.css +1 -0
- package/dist/web/assets/NewDotDialog-CDPUWmgN.js +2 -0
- package/dist/web/assets/NewDotDialog-DrPPqkSZ.css +1 -0
- package/dist/web/assets/NewTestRunDialog-BQBthVHE.js +2 -0
- package/dist/web/assets/NoBreakNames-Csxdqdt6.js +2 -0
- package/dist/web/assets/Pair-omex_K7H.js +2 -0
- package/dist/web/assets/PushSection-CmqHlE_2.js +2 -0
- package/dist/web/assets/ReleaseNotes-B6VqFewP.js +2 -0
- package/dist/web/assets/ReleaseNotes-DBJUL7Vm.css +1 -0
- package/dist/web/assets/ReportPage-BHS1xWEt.js +162 -0
- package/dist/web/assets/Reports-BEHnDIb1.js +2 -0
- package/dist/web/assets/ReviewChangeDialog-BVSt-cw-.js +2 -0
- package/dist/web/assets/ReviewChangeDialog-BbIlHRx0.css +1 -0
- package/dist/web/assets/Room-BoG_uge4.js +2 -0
- package/dist/web/assets/Room-evAfiW_e.css +1 -0
- package/dist/web/assets/RunActions-ZY7yf1AF.js +2 -0
- package/dist/web/assets/RunDetail-C8St20GQ.css +1 -0
- package/dist/web/assets/RunDetail-qADXjBvd.js +9 -0
- package/dist/web/assets/RunRow-BKEJv8ib.js +2 -0
- package/dist/web/assets/RunnerTry-Dgpp67-s.js +6 -0
- package/dist/web/assets/RunnerTry-DsweWOfO.css +1 -0
- package/dist/web/assets/Settings-fs-QJwNM.js +2 -0
- package/dist/web/assets/Setup-DI6hBEP-.js +2 -0
- package/dist/web/assets/TestRows-wh03T5Li.js +4 -0
- package/dist/web/assets/TestRun-DTOyF-Pv.js +2 -0
- package/dist/web/assets/TestRuns-ggDjm1Q8.js +2 -0
- package/dist/web/assets/TinyBeeAddLaptop-bc3pmh3T.js +2 -0
- package/dist/web/assets/TinyBeeAi-CkyOzhm5.js +2 -0
- package/dist/web/assets/TinyBeeConnections-B2K_P38u.js +2 -0
- package/dist/web/assets/TinyBeeHome-DSpxX5KS.js +3 -0
- package/dist/web/assets/TinyBeePlan-BamiLziu.js +2 -0
- package/dist/web/assets/TinyBeeSignup-vHcz0Wen.js +2 -0
- package/dist/web/assets/TinyBeeSkills-By9RLUse.js +2 -0
- package/dist/web/assets/TinyBeeWorkflow-DeNO7Jsh.js +2 -0
- package/dist/web/assets/TinyBeeWorkflowEditor-B6OGC2OT.js +2 -0
- package/dist/web/assets/TinyBeeWorkflows-BN4-h6lt.js +2 -0
- package/dist/web/assets/Trace-BBCI1aIB.css +1 -0
- package/dist/web/assets/Trace-aF92UWaH.js +2 -0
- package/dist/web/assets/UpdatesSection-CCWEbkue.js +2 -0
- package/dist/web/assets/Welcome-CCcy558Q.js +2 -0
- package/dist/web/assets/activity-C3qilrDm.css +1 -0
- package/dist/web/assets/activity-CBfTSxqw.js +2 -0
- package/dist/web/assets/authedMedia-BTYt_tyu.js +2 -0
- package/dist/web/assets/beeApi-BHW8Tx1s.js +2 -0
- package/dist/web/assets/data-CmXvx3Mj.js +2 -0
- package/dist/web/assets/engines-CfdJODFj.css +1 -0
- package/dist/web/assets/format-BBZ8vFyT.js +2 -0
- package/dist/web/assets/forms-Coc7p2UF.css +1 -0
- package/dist/web/assets/hivePush-DZJDokj7.js +2 -0
- package/dist/web/assets/impactModel-MY1OFuiP.js +2 -0
- package/dist/web/assets/index-B6qKm1NW.js +13 -0
- package/dist/web/assets/index-BvKyT1X7.css +1 -0
- package/dist/web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/web/assets/lead-BL_P_kri.css +1 -0
- package/dist/web/assets/model-BIQy5IVG.js +2 -0
- package/dist/web/assets/modelsApi-PUSySRQw.js +2 -0
- package/dist/web/assets/newDotModel-BaLLyw57.js +2 -0
- package/dist/web/assets/onboarding-bfKqnM4Z.css +1 -0
- package/dist/web/assets/phone-Rs7FoyG0.css +1 -0
- package/dist/web/assets/phoneApi-BG_1-M-D.js +3 -0
- package/dist/web/assets/releaseModel-EynYMVOC.js +2 -0
- package/dist/web/assets/releaseNotesModel-A1Rtv3cV.js +2 -0
- package/dist/web/assets/reports-BWaA1HhM.js +37 -0
- package/dist/web/assets/reports-DXwdWQsB.css +1 -0
- package/dist/web/assets/router-W6nZsQ33.js +2 -0
- package/dist/web/assets/runs-BY0Owv93.css +1 -0
- package/dist/web/assets/shadowWeekModel-BUUiww09.js +2 -0
- package/dist/web/assets/storage-yvL36AWt.js +2 -0
- package/dist/web/assets/store-IqrqHuFR.js +2 -0
- package/dist/web/assets/testruns-BzIZ0cR0.css +1 -0
- package/dist/web/assets/testruns-DyaqX4ji.js +2 -0
- package/dist/web/assets/true-9Q68cs5b.js +2 -0
- package/dist/web/assets/true-DPGBpoir.css +1 -0
- package/dist/web/assets/ui-DcmhYyYp.js +13 -0
- package/dist/web/assets/ui-DxEDgbIx.css +1 -0
- package/dist/web/assets/usePauseDot-BV60ZVy1.js +2 -0
- package/dist/web/assets/usePauseDot-NrSzMI1C.css +1 -0
- package/dist/web/assets/usePush-Dsm-TjlG.js +2 -0
- package/dist/web/assets/useRefChips-CbafNx59.js +68 -0
- package/dist/web/assets/useRestoreDot-D0B6W82H.js +2 -0
- package/dist/web/assets/view-worker-pyeVAhUT.js +2 -0
- package/dist/web/assets/workflowUi-QYsd3n9J.js +2 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/icon-192.png +0 -0
- package/dist/web/icon-512.png +0 -0
- package/dist/web/icon-maskable-512.png +0 -0
- package/dist/web/index.html +45 -0
- package/dist/web/manifest.webmanifest +23 -0
- package/dist/web/mascots/argus-attention.svg +7 -0
- package/dist/web/mascots/argus-ok.svg +7 -0
- package/dist/web/mascots/argus-outage.svg +7 -0
- package/dist/web/mascots/argus-running.svg +7 -0
- package/dist/web/mascots/bolt-attention.svg +7 -0
- package/dist/web/mascots/bolt-ok.svg +7 -0
- package/dist/web/mascots/bolt-outage.svg +7 -0
- package/dist/web/mascots/bolt-running.svg +7 -0
- package/dist/web/mascots/echo-attention.svg +7 -0
- package/dist/web/mascots/echo-ok.svg +7 -0
- package/dist/web/mascots/echo-outage.svg +7 -0
- package/dist/web/mascots/echo-running.svg +7 -0
- package/dist/web/mascots/lens-attention.svg +7 -0
- package/dist/web/mascots/lens-ok.svg +7 -0
- package/dist/web/mascots/lens-outage.svg +7 -0
- package/dist/web/mascots/lens-running.svg +7 -0
- package/dist/web/mascots/moss-attention.svg +7 -0
- package/dist/web/mascots/moss-ok.svg +7 -0
- package/dist/web/mascots/moss-outage.svg +7 -0
- package/dist/web/mascots/moss-running.svg +7 -0
- package/dist/web/mascots/nit-attention.svg +7 -0
- package/dist/web/mascots/nit-ok.svg +7 -0
- package/dist/web/mascots/nit-outage.svg +7 -0
- package/dist/web/mascots/nit-running.svg +7 -0
- package/dist/web/mascots/nova-attention.svg +7 -0
- package/dist/web/mascots/nova-ok.svg +7 -0
- package/dist/web/mascots/nova-outage.svg +7 -0
- package/dist/web/mascots/nova-running.svg +7 -0
- package/dist/web/mascots/penn-attention.svg +7 -0
- package/dist/web/mascots/penn-ok.svg +7 -0
- package/dist/web/mascots/penn-outage.svg +7 -0
- package/dist/web/mascots/penn-running.svg +7 -0
- package/dist/web/mascots/pip-attention.svg +7 -0
- package/dist/web/mascots/pip-ok.svg +7 -0
- package/dist/web/mascots/pip-outage.svg +7 -0
- package/dist/web/mascots/pip-running.svg +7 -0
- package/dist/web/mascots/ward-attention.svg +7 -0
- package/dist/web/mascots/ward-ok.svg +7 -0
- package/dist/web/mascots/ward-outage.svg +7 -0
- package/dist/web/mascots/ward-running.svg +7 -0
- package/dist/web/sw.js +98 -0
- package/dist/webhook-seen.js +53 -0
- package/dist/webhook-seen.js.map +1 -0
- package/dist/webhooks.js +625 -0
- package/dist/webhooks.js.map +1 -0
- package/dist/zip.js +63 -0
- package/dist/zip.js.map +1 -0
- package/docs/API-V2.md +532 -0
- package/docs/CHAT-EVAL.md +130 -0
- package/docs/CHAT-UI.md +416 -0
- package/docs/CONNECTIONS.md +89 -0
- package/docs/DATA-MODEL.md +518 -0
- package/docs/DEPLOY.md +577 -0
- package/docs/DOGFOOD-LEDGER.md +81 -0
- package/docs/GITHUB.md +148 -0
- package/docs/INTEGRATION-MODEL.md +200 -0
- package/docs/LEAD-DOT.md +553 -0
- package/docs/LIST-PATTERNS.md +52 -0
- package/docs/MULTI-REPO.md +766 -0
- package/docs/PARITY.md +276 -0
- package/docs/PR-REVIEW-QA.md +1266 -0
- package/docs/PR-REVIEW.md +357 -0
- package/docs/SANDBOX.md +320 -0
- package/docs/SETUP.md +776 -0
- package/docs/SLACK.md +80 -0
- package/docs/STAGES.md +619 -0
- package/docs/TRACE-MAP.md +89 -0
- package/docs/TRACKERS.md +225 -0
- package/docs/VOICE.md +36 -0
- package/docs/tinybee/00-README.md +45 -0
- package/docs/tinybee/01-PRD.md +216 -0
- package/docs/tinybee/02-architecture-pairing.md +199 -0
- package/docs/tinybee/03-local-agent.md +222 -0
- package/docs/tinybee/04-local-setup-ui.md +128 -0
- package/docs/tinybee/05-mobile-app-ux.md +199 -0
- package/docs/tinybee/06-environments-and-delivery.md +148 -0
- package/docs/tinybee/07-coding-agent-handoff.md +116 -0
- package/docs/tinybee/OPEN-QUESTIONS.md +26 -0
- package/docs/tinybee/PROGRESS.md +134 -0
- package/package.json +111 -4
package/docs/STAGES.md
ADDED
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
# Dot stages: build design
|
|
2
|
+
|
|
3
|
+
A dot today is one worker that does every QA job for its repo and tracker. This design gives each dot a small team of specialists, one per step from ticket to production, and lets each one pass its notes to the next. Think of a relay race where the baton is the ticket: the analyst reads it, the designer writes the tests, the reviewer runs them on the pull request, the regression runner runs them again after the merge, and the guard reports whether the release is covered.
|
|
4
|
+
|
|
5
|
+
Scope: Linear KAT-130 (dot stages, the new Test designer) and the use of the KAT-131 stage avatars. No code changes with this document; section 10 lists the work. Code references are to `duonghaijoe/localdost` at `a2f2ece` (2026-10-08). The generated Playwright engine is in PR #9 (`kat-93-playwright-gen`), and the repo sets, links, and traceability design is [MULTI-REPO.md](MULTI-REPO.md) (PR #7). Section numbers such as "MULTI-REPO 4.6" point there. Names from PR #9 (`src/runner/pwgen`, `runner.engine`, `runner.pwgen`, `QaEngine`, `pwgen.maxSpecs`) are contracts of that open PR and are not on `main` yet; the tasks that use them wait for its merge.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
1. One dot per product area
|
|
10
|
+
2. Stages and the code they wrap
|
|
11
|
+
3. Test designer
|
|
12
|
+
4. Handoff data model
|
|
13
|
+
5. Rules, model, and toggles per stage
|
|
14
|
+
6. Migration from role presets
|
|
15
|
+
7. Ticket timeline on the dot page
|
|
16
|
+
8. Stage avatars
|
|
17
|
+
9. Cost bounds and edge cases
|
|
18
|
+
10. Build tasks
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 1. One dot per product area
|
|
23
|
+
|
|
24
|
+
### 1.1 Decision
|
|
25
|
+
|
|
26
|
+
Huy asked on 2026-10-08 whether localdost should run one dot per role or one large dot. The recommendation in KAT-130, which stands unless Huy objects, is one dot per product area that runs specialist stages with handoffs.
|
|
27
|
+
|
|
28
|
+
| Option | What breaks | Decision |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| One dot per role (six dots for one area) | The ticket, its test cases, the PR, and the results cross four dots. Each dot re-reads the ticket, the user writes six briefs, and the Inbox shows six names for one feature | Rejected |
|
|
31
|
+
| One dot for the whole product | One brief and one rule set must cover checkout and the admin console alike. The dot's status color says nothing about which area is in trouble | Rejected |
|
|
32
|
+
| One dot per product area, with stages | Context stays inside one dot from ticket to production. Each stage has its own rules, model, and on/off switch. Status reads per area | Chosen |
|
|
33
|
+
|
|
34
|
+
Update 2026-10-22 (KAT-405). Huy chose one dot per job for the QA team: Ticket Reviewer (Ticket analyst and Test designer, tracker `katalon-studio/product`, label `pod:agentic`), PR Reviewer (Change reviewer, the four pod app repos), Regression Runner (Regression runner, the Tests repo and the deploy wait) and Site Watcher (Prod watcher, a site check on the QA tenant). The objection above, that the ticket, its cases, the PR and the results cross dots, is answered by one more dot, the Lead QA dot: it holds no repos, tracker or site of its own and names its member dots, so the context crosses dots through its member list. The lead shows team health, writes one daily team digest, answers questions about every member, lets the members share the test cases of a ticket, keeps one Inbox item for one bug, and gives the release call. Design and build spec: [LEAD-DOT.md](LEAD-DOT.md). A dot per product area with stages stays valid for a team that wants it, and a lead can name those dots too.
|
|
35
|
+
|
|
36
|
+
### 1.2 What an area is
|
|
37
|
+
|
|
38
|
+
A dot's area is the union of four scopes it already holds or will hold:
|
|
39
|
+
|
|
40
|
+
- Repos: the dot's repo set with roles (MULTI-REPO 1.2) and `pathFilters` per repo.
|
|
41
|
+
- Tracker: Jira project keys, Linear team keys, or GitHub Issues repos, labels, issue types, and milestones (`Watch.tracker`, `GithubTracker`).
|
|
42
|
+
- Production: `probes` and `statusPages`.
|
|
43
|
+
- People: the brief (`mission`, `notifyWhen`, `mustNot`) and the Slack channel.
|
|
44
|
+
|
|
45
|
+
Two dots can share a repo by area: `watchMatches` in `src/webhooks.ts` applies `pathFilters` (KAT-160), so a PR or push matches when one changed file falls inside them.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2. Stages and the code they wrap
|
|
50
|
+
|
|
51
|
+
Five of the six stages exist today as flows. A stage is a name, a set of job kinds, an avatar, and a config block on the dot. The flows keep their code; the stage layer adds routing, rules, model choice, and handoffs around them.
|
|
52
|
+
|
|
53
|
+
| Stage | Avatar | Trigger | Job kind | Code today | Output today |
|
|
54
|
+
|---|---|---|---|---|---|
|
|
55
|
+
| Ticket analyst | lens | `ticket_created`, `ticket_updated` | `ticket_review` | `src/flows/ticketReview.ts`: `llm.score`, `SCORE_FLOOR` 30, code search by `keywords()`, `analyze({ task: 'ticket_review' })`, timeline links through `recordIssueTimeline` | `Verdict` with `openQuestions`, `findings`, `testIdeas`; a `ticket_comment` through the gate; the run report saves as a `test_plan` page (`reportKindForRun`) |
|
|
56
|
+
| Test designer | penn | Handoff from the analyst; on demand | `test_design` (new) | None. Section 3 | Test cases linked to the ticket, a `test_plan` page per ticket |
|
|
57
|
+
| Change reviewer | nit | `pr_opened`, and `ci_failure` on an open PR head | `pr_check`, `ci_failure` | `src/flows/change.ts` `checkChange(job, 'pr_check')`, `src/review/*` (QA review and verifier), `src/flows/ticks.ts` (checklist ticks), `src/runner/aivision`, `src/runner/pwgen` (PR #9), `src/links.ts` `recordPrLinks` | Check run, sticky PR comment, push, `file_defect` drafts (`src/flows/defects.ts`) |
|
|
58
|
+
| Regression runner | echo | `pr_merged`, `push` to the default branch, and `ci_failure` elsewhere | `post_merge`, `ci_failure`, `rerun`, `repo_scan`, `nightly_run` | `checkChange(job, 'post_merge')`: reuses the PR review at the same head (`findReviewedRun`), `scopeSpecs` widens the spec pick; `src/flows/rerun.ts`; `src/flows/nightlyRun.ts` (the scheduled Tests repo run, [SETUP.md](SETUP.md#nightly-test-run)); `src/deploy-wait.ts` holds a merge job until its commit is deployed, when the dot sets `waitForDeploySec` ([SETUP.md](SETUP.md#waiting-for-the-deploy)) | Check run on the merge commit, push, `file_defect` drafts, release-note lines for the digest and the Release notes page ([API-V2.md](API-V2.md#release-notes-kat-391)) |
|
|
59
|
+
| Prod watcher | argus | `probe_down`, `statuspage`, `probe_up` | `outage`, `recovery` | `src/monitor/probes.ts` (third failure queues `outage`), `browser-probe.ts`, `statuspage.ts`, `src/flows/outage.ts` (blames merges of the last 24 h), `src/flows/recovery.ts` | Urgent push, Slack notice, `incident` report page |
|
|
60
|
+
| Release guard | ward | Schedule, milestone due date, on demand | `release_check` (new) | Builds on `links` (`LinkRecord`), per-issue test status and the traceability view (MULTI-REPO 4.6, 4.7), `releaseNotesLines` in `src/flows/digest.ts` | A `readiness` report page per milestone |
|
|
61
|
+
|
|
62
|
+
The daily digest (`digest`) stays a dot-level job with no stage, since it summarizes every stage. A `rerun` takes the stage of the run it reruns. A `ci_failure` takes the Change reviewer when the failed head is the head of an open PR the dot checked, else the Regression runner.
|
|
63
|
+
|
|
64
|
+
The stage keys are the ones `client/src/ui/mascotArt.ts` already defines for the avatars: `analyst`, `designer`, `reviewer`, `regression`, `watcher`, `guard`. Task 1 (built, KAT-159) moved `StageKey` into `src/types.ts`; the client imports it from `@shared`.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// src/types.ts (add only)
|
|
68
|
+
|
|
69
|
+
export type StageKey = 'analyst' | 'designer' | 'reviewer' | 'regression' | 'watcher' | 'guard';
|
|
70
|
+
|
|
71
|
+
export interface RunRecord {
|
|
72
|
+
// existing fields unchanged
|
|
73
|
+
/** Stage that ran this job. Unset on runs from before stages and on the digest. */
|
|
74
|
+
stage?: StageKey;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Built in KAT-159: `src/stages/index.ts` holds the registry (`STAGES`, `STAGE_KEYS`, `stageFor(kind)`, `runStage(run)`; the client reaches it through the `@stages` alias). `stageFor` takes the job kind only and maps `ci_failure` to the Regression runner; the open-PR-head split and `ev`/`rerunOf` arguments below are not built yet. `startRun` copies `stage` from the source run on a rerun. `runStage` falls back to `stageFor(kind)` for rows without `stage`, and `/api/feed` and `/api/runs/:id` return `stage`. The registry design: the stage label, its avatar name, its default config, and `stageFor(kind, ev, rerunOf)`. A fixed map from job kind to stage cannot serve `ci_failure` and `rerun`, so `stageFor` reads the event and the source run: `ci_failure` checks whether `ev.ci.headSha` is the head of an open PR the dot checked, and `rerun` copies `stage` from the run named in `rerunOf`. Every other kind maps one to one. `startRun` sets `stage` from `stageFor`, so every run, approval, and Feed row knows its stage without new queries.
|
|
79
|
+
|
|
80
|
+
The Lead QA dot (KAT-405) answers "can we release <milestone>?" with `releaseCall` in `src/lead-release.ts`: Ready, Ready with risk or Not ready, built by code from the rows of its members, read only, with readiness words and never "release" or "hold". The Release guard of task 12 stays as planned for a single dot. When it lands, its readiness rules call `releaseCall` for a lead's milestone, so a dot and a lead never give two answers for one milestone, and the rule that the guard never says release or hold stays.
|
|
81
|
+
|
|
82
|
+
Two new job kinds, `test_design` and `release_check`, join `JobKind` in the tasks that build their flows (tasks 6 and 12), never earlier. `JobKind` has exhaustive maps that must grow in the same PR: `KIND_LABEL` in `src/reports/build.ts` and in `client/src/features/runs/format.ts`, `reportKindForRun`, the queue handler registration, and `AnalyzeRequest['task']` with its prompt when the flow calls `analyze`.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. Test designer
|
|
87
|
+
|
|
88
|
+
### 3.1 Job
|
|
89
|
+
|
|
90
|
+
The analyst says what to test in a few test ideas. The designer turns that into real test cases a person or a machine can run, links them to the ticket, and keeps them current as the ticket changes. When a PR later names the ticket, the Change reviewer runs those same cases.
|
|
91
|
+
|
|
92
|
+
### 3.2 Input
|
|
93
|
+
|
|
94
|
+
- The ticket: title, description, acceptance criteria, type, labels (`Ticket`).
|
|
95
|
+
- The analyst's verdict for the same ticket revision: `testIdeas`, `openQuestions`, `findings`, and the `codeHits` it found.
|
|
96
|
+
- The spec inventory of the dot's repos (`discoverSpecs` today; the profile specs of MULTI-REPO 2.3 once R2 lands), so the designer can point a case at a spec that already covers it.
|
|
97
|
+
- The repo profile area that matches the ticket (MULTI-REPO 2.7, ticket review by area), when profiles exist: routes, flows, glossary.
|
|
98
|
+
- The ticket's current cases, when this is an update.
|
|
99
|
+
|
|
100
|
+
### 3.3 Output: one case, three forms
|
|
101
|
+
|
|
102
|
+
Each case has a manual form, which always exists, and up to two executable forms.
|
|
103
|
+
|
|
104
|
+
| Form | Written when | Runs where | Stored as |
|
|
105
|
+
|---|---|---|---|
|
|
106
|
+
| Manual | At design time | By a person, ticked in the sticky PR checklist or on the case | `TestCase.steps`, `expected`, `data`; rendered on the ticket's `test_plan` page |
|
|
107
|
+
| AI-Vision | At design time for `e2e` cases | `src/runner/aivision` in `pr_check` and `post_merge` when `runner.aivision` is set | `TestCase.aivision` (`AiVisionCase`, `source: 'ticket'`, `itemId` = case id) |
|
|
108
|
+
| Generated Playwright | Planned at design time; generated at the first change review that has a running app | `src/runner/pwgen` (PR #9) | `TestCase.playwright`: status, kept source, and later the repo path |
|
|
109
|
+
|
|
110
|
+
The Playwright form waits for a running app because pwgen's explore step opens the app and records ARIA snapshots and `data-testid` values before it writes a spec. A new feature has no pages to explore until a PR builds it. The designer therefore writes the case as a plan item in the shape pwgen reads (`QaTestToRun`: scenario, steps, expected, data, priority, type), and generation happens in the first `pr_check` that names the ticket and has a preview URL or `baseUrl` (section 4.4).
|
|
111
|
+
|
|
112
|
+
One exception: a bug ticket describes behavior that already exists. With `designer.reproduce` on, the designer runs the Playwright form against the dot's `baseUrl` at design time. A kept failing spec confirms the bug, posts a "Reproduced" step on the timeline, and becomes the regression test for the fix. A passing spec adds an open question ("Could not reproduce on <baseUrl>; which data or account shows it?"). Default off, because it runs a model-written spec against a shared environment.
|
|
113
|
+
|
|
114
|
+
When an existing spec already covers a case, the designer sets `existingTest` to its path and writes no executable form.
|
|
115
|
+
|
|
116
|
+
### 3.4 Case rules
|
|
117
|
+
|
|
118
|
+
The designer's output passes script checks before it is stored, the same pattern as `check.ts` in the QA review. A failed check goes back to the model once with the numbered errors, then the case is dropped with the reason on the run.
|
|
119
|
+
|
|
120
|
+
- Each case names what it covers: an acceptance criterion (quoted) or a test idea from the analyst. A case that covers nothing is dropped.
|
|
121
|
+
- `expected` is observable: a value, a message, a page, a state. "Works correctly" and "no errors" fail the check.
|
|
122
|
+
- No two cases share the same covers entry and the same steps.
|
|
123
|
+
- A case that depends on an open question carries `waitsOn` with the question text and stays `draft` until the ticket changes.
|
|
124
|
+
- At most `designer.maxCases` cases per ticket (default 8), must before should before could.
|
|
125
|
+
- New cases go into a folder per ticket (KAT-382, `ticketFolder` in `src/case-folders.ts`): "PROD-123: Short title" under a top folder named after the tracker project ("PROD"); a GitHub issue gets "#12: Short title" under a folder named "owner/name". The title is cut at a word, at most 50 characters. A re-design finds the folder by its key ("PROD-123:" at the start of the name), wherever a person moved or renamed it, and makes none when it adds no case. The folder of a GitHub issue stores the issue's repo (`repo`, lower case, KAT-398) and is found by repo plus number, so a "#12" folder that a person moved into Archive is never reused for "#12" of another repo. An older folder with no repo is filled at boot from the keys of its cases; one that has no such case is taken only when it is the single candidate and sits in no other repo's folder, and the repo that takes it stamps it. Only the cases the designer stores now get the folder: a case a person moved stays where it is. When the folder cannot be made (the dot's 500 folder limit or the nesting limit), the case is stored unfiled and the design still succeeds.
|
|
126
|
+
- Prompt safety follows the AI-Vision and pwgen rules (docs/SANDBOX.md): ticket text is untrusted, braces and doubled angle brackets in steps are neutralized, start URLs are paths.
|
|
127
|
+
|
|
128
|
+
Evals (KAT-165): `test/fixtures/designer/<name>/` holds `ticket.json` (with the cases the dot already has), `review.json` (the analyst's handoff), and `expected.json` (the criteria a good set covers and the case limits). `src/review/designer-eval.ts` scores criteria coverage (an expected result names the criterion id or shares enough of its keywords), duplicates (the same normalized steps, or a repeat of an existing case), unobservable expected results (`VAGUE_EXPECTED`), and case count, and reports problems in the style of the dogfood cases. `npm test` scores the mock backend for every fixture with fixed thresholds (coverage at least 80%, no duplicates, no unobservable results) and spends no tokens. `npm run eval:designer -- --backend <name>` runs a real model on the same fixtures and is never part of CI.
|
|
129
|
+
|
|
130
|
+
### 3.5 Updates
|
|
131
|
+
|
|
132
|
+
A `ticket_updated` event re-runs the analyst, which hands off to the designer again. The designer receives the current cases and returns a revision: unchanged cases keep their ids, edited cases get a new `revision`, and cases that no longer fit become `retired`. A case with results is never deleted, so the timeline and the guard keep its history. Cases a person added or edited (`origin: 'user'`) are never retired or rewritten by the model; the designer may add a note next to them.
|
|
133
|
+
|
|
134
|
+
### 3.6 The test plan page
|
|
135
|
+
|
|
136
|
+
Each ticket gets one `ReportPage` of kind `test_plan`, titled "Test cases: SHOP-12 Guest checkout coupon". The case table is the source of truth and the page is rendered from it on every change. People edit cases in the case drawer on the dot page or through chat, where an edit shows as a proposal card with Apply and Dismiss. Free notes go on a child page (`parentId`). This avoids parsing Markdown edits back into cases.
|
|
137
|
+
|
|
138
|
+
### 3.7 Rules for its actions
|
|
139
|
+
|
|
140
|
+
Writing cases and the page stays inside localdost, so it needs no gate. Three outward actions do:
|
|
141
|
+
|
|
142
|
+
| Action | Default | When |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `ticket_comment` | `ask` | `designer.postSummary` on: one comment on the ticket with the case titles and a link to the page. Off by default |
|
|
145
|
+
| `open_pr` | `act_when_asked` | Kept generated specs proposed into the repo, as pwgen does today (PR #9, Proposing specs) |
|
|
146
|
+
| `mcp_tool` | `ask` | Later: sync cases to a test management tool such as Katalon True Platform through an MCP connection |
|
|
147
|
+
|
|
148
|
+
### 3.8 Impact on existing tests (KAT-304)
|
|
149
|
+
|
|
150
|
+
A new story can change what a test the team already has should show. The designer in 3.5 only reads the cases linked to the ticket, so it never sees that an old case, written for another ticket, now expects the wrong value. After every ticket review the dot therefore checks the tests it already has, whichever ticket they came from. The check lives in `src/impact/` and `src/flows/impact.ts`, and runs inside the `ticket_review` flow before the review comment is drafted, so the comment can list the specs to update. It is best effort: a failure leaves a warning step and the review goes on.
|
|
151
|
+
|
|
152
|
+
**1. Find candidates** (`src/impact/find.ts`, no model call). A candidate is a case or a spec that may be about the same behavior as the ticket.
|
|
153
|
+
|
|
154
|
+
| Signal | Cases | Specs |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| Shared requirement | The case links the ticket, a ticket its text names, or a ticket linked to it | A spec title or comment names one of those tickets |
|
|
157
|
+
| Folder or suite | The case sits in a folder, or is in a suite, whose name the ticket uses (a folder "Checkout" for a ticket about checkout), and shares a word with the ticket | |
|
|
158
|
+
| Shared words | The title and steps share three words with the ticket, or two when they are a third of the title | The spec title shares two words with the ticket |
|
|
159
|
+
| Trace-map page | The case links a requirement on a page the ticket is about, or names a spec that tests it | The trace map's tests on those pages; the repo scan's specs that open a route the ticket names |
|
|
160
|
+
|
|
161
|
+
A page counts as "about the ticket" when one of its requirements is the ticket or a ticket related to it, when the ticket names its route, or when its first path segment is a word of the ticket. The spec of every candidate case is a candidate too. Retired cases never count. At most 12 cases and 6 specs go on, best score first. The check counts the cases and specs that matched but were over the cap, keeps the count on the run (`impact.leftOut`), and says it after the summary line: "6 existing tests checked: 2 need an update, 4 are still valid. 3 more matched and were left out." The sentence is absent when nothing was left out.
|
|
162
|
+
|
|
163
|
+
**2. Classify** (`src/impact/classify.ts`). One model call gets the ticket and all candidates, and answers per candidate:
|
|
164
|
+
|
|
165
|
+
| Verdict | Meaning | Extra fields |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `valid` | The ticket does not change what it checks, or the model cannot tell | `note` |
|
|
168
|
+
| `update` | A value, rule, message, or step changes and the test stays useful | `ticketLine` (the line that causes it), all steps of the new version with expected results, `note` |
|
|
169
|
+
| `obsolete` | The ticket removes or replaces the behavior | `ticketLine`, `note` |
|
|
170
|
+
|
|
171
|
+
Every answer passes `settle()`, which never guesses: low confidence, a ticket line the ticket does not hold, steps that break the case rules (3.4), steps equal to the old ones, or no answer at all end as `valid` with a note. A spec is never obsolete; it needs an update. The mock backend uses a fixed rule instead of a model: a line that gives an old and a new value ("from 10% to 20%", "20% instead of 10%", "replace 10% with 20%") makes a case `update` when a step holds the old value, and the steps carry the new value. A line with a removal word ("remove", "retire", "replace", "no longer offered") that names most of a case's title words makes it `obsolete`. Anything else is `valid`, with low confidence when the ticket has fewer than 15 meaningful words.
|
|
172
|
+
|
|
173
|
+
**3. Act** (`src/impact/store.ts`). Nothing is retired or rewritten on its own.
|
|
174
|
+
|
|
175
|
+
| Verdict | What the dot does | Who decides |
|
|
176
|
+
|---|---|---|
|
|
177
|
+
| `update`, case | Writes a draft case version: the case as it is, with the new steps, linked to the new ticket as well. The case keeps its current version and history; a test run keeps pinning the current version | A person accepts it on the Test cases page or the ticket review (the draft becomes the next version, the old one stays in the history) or rejects it |
|
|
178
|
+
| `obsolete`, case | Puts a `case_retire` draft in the Inbox. The kind always asks, whatever the dot's rules say (`effectiveLevel`); only `hand_off` is kept | A person approves (the case is retired, its results stay) or rejects it |
|
|
179
|
+
| `update`, spec | Lists it under "Automated tests to update" in the ticket comment and the ticket review page | A person changes the spec in the repo, then marks it updated or dismisses it |
|
|
180
|
+
| `valid` | Stores the row with its note | |
|
|
181
|
+
|
|
182
|
+
A flagged case shows **Needs review** in test runs (run item rows and the item sheet) and in the case table until the draft is decided, or the Inbox draft is rejected or expires. An accepted row is never reopened by a later review of the same ticket. A rejected row stays rejected while the ticket text (title, description, acceptance criteria) hashes the same as the text the row was checked against (`ticketHash`); when the ticket text changed, the next review checks that test again and may draft again. An open flag is not replaced by a later "still valid".
|
|
183
|
+
|
|
184
|
+
**4. Report.** The ticket comment gets two headings when something is flagged: "Existing test cases to review" and "Automated tests to update" (each spec as a titled link to the file). The run page shows an "Existing tests" section and the Test cases page shows the same list (filtered by the ticket when the requirement filter is set; otherwise the rows that wait for a person). Each row is a status icon and word (Needs update, Obsolete, Still valid, then Accepted, Rejected, Retired, Updated, Dismissed, Not decided), the case or spec and the ticket as titled chips, and the ticket line that causes the change. The PR review lists a spec under Tests to update when a PR for the ticket (a PR that closes or references it, as the traceability links hold) does not change the spec: "Update the test <title> for SHOP-40: ..." with "This PR does not change that test." under it. Ticking it on GitHub records like any other checklist item.
|
|
185
|
+
|
|
186
|
+
The data is in [DATA-MODEL.md](DATA-MODEL.md) section 2.3 (Impact row). Evals: `test/fixtures/designer/impact/` holds four stories (a coupon rule changes, a feature is removed, an unrelated story, a vague story), run by `test/impact.test.ts`.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 4. Handoff data model
|
|
191
|
+
|
|
192
|
+
### 4.1 The chain
|
|
193
|
+
|
|
194
|
+
```text
|
|
195
|
+
Ticket SHOP-12
|
|
196
|
+
| tests (source designer)
|
|
197
|
+
v
|
|
198
|
+
Cases tc_a .. tc_f ----------------------------+
|
|
199
|
+
| PR #58 names SHOP-12 (closes / references) |
|
|
200
|
+
v |
|
|
201
|
+
pr_check run -> case_results (engine, result) |
|
|
202
|
+
| merge |
|
|
203
|
+
v |
|
|
204
|
+
post_merge run -> case_results |
|
|
205
|
+
| failed on both retries |
|
|
206
|
+
v |
|
|
207
|
+
Defect SHOP-31 -- defect link (meta caseId) ---->+
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Every edge already has a home or gets one small addition:
|
|
211
|
+
|
|
212
|
+
| Edge | Stored in | Status |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| PR to ticket | `links`, kinds `closes` and `references` (`recordPrLinks`) | Exists |
|
|
215
|
+
| Issue to issue | `links`, kinds `references`, `parent`, `blocks` (`recordIssueTimeline`) | Exists |
|
|
216
|
+
| Case to ticket | `links`, kind `tests`, new source `designer` | New source value |
|
|
217
|
+
| Run to case | `case_results` table | New |
|
|
218
|
+
| Defect to ticket | `links`, new kind `defect`, `meta: { caseId, runId }` | New kind |
|
|
219
|
+
| Run to stage | `RunRecord.stage` | New field |
|
|
220
|
+
|
|
221
|
+
Refs follow `LinkRecord`: lower-case `owner/name#N` for GitHub, the key for Jira and Linear. A case ref is `case:<id>`.
|
|
222
|
+
|
|
223
|
+
### 4.2 Types
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
// src/types.ts (add only)
|
|
227
|
+
|
|
228
|
+
export interface TestCase {
|
|
229
|
+
id: string; // tc_<12 hex>
|
|
230
|
+
watchId: string;
|
|
231
|
+
ticketRef: string; // same form as LinkRecord refs
|
|
232
|
+
title: string;
|
|
233
|
+
type: QaTestType; // e2e | integration | unit | manual | exploratory
|
|
234
|
+
priority: QaPriority; // must | should | could
|
|
235
|
+
/** Acceptance criteria (quoted) or analyst test ideas this case checks. */
|
|
236
|
+
covers: string[];
|
|
237
|
+
preconditions?: string;
|
|
238
|
+
steps: string[];
|
|
239
|
+
expected: string;
|
|
240
|
+
data?: string;
|
|
241
|
+
/** An existing spec covers it: "path" or "owner/name:path". No executable form is written. */
|
|
242
|
+
existingTest?: string;
|
|
243
|
+
aivision?: AiVisionCase;
|
|
244
|
+
playwright?: {
|
|
245
|
+
status: 'planned' | 'kept' | 'discarded' | 'proposed' | 'in_repo';
|
|
246
|
+
/** Kept source, until the spec lives in the repo. */
|
|
247
|
+
source?: string;
|
|
248
|
+
/** Repo path once a proposal merged. */
|
|
249
|
+
path?: string;
|
|
250
|
+
reason?: string;
|
|
251
|
+
generatedInRun?: string;
|
|
252
|
+
};
|
|
253
|
+
status: 'draft' | 'active' | 'retired';
|
|
254
|
+
origin: 'designer' | 'user' | 'reviewer';
|
|
255
|
+
/** The open question this case waits on. */
|
|
256
|
+
waitsOn?: string;
|
|
257
|
+
revision: number;
|
|
258
|
+
/** The ticket's test_plan page. */
|
|
259
|
+
reportId?: string;
|
|
260
|
+
designRunId: string;
|
|
261
|
+
createdAt: string;
|
|
262
|
+
updatedAt: string;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface CaseResult {
|
|
266
|
+
id: string;
|
|
267
|
+
caseId: string;
|
|
268
|
+
runId: string;
|
|
269
|
+
stage: StageKey;
|
|
270
|
+
/** QaEngine from PR #9 ('spec' | 'playwright' | 'aivision'), or a person's tick. */
|
|
271
|
+
engine: QaEngine | 'manual';
|
|
272
|
+
result: 'passed' | 'failed' | 'flaky' | 'skipped' | 'not_run';
|
|
273
|
+
prRef?: string;
|
|
274
|
+
sha?: string;
|
|
275
|
+
at: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface LinkRecord {
|
|
279
|
+
kind: /* existing */ | 'defect';
|
|
280
|
+
source: /* existing */ | 'designer' | 'defect';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export interface QaTestToRun {
|
|
284
|
+
// existing fields unchanged
|
|
285
|
+
/** The ticket case this item runs. Set by the reviewer for behavior a case already covers. */
|
|
286
|
+
caseId?: string;
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Tables in `src/db.ts`: `test_cases` (one row per case, latest revision) and `case_results` (append only, indexed by `caseId` and `runId`).
|
|
291
|
+
|
|
292
|
+
### 4.3 How a handoff happens
|
|
293
|
+
|
|
294
|
+
A handoff is a queued job with a marker in its payload. `handoff(from, to, subject)` in `src/stages/index.ts`:
|
|
295
|
+
|
|
296
|
+
1. Skips when the target stage is off for the dot, and writes "Test designer is off; the Change reviewer uses the analyst's test ideas" on the source run.
|
|
297
|
+
2. Enqueues the target job with `payload.handoff = { from, runId, ticketRef, revision }` and dedupe key `handoff:<to>:<ticketRef>:<revision>`, so one ticket revision gets one design.
|
|
298
|
+
3. Adds a step on both runs: "Handed to Test designer" and "From Ticket analyst".
|
|
299
|
+
|
|
300
|
+
| From | To | When | What passes |
|
|
301
|
+
|---|---|---|---|
|
|
302
|
+
| Ticket analyst | Test designer | The review finished at or above `SCORE_FLOOR` | Ticket ref and revision, the analyst run id (its verdict holds ideas, questions, code hits) |
|
|
303
|
+
| Test designer | Change reviewer | A `pr_check` names the ticket: `ticketKeysIn(ev)` or a `closes` link | Active cases of each named ticket, read from `test_cases` at run time |
|
|
304
|
+
| Change reviewer | Regression runner | The PR merges | The PR review at the same head (`findReviewedRun`, exists) and the cases it ran |
|
|
305
|
+
| Regression runner | Release guard | Every `post_merge` and every defect | `case_results` and `defect` links, read at check time |
|
|
306
|
+
| Prod watcher | Release guard | An outage on a dot with an open milestone | The incident page, listed on the readiness report |
|
|
307
|
+
|
|
308
|
+
The first handoff queues a job. The others are reads at run time: the Change reviewer looks up cases when a PR names a ticket, and the guard reads results when it runs. This keeps stages independent: turning one off never leaves a queue of handoffs waiting for it.
|
|
309
|
+
|
|
310
|
+
### 4.4 Change reviewer reuse
|
|
311
|
+
|
|
312
|
+
When a PR names tickets that have cases:
|
|
313
|
+
|
|
314
|
+
- The reviewer input gets a `<ticket_cases>` block: id, title, type, steps, expected, and the executable forms. For behavior a case already covers, the reviewer cites the case by `caseId`. A check flags a `whatToTest` item that repeats a case's covers entry without the `caseId`.
|
|
315
|
+
- Cases with `existingTest` or a Playwright form `in_repo` join the spec pick (`selectQaSpecs`).
|
|
316
|
+
- A Playwright form `planned` goes to pwgen as a plan item, ahead of review items, within `pwgen.maxSpecs`. A `kept` form runs from its stored source through pwgen's spec runner without a new model call, after the spec safety checks run again on that source. A kept spec that later fails for its own reason (a locator drifted) gets pwgen's single heal, which may not change expected values.
|
|
317
|
+
- AI-Vision forms replace the ticket's raw test ideas in `planAiVisionCases`. `ticketIdeasFor` stays the fallback for tickets with no cases.
|
|
318
|
+
- Built (KAT-166): for each ticket the event names, `planAiVisionCases` writes one `AiVisionCase` per draft or ready case (never retired), ready before draft, then must before should before could, inside `maxCases`. Each action becomes an `ai` step and each expected result an `aiAssert` step. The case id is the AiVisionCase id and `itemId`, so the result file `aivision/<case id>.yaml` links back through `linkRunResults` as a result with engine `aivision`, and the case shows it as its latest result. A ticket with no draft or ready case keeps its raw ideas.
|
|
319
|
+
- Manual cases appear in the sticky comment checklist under "From SHOP-12". A tick by someone with write access (`applyChecklistEdit`) writes a `manual` case result.
|
|
320
|
+
- `runner.engine` (PR #9) still decides which engine runs an item without an existing spec: `auto`, `playwright`, `aivision`, or `both`.
|
|
321
|
+
- Every result for a case-backed item writes a `case_results` row.
|
|
322
|
+
|
|
323
|
+
A PR that names several tickets runs their cases up to `reviewer.maxTicketCases` (default 12), must first, spread across tickets.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## 5. Rules, model, and toggles per stage
|
|
328
|
+
|
|
329
|
+
### 5.1 Config
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
// src/types.ts (add only)
|
|
333
|
+
|
|
334
|
+
export interface StageConfig<O = Record<string, never>> {
|
|
335
|
+
enabled: boolean;
|
|
336
|
+
/** Overrides Watch.rules for actions this stage drafts. */
|
|
337
|
+
rules?: Partial<Record<ActionKind, RuleLevel>>;
|
|
338
|
+
/** Unset: the workspace backend and the stage's default tier. */
|
|
339
|
+
model?: { backend?: 'claude-cli' | 'codex-cli' | 'anthropic'; tier?: 'main' | 'fast' };
|
|
340
|
+
/** Added after the dot's instructions, for this stage only. */
|
|
341
|
+
instructions?: string;
|
|
342
|
+
options?: O;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export interface Watch {
|
|
346
|
+
// existing fields unchanged
|
|
347
|
+
stages?: {
|
|
348
|
+
analyst?: StageConfig<{ scoreFloor?: number; maxQuestions?: number }>;
|
|
349
|
+
designer?: StageConfig<{ maxCases?: number; forms?: ('manual' | 'aivision' | 'playwright')[]; reproduce?: boolean; postSummary?: boolean }>;
|
|
350
|
+
reviewer?: StageConfig<{ maxTicketCases?: number }>;
|
|
351
|
+
regression?: StageConfig<{ caseScope?: 'merged_tickets' | 'none' }>;
|
|
352
|
+
watcher?: StageConfig;
|
|
353
|
+
guard?: StageConfig<{ milestones?: string[]; daysBeforeDue?: number; hour?: number }>;
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Existing settings stay where they are, because the types contract is add-only: `Watch.review` remains the Change reviewer's review options, `runner.engine`, `runner.pwgen`, and `runner.aivision` remain the run engines, and `probes`, `statusPages`, `probeIntervalSec` remain the Prod watcher's targets. The stage settings UI shows them under their stage.
|
|
359
|
+
|
|
360
|
+
### 5.2 Toggles
|
|
361
|
+
|
|
362
|
+
Jobs reach the queue on two paths, and both check the stage. Webhooks and the GitHub, Jira, and Linear pollers go through `dispatchTrigger`, which asks `stageFor` and, when that stage is off for the dot, queues nothing and returns `stage off: reviewer`. Probes and status pages call `enqueue` directly (`src/monitor/probes.ts` for `outage` and `recovery`, `src/monitor/statuspage.ts` for `outage`), so the Prod watcher toggle also lives there: the probe scheduler and the status page poller skip a dot whose watcher is off, and no probe checks run for it. The pollers keep their cursors, so turning a stage back on resumes from the present without replaying old events.
|
|
363
|
+
|
|
364
|
+
### 5.2.1 Built (KAT-161, server side)
|
|
365
|
+
|
|
366
|
+
`Watch.stages` is `Partial<Record<StageKey, { on: boolean; rules?: string }>>`, in `src/stages/config.ts`. This first build keeps the stage config to the switch and one block of rules text. The `model`, `instructions`, and `options` fields of 5.1 come with later tasks.
|
|
367
|
+
|
|
368
|
+
- **Migration.** `migrateStages()` runs at boot after the repo migration. It fills only the keys a dot lacks, so it is safe to run again and never overwrites a saved choice. The derivation: a tracker turns the analyst and the designer on, a repo (or repo set) turns the reviewer and the regression runner on, probes or status pages turn the watcher on, and the guard stays off. A stage with no saved entry (a dot created after boot, before its first save) runs as it did before stages, except the guard, which stays off.
|
|
369
|
+
- **Skip with a reason.** `dispatchTrigger` checks `stageOn` per dot. An off stage queues nothing, adds the reason `stage off: <stage>` to the result (`skipped`, and `reason` when every matching dot skipped), stores the trigger in an `events` row with `skipped` set (one row per delivery), and logs it. The probe scheduler and the status page poller skip a dot whose watcher is off and log it once per dot until the dot is saved again.
|
|
370
|
+
- **Rules.** `renderWatch(watch, stage)` adds `rules for the <label> stage: ...` to the `<watch>` block of the prompt. Without an argument it takes the stage of the job running in that async context (a rerun takes the stage of its source run), so every prompt built inside a job gets its own stage's rules and no other. `mustNot` stays dot-level. Resolving the action level of `gate()` per stage (5.3) is not built.
|
|
371
|
+
- **API.** `PATCH /api/dots/:id` and `POST /api/dots` accept `stages`. Keys must be stage keys, each entry an object with a boolean `on` and optional `rules` text up to 4000 characters; other fields are refused with a 400 and nothing is saved. A patch merges per stage, and a patch that leaves `rules` out keeps the saved rules. An empty `rules` string removes them.
|
|
372
|
+
|
|
373
|
+
### 5.3 Rules
|
|
374
|
+
|
|
375
|
+
`gate()` resolves a level in this order: `stages[stage].rules[kind]`, then `Watch.rules[kind]`, then `DEFAULT_RULES[kind]`. The stage comes from the run (`RunRecord.stage`). `mustNot` stays dot-level and binds every stage. Auto-review sees the stage name, so a draft from the guard is judged as a readiness report.
|
|
376
|
+
|
|
377
|
+
| Stage | Actions it drafts | Defaults that differ from `DEFAULT_RULES` |
|
|
378
|
+
|---|---|---|
|
|
379
|
+
| Ticket analyst | `ticket_comment`, `push_notify`, `report_edit` | None |
|
|
380
|
+
| Test designer | `ticket_comment`, `open_pr`, `mcp_tool` | None |
|
|
381
|
+
| Change reviewer | `run_tests`, `check_run`, `pr_comment`, `push_notify`, `file_defect`, `open_pr` | None |
|
|
382
|
+
| Regression runner | `run_tests`, `check_run`, `push_notify`, `slack_post`, `file_defect`, `revert` | None |
|
|
383
|
+
| Prod watcher | `push_notify`, `slack_post`, `revert` | None |
|
|
384
|
+
| Release guard | `report_edit`, `slack_post`, `push_notify`, `ticket_comment` | `report_edit: act` for its own readiness page |
|
|
385
|
+
|
|
386
|
+
The guard reports coverage and results per requirement. Its wording follows the QA report style already in force: what was tested, what failed, what has no cases. It never says release or hold.
|
|
387
|
+
|
|
388
|
+
### 5.4 Model per stage
|
|
389
|
+
|
|
390
|
+
`getLlmFor(watch, stage)` replaces `getLlm()` in stage flows. It returns a cached instance per backend, so two stages on the same backend share one. The tier maps to the backend's main and fast model settings (`LOCALDOST_MODEL` and `LOCALDOST_FAST_MODEL`, the Claude CLI pair); a backend with one model setting ignores the tier. Demo mode keeps the mock backend for every stage.
|
|
391
|
+
|
|
392
|
+
| Stage | Model calls | Default tier |
|
|
393
|
+
|---|---|---|
|
|
394
|
+
| Ticket analyst | `score` (fast), `analyze` | main |
|
|
395
|
+
| Test designer | Design, one check round; pwgen generate and heal | main |
|
|
396
|
+
| Change reviewer | QA reviewer, verifier, `analyze`, auto-review (fast) | main |
|
|
397
|
+
| Regression runner | `analyze` | main |
|
|
398
|
+
| Prod watcher | `analyze` for the suspected cause | main |
|
|
399
|
+
| Release guard | One summary over deterministic counts | fast |
|
|
400
|
+
|
|
401
|
+
`QaReviewPass` already records backend and model per pass; the stage name joins it so the eval and cost views split by stage.
|
|
402
|
+
|
|
403
|
+
Built in KAT-162. `Watch.stageModels` holds one switcher-list id per stage (`claude-cli`, `codex-cli`, `claude-token`, `anthropic`), validated against the stage keys and those ids by `PATCH /api/dots/:id` (a stage sent as `null` is cleared, other stages stay). `getLlmFor(watch, stage)` in `src/agent/llm.ts` returns the stage's backend when it is set and ready, and the dot's default model (`getLlm()`) otherwise. The stage model never fails a job:
|
|
404
|
+
|
|
405
|
+
- A model that is not signed in, is not on the list, or waits after a quota, spend cap, rate limit, or sign-in error falls back to the default, with a log line and a "Stage model unavailable" warn step on the run.
|
|
406
|
+
- A stage model that fails with one of those errors in the middle of a call is marked unavailable (the same wait as the model guard) and the call runs again on the default.
|
|
407
|
+
- Demo mode (the mock default) and a stage set to the default's own backend use the default.
|
|
408
|
+
- Chat and the safety review (auto-review) always use the default. A call with no stage is `getLlm()`.
|
|
409
|
+
- Call sites: ticket review, test design (the cases and the impact check), the change reviewer's PR review passes (`qaBackendForStage` in `src/review/run.ts`), the post-merge, CI-failure, and rerun verdicts, generated Playwright specs, and the outage verdict. The stage is the run's (`runStage`). The digest has no stage.
|
|
410
|
+
- `RunRecord.model` holds the model of the last model call of the run as `backend/model` (for example `claude-cli/sonnet`, `anthropic/claude-sonnet-5-5`, `codex-cli/default`, `mock`). A guard fallback to another backend still shows as its own "Model fallback" step. The `model_calls` table (KAT-362, [Daily model cap](SETUP.md#daily-model-cap)) holds one row per answered call with the stage and the tokens a backend reported, which the Model use card of the dot page sums per stage.
|
|
411
|
+
- No tier mapping yet: a stage picks a backend, and the backend uses its main model setting. The stage settings UI is built in KAT-171 (section 5.5).
|
|
412
|
+
|
|
413
|
+
### 5.5 Built (KAT-171, stage settings UI)
|
|
414
|
+
|
|
415
|
+
The dot dialog (Settings on the dot page) has a Stages section after Sources. Code: `client/src/features/stages/`.
|
|
416
|
+
|
|
417
|
+
- **Rows.** One row per stage, in registry order: the stage avatar (64 px, off stages dimmed), the name, one sentence, and a labeled switch that reads On or Off. A visible Settings button opens the panel of the stage. A line under the sentence names the stage's own rules and its own model; a model that is not available on the server says so there too ("Not available. Uses the dot default."), because the stage then runs on the dot default. Nothing is disabled. An off stage keeps its panel editable, and the panel says the settings apply when the stage turns on. The stage names are h3 headings under the dialog's h2 title, and the settings groups inside a panel are h4. On a phone narrower than 381 px the Settings button and the switch move to a row of their own under the avatar and the text, so both keep their labels on one line.
|
|
418
|
+
- **Panel.** Rules (text, up to 4000 characters, saved as `stages[stage].rules`), Model (the model list of Setup, default "Dot default"; saved as `stageModels[stage]`, `null` for the default), and the settings that belong to the stage. A model that is not available on the server shows a hint that the stage uses the dot default until it is, as the server does.
|
|
419
|
+
- **Settings moved under their stage.** Change reviewer: the PR review options (`Watch.review`, saved with the dot; only the options a person changed are sent), the engine for new scenarios (`runner.engine`), and the AI-Vision switch. Prod watcher: probes, the probe interval, and status pages. The base URL moved to the Test runner section. The PR review card on Settings is gone, and the Test engines link on the dot page opens the dialog on the Change reviewer panel.
|
|
420
|
+
- **Role sets the stages.** The Role picker is the only preset picker, because a role preset is a set of stages (6.3). Picking a role sets the six switches and keeps the rules and the model a person wrote for a stage; the note under the picker says when the switches moved. Product area is the first role. A new dot starts on it with all six stages on and an empty brief, and a click on the chosen role fills the brief in a create (an edit never re-applies its saved role). The stage list has one summary line, such as "3 of 6 stages are on: ...", and no picker of its own.
|
|
421
|
+
- **Notice.** `migrateStages` sets `stagesNotice: 'offer'` on every dot that has not answered it and still has the Test designer or the Release guard off. That covers a dot with no stage settings and a dot whose settings the first stage migration (KAT-161) wrote. A dot made after the upgrade, through `POST /api/dots` (the quick New dot dialog, the full form, an API client), `localdost init`, `localdost seed`, or the demo seed, is born with `stagesNotice: 'dismissed'` and is never offered. A save that carries `stages` answers the offer for a dot that never had one, and leaves an open offer to the dialog. The dialog shows "New stages: Test designer and Release guard" (only the ones still off) with a Turn on button for each and Dismiss. Dismiss saves `stagesNotice: 'dismissed'` through `PATCH /api/dots/:id` at once, and shows the error in place when that fails. Turning a stage on changes the form, and the save then sends `dismissed` too, as does a save after the switches or a role left nothing to offer. A client may send only `dismissed`.
|
|
422
|
+
- **Save.** Every stage goes in each save (`stages` with `on` and `rules`, `stageModels` with a model or `null`), through the dot update route and its validation. A save error shows in the dialog's error summary and the changes stay. A field error inside a closed panel opens that panel, and so does a server refusal that names a stage (`stages.<stage>...`, `stageModels.<stage>...`, or a `review:` option, which opens the Change reviewer). A refusal that names no stage opens nothing.
|
|
423
|
+
- **Review options and a new repo.** The dot update route builds the saved review options from the dot as the save leaves it. A repo added in the same save as a changed review option keeps pull request review on (it is on by default for a dot with an app repo).
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## 6. Migration from role presets
|
|
428
|
+
|
|
429
|
+
### 6.1 What roles do today
|
|
430
|
+
|
|
431
|
+
A role preset (`src/routes/roles.ts`: `qa-lead`, `release-guard`, `ticket-reviewer`, `prod-watcher`, `custom`) only seeds the brief, instructions, rules, mascot, and digest hour in the create dialog. Jobs are routed by configuration: any dot with a repo gets `pr_check` and `post_merge`, any dot with a tracker gets `ticket_review`, and any dot with probes gets `outage`. The `release-guard` preset, for example, runs post-merge suites; it has no readiness logic.
|
|
432
|
+
|
|
433
|
+
### 6.2 Boot migration
|
|
434
|
+
|
|
435
|
+
`migrateStages()` in `src/stages/index.ts` runs at boot and is safe to repeat. For each dot without `stages`, it writes stages from configuration, so behavior after migration equals behavior before:
|
|
436
|
+
|
|
437
|
+
| Stage | On when |
|
|
438
|
+
|---|---|
|
|
439
|
+
| Ticket analyst | `tracker` is set |
|
|
440
|
+
| Test designer | Never on migration |
|
|
441
|
+
| Change reviewer | A repo is set |
|
|
442
|
+
| Regression runner | A repo is set |
|
|
443
|
+
| Prod watcher | `probes` or `statusPages` is non-empty |
|
|
444
|
+
| Release guard | Never on migration |
|
|
445
|
+
|
|
446
|
+
`Watch.role` stays as the preset label. Dots that predate the new stages get a one-time offer of them, built in KAT-171 as a notice in the dot dialog (section 5.5) rather than a row on the dot page. Rollback: an older build ignores `stages` and routes by configuration as before.
|
|
447
|
+
|
|
448
|
+
### 6.3 Stage presets
|
|
449
|
+
|
|
450
|
+
Presets become sets of stages with defaults. `RoleKey` has `product-area`, the first option in the create dialog and the default of the quick New dot dialog (its suggestion posts the Product area brief and all six stages on). `GET /api/roles` sends each preset with `defaults.stages`, which names all six stages, so applying a preset also switches the other stages off.
|
|
451
|
+
|
|
452
|
+
| Preset | Stages on | Mascot |
|
|
453
|
+
|---|---|---|
|
|
454
|
+
| Product area (new) | All six | pip |
|
|
455
|
+
| QA lead | Analyst, designer, reviewer, regression | pip |
|
|
456
|
+
| Release guard | Regression, guard | nova |
|
|
457
|
+
| Ticket reviewer | Analyst, designer | bolt |
|
|
458
|
+
| Prod watcher | Watcher | moss |
|
|
459
|
+
| Custom | None; the user picks | pip |
|
|
460
|
+
|
|
461
|
+
Each preset keeps today's brief text and rules. Product area reuses the QA lead brief and rules with one more clause for production. Stage-level rules are not built: the stage `rules` field is text for the prompt, and the guard's `report_edit: act` waits for the per-stage action levels of 5.3, so no preset sets a stage's rules yet.
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
## 7. Ticket timeline on the dot page
|
|
466
|
+
|
|
467
|
+
### 7.1 Tickets table
|
|
468
|
+
|
|
469
|
+
The dot page gains a Tickets section: one row per ticket in the dot's area, a status indicator, and a drawer. It extends the traceability view of MULTI-REPO 4.7 with the stage columns and works the same for Jira, Linear, and GitHub tickets.
|
|
470
|
+
|
|
471
|
+
```text
|
|
472
|
+
Tickets [Milestone: 2026.11 v] [Status: All v] [Stage: All v]
|
|
473
|
+
Ticket Stage now Cases PRs Defects Status
|
|
474
|
+
SHOP-12 Guest checkout coupon Regression runner 6 #58 1 closed (o) Passing
|
|
475
|
+
SHOP-15 Saved cards Change reviewer 4 #63 1 open (!) Failing
|
|
476
|
+
SHOP-18 Order history filter Test designer - - - ( ) Designing
|
|
477
|
+
SHOP-21 Gift wrap option Ticket analyst - - - (?) 2 questions
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Statuses extend MULTI-REPO 4.6: Not designed (no active cases), Designing, Waiting on questions, Not tested, Partly tested, Passing, Failing, Out of date. "Stage now" is the stage of the latest event.
|
|
481
|
+
|
|
482
|
+
### 7.2 Drawer timeline
|
|
483
|
+
|
|
484
|
+
```text
|
|
485
|
+
SHOP-12 Guest checkout coupon (o) Passing
|
|
486
|
+
Cases 6 (4 manual, 3 Playwright kept, 2 AI-Vision) Open test cases Open ticket
|
|
487
|
+
|
|
488
|
+
[lens] Oct 8 09:12 Ticket analyst Reviewed: 2 questions, 5 test ideas Open run
|
|
489
|
+
[penn] Oct 8 09:14 Test designer Wrote 6 cases, 1 waits on a question Open cases
|
|
490
|
+
[nit] Oct 9 14:03 Change reviewer PR #58 at 4f1c2a9: 5 passed, 1 failed Open run
|
|
491
|
+
[nit] Oct 9 14:05 Change reviewer Defect SHOP-31 filed: total off by one cent Open defect
|
|
492
|
+
[nit] Oct 9 17:40 Change reviewer PR #58 at 9be0d11: 6 passed Open run
|
|
493
|
+
[echo] Oct 10 10:20 Regression runner Merge 9be0d11: 6 passed Open run
|
|
494
|
+
[ward] Oct 12 08:00 Release guard 2026.11: SHOP-12 passing Open report
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Entries come from runs with a stage whose trigger names the ticket or whose PR links to it, case revisions, `case_results`, `defect` links, and approvals that wait on a person. Each entry has the stage avatar at 20 px, the time, the stage name, one sentence, and a labeled link. A case row opens the case drawer with its forms, its results per run, and Edit.
|
|
498
|
+
|
|
499
|
+
### 7.3 API
|
|
500
|
+
|
|
501
|
+
| Method and path | Purpose |
|
|
502
|
+
|---|---|
|
|
503
|
+
| `GET /api/dots/:id/tickets?milestone=&status=&stage=` | Rows of the Tickets table |
|
|
504
|
+
| `GET /api/dots/:id/tickets/:ref/timeline` | `TimelineEntry[]`, oldest first |
|
|
505
|
+
| `GET /api/dots/:id/cases?ticket=` | Cases of a ticket |
|
|
506
|
+
| `POST /api/dots/:id/cases` | Add a case by hand (`origin: 'user'`) |
|
|
507
|
+
| `PATCH /api/dots/:id/cases/:caseId` | Edit; bumps `revision`. 409 on a stale revision |
|
|
508
|
+
| `POST /api/dots/:id/tickets/:ref/design` | Queue `test_design` on demand. 409 when the designer is off |
|
|
509
|
+
| `POST /api/dots/:id/release-check` body `{ milestone? }` | Queue `release_check` on demand |
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
export interface TimelineEntry {
|
|
513
|
+
at: string;
|
|
514
|
+
stage: StageKey;
|
|
515
|
+
kind: 'review' | 'design' | 'run' | 'defect' | 'approval' | 'readiness' | 'incident';
|
|
516
|
+
title: string; // one sentence
|
|
517
|
+
status: 'ok' | 'warn' | 'error' | 'info';
|
|
518
|
+
runId?: string;
|
|
519
|
+
caseIds?: string[];
|
|
520
|
+
prRef?: string;
|
|
521
|
+
url?: string;
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Live events: `{ type: 'case'; case: TestCase }` joins `LiveEventV2`, so the drawer updates while the designer writes.
|
|
526
|
+
|
|
527
|
+
Mobile: at 390 px the table drops the PRs and Defects columns into the drawer, and timeline rows wrap to two lines with the avatar and time on the first. A visual check of both themes at 390x844 and 1280x800 is part of the UI tasks.
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## 8. Stage avatars
|
|
532
|
+
|
|
533
|
+
KAT-131 (PR #15) added six characters in the mascot style, mapped in `client/src/ui/mascotArt.ts` `STAGE_MASCOT`:
|
|
534
|
+
|
|
535
|
+
| Stage | Avatar | Cue |
|
|
536
|
+
|---|---|---|
|
|
537
|
+
| Ticket analyst | lens (sky) | Magnifier |
|
|
538
|
+
| Test designer | penn (pink) | Pencil |
|
|
539
|
+
| Change reviewer | nit (teal) | Diff tag with a green and a red line |
|
|
540
|
+
| Regression runner | echo (clay) | Loop arrow |
|
|
541
|
+
| Prod watcher | argus (slate) | Watching eye |
|
|
542
|
+
| Release guard | ward (indigo) | Shield with a check |
|
|
543
|
+
|
|
544
|
+
The dot keeps its own mascot (`pip`, `nova`, `bolt`, `moss`) as its identity. A stage avatar shows which specialist did the work:
|
|
545
|
+
|
|
546
|
+
- Feed rows: the stage avatar at 20 px next to the run title.
|
|
547
|
+
- Run detail header: the stage avatar and name next to the dot name.
|
|
548
|
+
- Inbox cards: the stage that drafted the action.
|
|
549
|
+
- Dot page: the stage list (64 px in settings, 20 px in rows) and the ticket timeline.
|
|
550
|
+
- Chat: tool cards that queue a stage job carry its avatar.
|
|
551
|
+
|
|
552
|
+
State per stage avatar, from the dot's runs:
|
|
553
|
+
|
|
554
|
+
| State | When |
|
|
555
|
+
|---|---|
|
|
556
|
+
| `running` | A job of that stage is running |
|
|
557
|
+
| `attention` | Its latest run ended `needs_attention`, `product_failure`, or `test_failure`, or one of its drafts waits in the Inbox |
|
|
558
|
+
| `outage` | Prod watcher: a probe is down. Other stages: the last three runs failed to run (`environment_failure` or `notRun`) |
|
|
559
|
+
| `ok` | Otherwise |
|
|
560
|
+
|
|
561
|
+
A stage that is off shows its avatar at reduced opacity with the label "Off". The avatar is never the only signal: the stage name and state text sit next to it.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## 9. Cost bounds and edge cases
|
|
566
|
+
|
|
567
|
+
| Item | Bound |
|
|
568
|
+
|---|---|
|
|
569
|
+
| Designer model calls | One per ticket revision, plus one check round. None in demo mode |
|
|
570
|
+
| Designer input | 24 KB: ticket, analyst verdict, matching area, spec titles of that area, current cases |
|
|
571
|
+
| Designer output | `maxCases` cases (default 8, at most 20) as JSON, checked by schema and the rules of section 3.4 |
|
|
572
|
+
| Generated specs per PR run | `pwgen.maxSpecs` (PR #9, default 3), ticket cases first |
|
|
573
|
+
| Ticket cases per PR run | `reviewer.maxTicketCases` (default 12) |
|
|
574
|
+
| Release guard | Deterministic counts plus one fast-tier summary per check |
|
|
575
|
+
|
|
576
|
+
Edge cases:
|
|
577
|
+
|
|
578
|
+
- A ticket the analyst scores below the floor gets no design. The timeline says "Too thin to design" and the ticket stays Not designed.
|
|
579
|
+
- A ticket reviewed by two dots gets two case sets, one per dot. Sharing cases across dots is out of scope.
|
|
580
|
+
- A PR that names a ticket outside the dot's tracker scope runs no cases for it; the link is still written.
|
|
581
|
+
- A retired case keeps its results. The guard counts only active cases.
|
|
582
|
+
- The designer off: the Change reviewer falls back to the analyst's test ideas for AI-Vision, as today.
|
|
583
|
+
- The analyst off: the designer runs only on demand from the dot page or chat, and reads the ticket itself.
|
|
584
|
+
- A person edits a case while the designer revises it: the designer's write fails on the revision check and retries once on the new revision; a user-origin case is never overwritten.
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## 10. Build tasks
|
|
589
|
+
|
|
590
|
+
Sizes: S is under half a day, M is one to two days, L is three days or more. Each row is one PR that passes review and CI on its own and leaves the product working. Dependencies in brackets.
|
|
591
|
+
|
|
592
|
+
| # | PR | Size | Notes |
|
|
593
|
+
|---|---|---|---|
|
|
594
|
+
| 1 | Built (KAT-159). Stage contract: `StageKey` moved to `src/types.ts`, `src/stages/index.ts` registry with `stageFor(kind, ev, rerunOf)` (labels, avatars, `ci_failure` by PR head, `rerun` from the source run), `RunRecord.stage` set in `startRun`, `stage` on the runs API. No new job kinds | S | No behavior change |
|
|
595
|
+
| 2 | Area scope: apply `pathFilters` in `watchMatches` for PR and push events | S | Independent. A dot without filters matches as today |
|
|
596
|
+
| 3 | Stage toggles and rules: `Watch.stages`, `migrateStages`, `dispatchTrigger` skips jobs of an off stage, the probe scheduler and status page poller skip dots whose watcher is off, `gate()` resolves stage rules, API validation | M | [1] Migration test on a copy of a real `localdost.db`: same jobs before and after |
|
|
597
|
+
| 4 | Model per stage: `getLlmFor(watch, stage)`, cache per backend, tier mapping, stage on `QaReviewPass` | M | [1] |
|
|
598
|
+
| 5 | Case store: `TestCase`, `CaseResult`, tables, case API, `tests` links with source `designer`, `test_plan` page renderer | M | [1] |
|
|
599
|
+
| 6 | Test designer, manual cases: `test_design` job kind with its labels, report kind, and handler, handoff from the analyst, prompt, schema and script checks, revision and retire rules, mock output, on-demand endpoint | L | [3, 5] |
|
|
600
|
+
| 7 | Designer evals: fixture tickets with expected cases; scores for criterion coverage, duplicates, and unobservable expectations; CI budget | M | [6] |
|
|
601
|
+
| 8 | AI-Vision form: `AiVisionCase` per e2e case; `planAiVisionCases` prefers designed cases over test ideas | S | [6] |
|
|
602
|
+
| 9 | Playwright form: planned items to pwgen at the first change review that names the ticket, kept source on the case, reuse without a new model call, `in_repo` after the proposal merges, `reproduce` for bug tickets | M | [6] and PR #9 merged |
|
|
603
|
+
| 10 | Change reviewer reuse: cases for named tickets, `<ticket_cases>` block, `QaTestToRun.caseId` and its check, manual cases in the sticky checklist, results to `case_results` | M | [6] Re-run `npm run eval:qa-review`; scores must not drop |
|
|
604
|
+
| 11 | Regression runner: `post_merge` runs active cases of the tickets the merge closes; defects carry `caseId` and write `defect` links | S | [10] |
|
|
605
|
+
| 12 | Release guard: `release_check` job kind with its labels, report kind, and handler, schedule and on-demand endpoint, readiness per requirement with the statuses of section 7.1, `readiness` page per milestone, report-only wording | M | [11] and MULTI-REPO A7 |
|
|
606
|
+
| 13 | Built (KAT-171, section 5.5). Stage settings UI: stage list in the dot dialog with toggles, rules, model, and options; stage presets with Product area first; migrated-dot notice | M | [3, 4] Screenshots of both themes at 390x844 and 1280x800 |
|
|
607
|
+
| 14 | Ticket timeline: tickets and timeline API, Tickets table and drawer on the dot page, case drawer, `case` live event | L | [5, 10] Screenshots of both themes |
|
|
608
|
+
| 15 | Stage avatars in Feed rows, run detail, Inbox cards, and chat tool cards, with the state mapping of section 8 | S | [1] |
|
|
609
|
+
| 16 | Chat tools: `design_tests(ticket)` and `list_cases(ticket)`, case edit proposal card | S | [6] and KAT-133 |
|
|
610
|
+
|
|
611
|
+
Task 11 is built (KAT-169, `src/flows/mergeCases.ts`) for the first half: a `post_merge` finds the active cases of the tickets its PR closes or references, records the results of automated ones through `linkRunResults`, adds manual ones as run items of one manual test run per merge (rerunning the merge adds none), and a defect drafted from the run carries `caseId` and `caseKey` in its meta and a case link in its body when the failing test maps to a case. Writing a `defect` links row on execution is not built yet.
|
|
612
|
+
|
|
613
|
+
### Order
|
|
614
|
+
|
|
615
|
+
1. Tasks 1, 2, 3, 4, and 15. After these, every run carries a stage, stages can be switched off, and the Feed shows who did the work.
|
|
616
|
+
2. Tasks 5, 6, 7, 8. First useful release: the designer writes manual and AI-Vision cases per ticket, and the Change reviewer runs the AI-Vision ones.
|
|
617
|
+
3. Tasks 10, 11, then 9 once PR #9 is merged. Second release: ticket cases run on every PR and merge that names the ticket, with generated Playwright specs.
|
|
618
|
+
4. Tasks 13, 14, 16.
|
|
619
|
+
5. Task 12 after MULTI-REPO A7.
|