diff --git a/packages/coding-agent/src/discovery/builtin-rules/go-add-cleanup.md b/packages/coding-agent/src/discovery/builtin-rules/go-add-cleanup.md index dc0ccc3c6..72bf24601 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/go-add-cleanup.md +++ b/packages/coding-agent/src/discovery/builtin-rules/go-add-cleanup.md @@ -2,6 +2,7 @@ description: "Prefer runtime.AddCleanup over runtime.SetFinalizer for new code (Go 1.24)" condition: 'runtime\.SetFinalizer' scope: "tool:edit(*.go), tool:write(*.go)" +interruptMode: never --- Go 1.24 added `runtime.AddCleanup`, a finalization mechanism that is more flexible and less error-prone than `runtime.SetFinalizer`. The release notes state plainly: **new code should prefer `AddCleanup` over `SetFinalizer`.** diff --git a/packages/coding-agent/src/discovery/builtin-rules/go-exp-promoted.md b/packages/coding-agent/src/discovery/builtin-rules/go-exp-promoted.md index 76fde42c8..319de1dbf 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/go-exp-promoted.md +++ b/packages/coding-agent/src/discovery/builtin-rules/go-exp-promoted.md @@ -4,6 +4,7 @@ condition: - '"golang.org/x/exp/slices"' - '"golang.org/x/exp/maps"' scope: "tool:edit(*.go), tool:write(*.go)" +interruptMode: never --- `golang.org/x/exp/slices` and `golang.org/x/exp/maps` were promoted into the standard library as `slices` and `maps` in Go 1.21. Import the stdlib packages in new code instead of the experimental ones. diff --git a/packages/coding-agent/src/discovery/builtin-rules/go-ioutil.md b/packages/coding-agent/src/discovery/builtin-rules/go-ioutil.md index 394dd77e0..3aef73368 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/go-ioutil.md +++ b/packages/coding-agent/src/discovery/builtin-rules/go-ioutil.md @@ -2,6 +2,7 @@ description: "Use io and os instead of the deprecated io/ioutil package" condition: '"io/ioutil"' scope: "tool:edit(*.go), tool:write(*.go)" +interruptMode: never --- `io/ioutil` has been deprecated since Go 1.16. Every function moved to `io` or `os` with the same behavior. Do not import it in new code. diff --git a/packages/coding-agent/src/discovery/builtin-rules/go-join-hostport.md b/packages/coding-agent/src/discovery/builtin-rules/go-join-hostport.md index 807b6bad2..b8104aea7 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/go-join-hostport.md +++ b/packages/coding-agent/src/discovery/builtin-rules/go-join-hostport.md @@ -2,6 +2,7 @@ description: "Build network addresses with net.JoinHostPort, not fmt.Sprintf(\"%s:%d\", host, port) — the Sprintf form breaks on IPv6" condition: 'fmt\.Sprintf\("%s:%d"' scope: "tool:edit(*.go), tool:write(*.go)" +interruptMode: never --- Use `net.JoinHostPort(host, port)` to assemble a `host:port` address. `fmt.Sprintf("%s:%d", host, port)` produces invalid addresses for IPv6 hosts, which must be bracketed (`[::1]:80`). Go 1.25's `go vet` `hostport` analyzer flags exactly this pattern. diff --git a/packages/coding-agent/src/discovery/builtin-rules/go-rand-v2.md b/packages/coding-agent/src/discovery/builtin-rules/go-rand-v2.md index 6147ff0ec..7c6b53446 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/go-rand-v2.md +++ b/packages/coding-agent/src/discovery/builtin-rules/go-rand-v2.md @@ -2,6 +2,7 @@ description: Prefer math/rand/v2 over the legacy math/rand package condition: '"math/rand"' scope: "tool:edit(*.go), tool:write(*.go)" +interruptMode: never --- Use `math/rand/v2` instead of the legacy `math/rand` package (stable since Go 1.22). diff --git a/packages/coding-agent/src/discovery/builtin-rules/rs-box-leak.md b/packages/coding-agent/src/discovery/builtin-rules/rs-box-leak.md index e6abd0e55..ce1ac6cdc 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/rs-box-leak.md +++ b/packages/coding-agent/src/discovery/builtin-rules/rs-box-leak.md @@ -2,6 +2,7 @@ description: Never use Box::leak - it intentionally leaks memory condition: "Box::leak" scope: "tool:edit(*.rs), tool:write(*.rs)" +interruptMode: never --- Never use `Box::leak` to satisfy a lifetime. It intentionally leaks the allocation for the rest of the process. diff --git a/packages/coding-agent/src/discovery/builtin-rules/rs-future-prelude.md b/packages/coding-agent/src/discovery/builtin-rules/rs-future-prelude.md index 4ffd17618..f84706d02 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/rs-future-prelude.md +++ b/packages/coding-agent/src/discovery/builtin-rules/rs-future-prelude.md @@ -2,6 +2,7 @@ description: Use Future not std::future::Future - it's in the prelude condition: "std::future::Future" scope: "tool:edit(*.rs), tool:write(*.rs)" +interruptMode: never --- Use `Future` directly instead of `std::future::Future` in type positions. diff --git a/packages/coding-agent/src/discovery/builtin-rules/rs-lazylock.md b/packages/coding-agent/src/discovery/builtin-rules/rs-lazylock.md index c82a9e0af..313712790 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/rs-lazylock.md +++ b/packages/coding-agent/src/discovery/builtin-rules/rs-lazylock.md @@ -4,6 +4,7 @@ condition: - "once_cell::" - "OnceLock::new" scope: "tool:edit(*.rs), tool:write(*.rs)" +interruptMode: never --- Prefer `std::sync::LazyLock` over `OnceLock` and the `once_cell` crate when the initializer is known at declaration time. diff --git a/packages/coding-agent/src/discovery/builtin-rules/rs-match-ergonomics.md b/packages/coding-agent/src/discovery/builtin-rules/rs-match-ergonomics.md index 8f4d34280..250289563 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/rs-match-ergonomics.md +++ b/packages/coding-agent/src/discovery/builtin-rules/rs-match-ergonomics.md @@ -4,6 +4,7 @@ condition: - "\\(ref mut " - "\\(ref [a-z_]" scope: "tool:edit(*.rs), tool:write(*.rs)" +interruptMode: never --- Use match ergonomics instead of explicit `ref` / `ref mut` patterns. Borrow the scrutinee and let bindings receive references. diff --git a/packages/coding-agent/src/discovery/builtin-rules/rs-parking-lot.md b/packages/coding-agent/src/discovery/builtin-rules/rs-parking-lot.md index 3a6d18b22..30c4df3bc 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/rs-parking-lot.md +++ b/packages/coding-agent/src/discovery/builtin-rules/rs-parking-lot.md @@ -5,6 +5,7 @@ condition: - "\\.read\\(\\)\\.unwrap\\(\\)" - "\\.write\\(\\)\\.unwrap\\(\\)" scope: "tool:edit(*.rs), tool:write(*.rs)" +interruptMode: never --- Use `parking_lot::{Mutex, RwLock}` instead of `std::sync::{Mutex, RwLock}` when code immediately unwraps lock results. diff --git a/packages/coding-agent/src/discovery/builtin-rules/rs-result-type.md b/packages/coding-agent/src/discovery/builtin-rules/rs-result-type.md index 6515e0736..55b85a6af 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/rs-result-type.md +++ b/packages/coding-agent/src/discovery/builtin-rules/rs-result-type.md @@ -2,6 +2,7 @@ description: Result type aliases must include a defaulted error type parameter condition: "type\\s+Result<[A-Za-z_]\\w*>\\s*=" scope: "tool:edit(*.rs), tool:write(*.rs)" +interruptMode: never --- `Result` aliases must expose the error type as a defaulted parameter. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-bare-catch.md b/packages/coding-agent/src/discovery/builtin-rules/ts-bare-catch.md index accc6a95d..0e246fd08 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-bare-catch.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-bare-catch.md @@ -2,6 +2,7 @@ description: Use bare `catch {` when the error binding is unused condition: "catch \\(_" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Use bare `catch {}` when the caught value is unused. An underscore-prefixed binding adds noise and still allocates a local name. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-import-type.md b/packages/coding-agent/src/discovery/builtin-rules/ts-import-type.md index 5cf001747..612aadc02 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-import-type.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-import-type.md @@ -2,6 +2,7 @@ description: "Use `import type`, not `import('pkg').Type` in type positions" condition: "import\\(" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Use top-level `import type` declarations for type-only dependencies. NEVER write `import("pkg").Type` inside source annotations. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-no-any.md b/packages/coding-agent/src/discovery/builtin-rules/ts-no-any.md index 55d25b065..e293993b0 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-no-any.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-no-any.md @@ -2,6 +2,7 @@ description: "Never use `any` in TypeScript annotations or assertions — use `unknown`, generics, a schema parse at trust boundaries, or the actual type" condition: ": any|as any" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Never use `: any` or `as any`. They disable type checking exactly where the boundary needs precision. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md b/packages/coding-agent/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md index 30641d654..f7db546b8 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md @@ -2,6 +2,7 @@ description: "Do not leave `@deprecated` shims behind after refactors — update call sites and remove the old API" condition: "@deprecated" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Do not use `@deprecated` as a substitute for finishing a refactor. If an API is obsolete inside the code you control, update every call site and remove the old name in the same change. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-no-dynamic-import.md b/packages/coding-agent/src/discovery/builtin-rules/ts-no-dynamic-import.md index 831aed215..a4cc26362 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-no-dynamic-import.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-no-dynamic-import.md @@ -2,6 +2,7 @@ description: "Do not use `await import()` — use static imports unless dynamic loading is unavoidable" condition: "await import\\(" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Use static imports for modules known at author time. Reach for `await import()` only when the module specifier is genuinely runtime-selected. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-no-inline-cast-access.md b/packages/coding-agent/src/discovery/builtin-rules/ts-no-inline-cast-access.md index 69c23dc50..87631139b 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-no-inline-cast-access.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-no-inline-cast-access.md @@ -1,7 +1,7 @@ --- description: "Don't assert an inline object type and immediately read a property — `(x as { y: T }).y` trusts an unchecked shape; validate with a schema parse at trust boundaries, narrow with `in`/`typeof`, or use a validated named type" scope: "tool:edit(*.{ts,tsx,mts,cts}), tool:write(*.{ts,tsx,mts,cts})" -interruptMode: tool-only +interruptMode: never astCondition: - "($X as { $$$BODY }).$PROP" - "($X as { $$$BODY })?.$PROP" diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-no-return-type.md b/packages/coding-agent/src/discovery/builtin-rules/ts-no-return-type.md index 17af06855..455dbb170 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-no-return-type.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-no-return-type.md @@ -2,6 +2,7 @@ description: "Do not use `ReturnType` — name the type explicitly" condition: "ReturnType<" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Do not publish contracts through `ReturnType`. Name the type at the module that owns the value and import that name at consumers. diff --git a/packages/coding-agent/src/discovery/builtin-rules/ts-promise-with-resolvers.md b/packages/coding-agent/src/discovery/builtin-rules/ts-promise-with-resolvers.md index 27d14a62f..c640d43eb 100644 --- a/packages/coding-agent/src/discovery/builtin-rules/ts-promise-with-resolvers.md +++ b/packages/coding-agent/src/discovery/builtin-rules/ts-promise-with-resolvers.md @@ -2,6 +2,7 @@ description: Use Promise.withResolvers() instead of new Promise() constructor condition: "new Promise\\(" scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)" +interruptMode: never --- Use `Promise.withResolvers()` instead of `new Promise((resolve, reject) => ...)`. It keeps control flow linear and exposes typed resolver functions without callback nesting.