# AGENT.md

## 1. Overview

This repository is a **polyglot monorepo** containing:

* **Go** services (control plane, workers, infra-facing components)
* **Python** services (AI/LLM orchestration, evaluation, data processing)
* **TypeScript** applications (frontend, SDKs, tooling)

The repository is structured around **responsibility boundaries**, not programming languages.

---

## 2. Repository Structure

```text
repo/
  apps/              # User-facing or entry-point applications
  services/          # Deployable backend services
  packages/          # Shared libraries, contracts, SDKs
  infra/             # Deployment and infrastructure definitions
  scripts/           # Unified developer workflows
  docs/              # Architecture and design documentation
```

### 2.1 apps/

```text
apps/
  web/               # Main frontend (React / Next.js)
  admin-web/         # Internal tooling UI (optional)
  cli/               # CLI tools (TS or Go)
```

* Only contains **entrypoints**
* No business logic duplication
* Depends on `packages/` for shared logic

---

### 2.2 services/

```text
services/
  control-plane/     # Go API / orchestration layer
  worker/            # Go async processing
  diagnosis-engine/  # Python LLM / rule engine
  eval-engine/       # Python offline evaluation
  notification/      # Go notification / webhook service
```

Each service:

* Is independently deployable
* Has its own dependency management
* Communicates via API / RPC / queue (NOT code import)

---

### 2.3 packages/

```text
packages/
  contracts/         # API schemas (OpenAPI / protobuf / JSON schema)
  sdk-ts/            # TypeScript SDK
  sdk-go/            # Go SDK / client
  sdk-py/            # Python SDK
  ui/                # Shared UI components
  config/            # Shared config templates
  prompts/           # LLM prompt templates
  utils-*            # Language-specific utilities
```

This is the **core of the monorepo**.

Rules:

* Must be **language-agnostic where possible**
* Cannot depend on `apps/` or `services/`
* Must not contain business logic tied to a single service

---

### 2.4 infra/

```text
infra/
  docker/
  k8s/
  terraform/
  helm/
```

* Infrastructure definitions
* No application logic
* Referenced by CI/CD pipelines

---

### 2.5 scripts/

```text
scripts/
  bootstrap/
  lint/
  test/
  release/
```

Purpose:

* Provide **consistent developer experience**
* Avoid language-specific command fragmentation

---

## 3. Dependency Rules (Strict)

### Allowed

```text
apps        -> packages
services    -> packages
```

### Communication

```text
apps        -> services (via API)
services    -> services (via RPC / MQ)
```

### Forbidden

```text
packages    -> apps
packages    -> services (business logic)
services    -> import other services directly
```

---

## 4. Contract-First Development

All cross-service communication must go through:

```text
packages/contracts/
```

Supported formats:

* OpenAPI
* Protobuf
* JSON Schema

### Workflow

1. Define/update contract
2. Generate SDKs (TS / Go / Python)
3. Implement service logic
4. Consume via SDK (not manual types)

---

## 5. Design Principles

### 1. Separation of Concerns

Each directory represents a **clear responsibility boundary**

---

### 2. Contract as Source of Truth

No implicit interface definitions across languages

---

### 3. Polyglot, Not Fragmented

Languages coexist but do not fragment ownership

---

### 4. Minimal Shared Layer

Shared packages must remain **small and stable**

---

### 5. Independent Deployability

Every service should be deployable in isolation

---

## 6. Deployment And app-delivery

For services that keep app-delivery manifests in this repository, treat the
in-repo deployment directory as the source template.

Rules:

- Update the service-owned app-delivery template in this repository first.
- Use the repo GitHub Actions workflow to create the corresponding
  `tidbcloud/app-delivery` pull request when one exists.
- Do not make lasting manual edits directly in a local `app-delivery` checkout
  unless the same change is also reflected back into the source template here.
- Do not commit secret values to either repository.
- If a deployment references manually-created Kubernetes Secrets, the PR should
  only wire the Secret names and keys. The actual Secret objects and values are
  created operationally outside the PR.
- Do not add `ExternalSecret` resources unless the chosen deployment model is
  explicitly AWS Secrets Manager or another external secret store as source of
  truth.

For `auto-oncall-services`, the app-delivery source template lives under:

```text
auto-oncall-services/deploy/app-delivery/
```

The workflow for syncing it to `tidbcloud/app-delivery` is:

```text
.github/workflows/open-auto-oncall-app-delivery-registration-pr.yml
```


## 7. Unit Tests

Test Framework: standard `testing` plus `testify`

Mock Framework: Use `go.uber.org/mock` to generate mock classes.

Style:

- Prioritize using `go.uber.org/mock` to generate Mock classes for writing unit tests; do not start by manually writing a Mock class yourself.
- Write test cases that can be run in parallel.
- Leverage the capabilities of `testify` as much as possible to write concise test code.

## 7.1 Auto Oncall Single Ticket Optimizer

Before changing `services/auto-oncall-optimizer` single-ticket feedback trigger,
commands, terminal notification, investigation output, deterministic repair admission, or deployment wiring,
read `auto-oncall-services/docs/SINGLE_TICKET_OPTIMIZER.md` completely. That
document owns the boundary between a one-ticket engineering repair and a
Recent Focus candidate. Keep the new lane in the existing optimizer Deployment
and preserve `auto-oncall-services` as an independently deployable service with
no runtime dependency on the optimizer.

Single-ticket investigation chain fields and every non-historical finding describe
current `main` plus the fresh replay. One ticket may retain multiple independent
findings, but at most one stable-knowledge, deterministic-query, or locally
reproduced orchestration-fallback finding may be selected for repair. Diagnostic
strategy, external transient, roadmap/commercial, and global budget changes stay
outside automatic admission. Historical-only findings cannot be selected. A
classification-contract mismatch may receive one bounded same-thread correction;
a second mismatch fails closed before the write Agent.
Runtime candidate deduplication uses final `failureCodes` only to decide whether to
start the optimizer. The investigator must receive and inspect the full ordered
`providerQueryAttempts`; a corrected intermediate failure, supplemental-only failure,
or historical failure absent from the fresh replay is not a current finding.
Before that chain review, the investigator must independently compare the exact
nominated AI answer, the complete same-stage human answer, the version-bound human
feedback, and the fresh Judge result. The Judge is evaluation evidence rather than
an authority for diagnosis or chain classification. The controller binds both
answer fingerprints: the fresh Judge verdict is the current answer's evaluation
result and the investigator must not overwrite it. When the versions differ, old
feedback remains only on the nominated historical answer; the investigator records
separately whether that historical problem is reproduced by the current answer.
After the write Agent, one controller-owned full-test failure may be returned to
the same repair thread. That continuation may only finish tests or contracts
directly affected by the selected diff; a second full-test failure fails closed
and preserves the worktree. The continuation must retain every admitted changed
path and may add only directly affected files under `auto-oncall-services/test/`.
Automatic candidates include version-bound `wrong|revise`, `human_better`,
successful-run Provider degradation, and Router/Final timeout notices. Manual
`/ticket` selects the current latest answer; feedback candidates retain their
exact historical job and answer fingerprint. Both use the same fresh-replay
pipeline after that selection boundary.
The canonical Jira feedback prompt keeps a colon before its reason. Parser
compatibility also accepts `:`, `：`, `.`, `。`, and a legacy whitespace-only
separator when an exact `/ao wrong|revise` command occupies one complete
trimmed line.
For an admitted repair, CI is followed by controller-owned merge without human
review, exact-SHA staging deployment, post-change read verification, stable
internal Jira write replay, and a separate `optimized_verified` record PR. One
post-deployment continuation is allowed only for the same finding, owner, and
targets; any scope change or second failure requires a durable human notification.

---

## 8. Go SDK Infra Utils

`packages/sdk-go/infra/utils` contains shared, service-neutral helper packages for Go code.

When adding helper functions, **first check and reuse the existing implementations under `packages/sdk-go/infra/utils`**. Do not duplicate pointer helpers, collection transforms, set operations, timestamp conversions, signal handling, random string generation, or struct/map conversion logic in services or feature packages unless there is a concrete missing capability that should not be shared.

Available packages:

- `container/gmap`: thread-safe generic map with `Load`, `Store`, `LoadOrStore`, `LoadAndDelete`, `Delete`, and locked iterators for keys, values, or key/value pairs.
- `container/slice`: slice utilities such as transform, iterator transform/filter, slice-to-map conversion, `ForEach`, and a thread-safe generic slice wrapper.
- `container/set`: generic set implementation with construction from slices, membership checks, insert/delete, iteration, slice conversion, union, intersection, and difference.
- `container/pair`: typed pair and pair-list helpers with iterators over pairs, first values, and second values.
- `container/str`: string helpers including secure random lowercase alphanumeric strings and conversion helpers for custom string aliases.
- `object`: pointer/deref helpers, typed `any` dereference, deep copy, struct/map conversion, and JSON marshal-without-error helper.
- `time`: shared time helpers, including `ChinaTimeZone` and pointer-safe conversions between Unix timestamps and `time.Time`.
- `signals`: process signal handling for graceful shutdown on `SIGINT`/`SIGTERM`, with immediate exit on a second signal.

Guidelines:

- Prefer these packages for small reusable helper logic in Go services and SDK packages.
- If a helper is broadly useful and service-neutral but missing, add it under the appropriate `utils` package with focused tests.
- Keep `utils` free of service-specific business rules, API contracts, storage models, and external service dependencies.
