The PausedDuringWaitForReady and WaitsForWorkingAppState tests flaked
because the quartz resetTrap was released immediately after catching
ticker.Reset (line 174), allowing client.TaskByID (line 175) to race
with the subsequent DB mutation (pauseTask / PatchAppStatus).
Fix: keep the resetTrap open across both poll iterations. On the first
poll, release the trap so the goroutine sees the initial state and
continues. On the second poll, hold the goroutine frozen at
ticker.Reset while mutating state. Then release; client.TaskByID
deterministically sees the mutated state. No race because the
goroutine cannot execute client.TaskByID while trapped.
Closes CODAGT-482
PausedDuringWaitForReady used the real clock, so the 5s poll in
waitForTaskIdle could race with an in-flight stop build. The SQL
view (tasks_with_status) returns "unknown" for stop builds with
job_status != "succeeded" because the build_status CASE has no
branch for (stop, pending) or (stop, running). On macOS CI, where
the provisioner is slower, the poll fires during this transient
window and hits the TaskStatusUnknown case instead of
TaskStatusPaused, failing with "task entered unknown state" rather
than the expected "was paused".
Convert to the same quartz mock clock pattern that PR #25648
applied to WaitsForWorkingAppState: inject a mock clock via
NewWithClock, trap ticker creation and reset, then advance time
deterministically so the poll fires after the stop build completes.
Closes CODAGT-482
waitForTaskIdle used time.NewTicker(5s) which delays the first poll
by 5 seconds. Debugger tracing proved the failure mechanism: on slow
CI (Windows), the first poll at 5s sees "working" (idle patch has not
landed due to goroutine scheduling), needs poll #2 at 10s, but the
25s context expires before it fires.
Two changes:
1. Use r.clock.NewTicker (quartz) with time.Nanosecond initial
interval and Reset(5s) for immediate first poll. Tests inject a
mock clock via clitest.NewWithClock for deterministic control.
2. Rewrite WaitsForWorkingAppState test with quartz traps
(NewTicker + TickerReset) for deterministic synchronization
instead of racing goroutines. Fix PausedDuringWaitForReady
sync point.
Closes DEVEX-381
Context was created before expensive setup operations (building
workspaces, starting agents), leaving insufficient time for the actual
command execution. Split into setupCtx for setup and a fresh ctx for
the command to ensure both get the full timeout.
Fixes all our Go file imports to match the preferred spec that we've _mostly_ been using. For example:
```
import (
"context"
"time"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/xerrors"
"gopkg.in/natefinch/lumberjack.v2"
"cdr.dev/slog/v3"
"github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/serpent"
)
```
3 groups: standard library, 3rd partly libs, Coder libs.
This PR makes the change across the codebase. The PR in the stack above modifies our formatting to maintain this state of affairs, and is a separate PR so it's possible to review that one in detail.
## Overview
This change promotes the tasks CLI commands from `coder exp task` to
`coder task`, marking them as generally available (GA).
## Migration
Users will need to update their scripts from:
```shell
coder exp task create "my task"
```
To:
```shell
coder task create "my task"
```
---
🤖 This change was written by Claude Sonnet 4.5 Thinking using [mux](https://github.com/coder/mux) and reviewed by a human 🏄🏻♂️