# Reject Pause For Failed Changefeeds

## Analysis

| Area | Impact | Verification |
| --- | --- | --- |
| Biz changefeed pause | Reject pause when synced kernel state is `failed`, so the enclosing transaction rolls back and `operation_status` is not persisted as `paused`. | `go test ./app/models/biz_changefeed/impl -run TestBizChangefeedModelTestSuite/TestPauseKernelChangefeed` |
| Kernel changefeed pause | Treat only `stopped` as idempotent success. Return a parameter error for `failed`. | `go test ./app/models/ticdc/impl -run TestChangefeedModelRegionalImplTestSuite/TestPauseChangefeed` |
| Next-gen changefeed pause | Apply the same failed-state pause rejection in `dataflow-service-ng`. | `go test ./app/models/biz_changefeed/impl -run TestBizChangefeedModelTestSuite/TestPauseKernelChangefeed` and `go test ./app/models/ticdc/impl -run TestChangefeedModelRegionalImplTestSuite/TestPauseChangefeed` from `dataflow-service-ng/` |
| UI/API status aggregation | Expose kernel `failed/error` as `ERROR` even when business status is non-normal, including paused. | `go test ./app/models/domain -run TestBizChangefeed_GetConnectorStatus` in both modules |
| Existing stopped behavior | Keep `stopped` idempotent to preserve retry behavior. | Same focused tests above. |

## Execution Steps

1. Add a guard in biz changefeed pause after loading kernel metrics:
   - If kernel state is `stopped`, keep returning success.
   - If kernel state is `failed`, return `ErrCodeParams`.
   - Success criteria: failed state does not invoke `PauseChangefeed` on the kernel model.

2. Add a guard in regional kernel pause:
   - If kernel state is `stopped`, keep returning success.
   - If kernel state is `failed`, return `ErrCodeParams`.
   - Success criteria: failed state does not load the TiCDC cluster or call regional pause.

3. Update focused unit tests:
   - Add failed-state coverage for `pauseKernelChangefeed`.
   - Update `PauseChangefeed` regional test to expect an error for failed state.

4. Verify:
   - Run `go test ./app/models/biz_changefeed/impl -run TestBizChangefeedModelTestSuite/TestPauseKernelChangefeed`.
   - Run `go test ./app/models/ticdc/impl -run TestChangefeedModelRegionalImplTestSuite/TestPauseChangefeed`.
   - Run the same two focused tests from `dataflow-service-ng/`.
   - Run `go test ./app/models/domain -run TestBizChangefeed_GetConnectorStatus` in both modules.

## Risk

Low. The change only affects pause requests when the latest synced kernel state is already `failed`. Normal and already stopped pause paths remain unchanged.
