# Auto-Oncall Live Initial Analysis

## Current Design

`POST /v1/tickets/analyze` is still the manual dry-run and historical replay
API. It accepts one Jira issue key or caller-provided ticket snapshot, builds a
replay workspace, runs Codex, and optionally previews or writes an internal Jira
comment through backend-owned gates.

There is no webhook or user-provided JQL. The automatic path is service-owned:
a Jira poller builds a fixed JQL query for active ST/TCID/APID/NAID/EMID issues,
stores initial-analysis jobs in MySQL/TiDB Cloud, and a worker claims jobs from
that table.

## Risks

- Duplicate analysis can happen if Jira polling overlaps or staging/prod are
both active.
- Jira internal comments must remain internal-only and idempotent.
- Dry-run replay workspaces must not gain current-status or future-context
inputs.
- The DB must be the canonical source of job state; workspace files are run
artifacts, not the job index.

## Target Contract

- Dry-run remains unchanged and keeps the replay workspace contract.
- Live automation is enabled only when
  `AUTO_ONCALL_AUTOMATION_ROLE=active` and
  `AUTO_ONCALL_POLL_ENABLED=true`.
- `auto_oncall_jobs` has a unique key on
  `(issue_key, trigger_kind, trigger_version)`, so v1 initial analysis is
  enqueued once per ticket.
- Worker claims jobs with a DB transaction and row lock, writes one live run,
  then writes or updates one Jira internal comment.
- Completed worker outcomes notify the Feishu group `Support Intelligence
  Campaign`. Retryable failures do not notify until they become permanent.
- Live Jira idempotency key is `auto-live:v1:<issueKey>:initial` and does not
  include the environment.
- Live workspaces include current status and updated time, do not create a
  replay target, and exclude prior auto-oncall/internal/support/bot comment
  bodies from model input.
- Automatic mode never writes customer-visible comments, transitions or closes
  issues, or executes production operations.

## Implementation Steps

1. Add fixed Jira search pagination and polling config.
2. Add MySQL/TiDB migration and store APIs for cursors, jobs, and runs.
3. Add live workspace and live runner output contract.
4. Add poller/worker runtime with retry, max-attempt, stale-running recovery,
   and idempotent Jira internal comment writes.
5. Add read-only query APIs for job and latest issue state.
6. Add Feishu notification for completed jobs through bot OpenAPI.
7. Wire staging active/prod disabled deployment configuration without storing
   secret values.

## Verification Checklist

- Unit tests for JQL cursor overlap, duplicate enqueue, retry/backoff, max
  attempts, and stale running recovery.
- Workspace tests proving live mode includes current status and has no
  replay-target file.
- API tests proving dry-run response shape remains unchanged and query APIs are
  read-only.
- DB integration through `AUTO_ONCALL_TEST_DATABASE_URL` for migration,
  uniqueness, row-lock claim, and recovery.
- Staging FT on an allowlisted Jira ticket before any prod activation.
- Feishu staging smoke test confirms the bot can send to `Support Intelligence
  Campaign`.

## Non-Goals

- No Jira webhook.
- No arbitrary JQL API.
- No staging/prod dual-active automation.
- No customer-visible Jira comments.
- No transition, close, or production operation execution.
- No dependency on parent repo code.
