diff options
| author | amankumarsingh77 <amankumarsingh7702@gmail.com> | 2026-07-28 20:40:58 +0530 |
|---|---|---|
| committer | Aman Kumar <145339995+amankumarsingh77@users.noreply.github.com> | 2026-08-02 19:12:46 +0530 |
| commit | 3c4e0b21ad76a734731725cf16cdfb772aa69bbf (patch) | |
| tree | 75b48925706de9f01ab84576dcdad836f889592b /scripts | |
| parent | a9bdbd8590801cd9c2fa0cda6203948ac19a779c (diff) | |
chore: make the boundary scanner see every cast, not just the unsafe forms
The scanner banned as any, as {, as unknown as, non-null assertions and
ts-ignore, but said nothing about `as SomeNamedType` — so a new cast over
CDP or JSON data could be added and CI would stay green, which is the exact
regression the refactor exists to prevent. It also could not see a cast
whose target type sits on the following line.
Adds named-cast, function-cast and trailing-cast. All six surviving
assertions in src/ are now visible to the scanner and individually
exempted with a stated reason, so the allowlist is the complete inventory.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/boundary-allowlist.ts | 35 | ||||
| -rw-r--r-- | scripts/check-boundaries.ts | 3 |
2 files changed, 38 insertions, 0 deletions
diff --git a/scripts/boundary-allowlist.ts b/scripts/boundary-allowlist.ts index be6816f..bb34139 100644 --- a/scripts/boundary-allowlist.ts +++ b/scripts/boundary-allowlist.ts @@ -13,4 +13,39 @@ export const ALLOWLIST: ReadonlyArray<Exemption> = [ reason: "sharp is an optional dependency resolved by a dynamic import, so its shape is unknown at compile time; the cast only claims an optional .default and every value read off it is re-checked with typeof before use", }, + { + path: "src/util/sharp-shim.ts", + rule: "named-cast", + count: 1, + reason: + "the same optional-dependency boundary: candidate is narrowed to a callable by a typeof check on the line above before it is claimed to be a SharpFactory", + }, + { + path: "src/cdp/commands.ts", + rule: "named-cast", + count: 1, + reason: + "the sanctioned CDP result decoder; guarded by the validate.Check on the preceding line, and unavoidable because a generic key cannot correlate with its mapped value type", + }, + { + path: "src/cdp/events.ts", + rule: "named-cast", + count: 1, + reason: + "the sanctioned CDP event decoder; same guarded Check and same generic-correlation limit as cdp/commands.ts", + }, + { + path: "src/util/tool.ts", + rule: "function-cast", + count: 1, + reason: + "renderCall is stored under a per-tool Static<S> but invoked through the erased TSchema form; the generic-correlation limit makes this unavoidable and the value is the tool's own handler, created with the same S", + }, + { + path: "src/domains/js.ts", + rule: "trailing-cast", + count: 1, + reason: + "the AsyncFunction constructor is reached through Object.getPrototypeOf, which returns any; the cast restores the constructor signature that a plain unknown would lose", + }, ]; diff --git a/scripts/check-boundaries.ts b/scripts/check-boundaries.ts index 5dff96d..c438b83 100644 --- a/scripts/check-boundaries.ts +++ b/scripts/check-boundaries.ts @@ -17,6 +17,9 @@ const RULES: ReadonlyArray<{ readonly rule: string; readonly re: RegExp }> = [ { rule: "non-null-assertion", re: /[A-Za-z_$)\]]!\s*(?:[.[(;,)\]}]|$)/ }, { rule: "inline-object-cast", re: /\bas\s+\{/ }, { rule: "double-cast", re: /\bas\s+unknown\s+as\b/ }, + { rule: "named-cast", re: /\bas\s+(?:new\s+)?[A-Z][A-Za-z0-9_]*/ }, + { rule: "function-cast", re: /\bas\s+\(/ }, + { rule: "trailing-cast", re: /\bas\s*$/ }, ]; export type SourceFile = { readonly path: string; readonly text: string }; |
