feat(coding-agent/discovery): set builtin discovery rules to interruptMode never

- Added `interruptMode: never` to all updated Go, Rust, and TypeScript built-in discovery rule files.
- Changed `ts-no-inline-cast-access.md` from `interruptMode: tool-only` to `interruptMode: never`.
This commit is contained in:
can1357
2026-07-15 14:34:38 +02:00
parent 71f29e17c9
commit b52c798025
19 changed files with 19 additions and 1 deletions
@@ -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`.**
@@ -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.
@@ -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.
@@ -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.
@@ -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).
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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"
@@ -2,6 +2,7 @@
description: "Do not use `ReturnType<typeof fn>` — 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<typeof fn>`. Name the type at the module that owns the value and import that name at consumers.
@@ -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.