Skip to content

feat: migrate unsafe_type_assertion from regex to AST detection - #24

Merged
CodeDeficient merged 8 commits into
mainfrom
feat/ast-unsafe-type-assertion
Jul 27, 2026
Merged

feat: migrate unsafe_type_assertion from regex to AST detection#24
CodeDeficient merged 8 commits into
mainfrom
feat/ast-unsafe-type-assertion

Conversation

@CodeDeficient

@CodeDeficient CodeDeficient commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

Migrates unsafe_type_assertion (as any) from line-based regex to TypeScript Compiler API AST detection, following the same pattern as the existing unsafe_double_type_assertion, unsafe_object_assertion, and unsafe_array_assertion rules.

Changes

  • AST detection: as any assertions are now detected by the AST visitor in findUnsafeAssertions() instead of the generic regex loop
  • No false positives from text: Comments, strings, and template literals containing as any are no longer reported — the AST naturally distinguishes syntax from text
  • Nested/multiline support: Assertions inside function calls, parenthesized expressions, and multiline forms are handled correctly
  • Pattern ID preserved: unsafe_type_assertion remains unchanged — existing severityOverrides configurations continue to work
  • Regex path removed: The old regex pattern and its special-case test-file skip logic have been removed

Testing

  • 10 new regression tests covering: basic detection, comments, strings, template literals, nested expressions, multiline expressions, multiple assertions, @ts-expect-error, eslint-disable-next-line, and .d.ts exclusion
  • All 30 tests pass
  • Build succeeds
  • No mocks used — all tests exercise real findUnsafeAssertions execution

Version

1.0.29


CodeAnt-AI Description

Detect unsafe as any assertions accurately in TypeScript code

What Changed

  • as any assertions are now detected from TypeScript syntax, including nested and multiline expressions
  • Text in comments, strings, and template literals is no longer incorrectly reported
  • Suppression comments and declaration files continue to avoid findings
  • Existing unsafe_type_assertion configuration keys remain supported

Impact

✅ Fewer false-positive unsafe assertion warnings
✅ Reliable detection of nested and multiline assertions
✅ Unchanged severity override compatibility

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Improved unsafe assertion reporting for as any, including nested, multiline, and chained forms with accurate source positioning.
  • Bug Fixes
    • More reliable suppression handling for eslint-disable-line / @ts-ignore on the first line and improved multiline suppression anchoring.
    • Unsafe as any is no longer reported from comments/strings/template literals or .d.ts inputs; guidance text updated to avoid recommending chained assertions.
    • Restored test-file skipping behavior with a refined path heuristic.
  • Tests
    • Expanded behavior and CLI output coverage, including strict-mode disabling scenarios.
  • Changelog
    • Added v1.0.29 entry and bumped package version.

- Replace regex-based  detection with TypeScript Compiler API
- Comments and strings containing  are no longer reported
- Nested and multiline assertions handled syntactically
- Pattern ID unchanged — existing severityOverrides continue to work
- 10 new regression tests covering detection, false positives, suppression
@codeant-ai

codeant-ai Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR f0c4ce2 Jul 27, 2026 · 15:42 15:45

@codeant-ai

codeant-ai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 17565252-9081-4b39-8fd4-527fd075e427

📥 Commits

Reviewing files that changed from the base of the PR and between 3a9b942 and dbd609b.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • ai-slop-detector.ts
  • tests/ai-slop-detector.behavior.test.ts
  • tests/t4-educational-output.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • CHANGELOG.md
  • tests/ai-slop-detector.behavior.test.ts
  • ai-slop-detector.ts

📝 Walkthrough

Walkthrough

unsafe_type_assertion now detects as any through TypeScript AST analysis, including chained and multiline assertions, with updated suppression and test-file scan behavior. Chained assertion detection is broadened, tests are expanded, and the package version is updated to 1.0.29.

Changes

Unsafe assertion detection

Layer / File(s) Summary
AST assertion detection
ai-slop-detector.ts
AST analysis reports direct and chained as any assertions at the any type-node location, while related unsafe assertion patterns use AST-only detection.
Suppression and file filtering
ai-slop-detector.ts
Suppression checks handle first-line and adjacent directives, and test-file filtering remains applied to unsafe_type_assertion.
Detection validation and release metadata
tests/ai-slop-detector.behavior.test.ts, tests/t4-educational-output.ts, package.json, CHANGELOG.md
Tests cover nested, multiline, suppressed, chained, configuration-override, and test-file behavior; guidance, changelog, and version metadata target 1.0.29.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SourceFile
  participant analyzeFile
  participant findUnsafeAssertions
  participant TypeScriptAST
  participant SuppressionChecks
  SourceFile->>analyzeFile: provide source text
  analyzeFile->>findUnsafeAssertions: inspect assertions
  findUnsafeAssertions->>TypeScriptAST: locate assertion target types
  TypeScriptAST-->>findUnsafeAssertions: return assertion nodes and positions
  findUnsafeAssertions->>SuppressionChecks: evaluate suppression directives
  SuppressionChecks-->>analyzeFile: return applicable findings
Loading

Possibly related issues

Possibly related PRs

Poem

I hopped through the AST with care,
Found as any hiding there.
Chained forms now join the queue,
Suppression rules are tidy too.
Test files rest, source files gleam—
Version 1.0.29 joins the stream!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: moving unsafe_type_assertion detection from regex to AST-based detection.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ast-unsafe-type-assertion

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Jul 27, 2026
Comment thread ai-slop-detector.ts Outdated
Comment on lines +245 to +247
// Use the position of the type node (same line as `as` keyword) for correct line reporting
const { line: asLineIdx, character: asCharIdx } = sourceFile.getLineAndCharacterOfPosition(node.type.getStart(sourceFile));
const asLine = asLineIdx + 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The finding location is now taken from node.type, while suppression is checked earlier using the outer assertion's sourceLine. For a multiline assertion such as value as\\n any, a suppression directive on the reported any line is evaluated against line 1 and is missed, so the new multiline detection cannot be suppressed at the location it reports. Check suppression against the reported line as well, or keep the finding location and suppression basis consistent. [logic error]

Severity Level: Major ⚠️
- ⚠️ Multiline assertion suppressions are ineffective.
- ⚠️ Reported locations disagree with suppression checks.
- ❌ Explicit lint directives cannot silence affected findings.
Steps of Reproduction ✅
1. Call `findUnsafeAssertions()` with the multiline assertion form exercised by
`tests/ai-slop-detector.behavior.test.ts:263-271`: `const x = value as` followed by
`any;`.

2. The visitor enters the outer `ts.AsExpression` and checks suppression against its start
line at `ai-slop-detector.ts:227`; for this form, the outer expression starts on line 1.

3. The finding location is then calculated from `node.type.getStart(sourceFile)` at
`ai-slop-detector.ts:246-247`, so the reported finding is line 2, where the `any` type
node begins.

4. Put `// eslint-disable-line` on the reported line (`any; // eslint-disable-line`).
`lineIsSuppressed()` at `ai-slop-detector.ts:183-199` would recognize that directive for
line 2, but the visitor already tested line 1 and proceeds to emit the finding. Thus
suppression at the reported location fails for multiline assertions.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** ai-slop-detector.ts
**Line:** 245:247
**Comment:**
	*Logic Error: The finding location is now taken from `node.type`, while suppression is checked earlier using the outer assertion's `sourceLine`. For a multiline assertion such as `value as\\n any`, a suppression directive on the reported `any` line is evaluated against line 1 and is missed, so the new multiline detection cannot be suppressed at the location it reports. Check suppression against the reported line as well, or keep the finding location and suppression basis consistent.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread ai-slop-detector.ts
pattern.id === 'unsafe_object_assertion' ||
pattern.id === 'unsafe_array_assertion') {
pattern.id === 'unsafe_array_assertion' ||
pattern.id === 'unsafe_type_assertion') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The regex path now skips unsafe_type_assertion for every target extension, but the AST pass below runs only for .ts and .tsx. As a result, .js and .jsx files no longer produce this finding even though they remain supported scan targets and previously went through the regex detector. Either run the AST detection for those extensions with the appropriate script kind or retain equivalent detection for them. [api mismatch]

Severity Level: Critical 🚨
- ❌ JavaScript assertions are no longer reported.
- ❌ JSX assertion coverage is also lost.
- ⚠️ Supported target extensions behave inconsistently.
Steps of Reproduction ✅
1. Run the detector against a project containing `.js` or `.jsx` files;
`AISlopDetector.targetExtensions` explicitly includes these extensions at
`ai-slop-detector.ts:296`.

2. A target file containing `value as any` reaches the generic pattern loop in
`analyzeFile()` at `ai-slop-detector.ts:982-1000`.

3. The new condition at `ai-slop-detector.ts:998` skips every pattern whose ID is
`unsafe_type_assertion`, so the regex path cannot report the assertion.

4. The AST pass is guarded by `filePath.endsWith('.ts') || filePath.endsWith('.tsx')` at
`ai-slop-detector.ts:1173-1174`, so it never calls `findUnsafeAssertions()` for `.js` or
`.jsx` files. The result is no `unsafe_type_assertion` finding for those supported target
extensions.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** ai-slop-detector.ts
**Line:** 998:998
**Comment:**
	*Api Mismatch: The regex path now skips `unsafe_type_assertion` for every target extension, but the AST pass below runs only for `.ts` and `.tsx`. As a result, `.js` and `.jsx` files no longer produce this finding even though they remain supported scan targets and previously went through the regex detector. Either run the AST detection for those extensions with the appropriate script kind or retain equivalent detection for them.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@CodeDeficient

Copy link
Copy Markdown
Owner Author

Tracked the column/line inconsistency as issue #25 for follow-up validation.

When the outer assertion type is also , both
unsafe_double_type_assertion and unsafe_type_assertion are now
emitted independently. Disabling one rule does not suppress the other.
@CodeDeficient

Copy link
Copy Markdown
Owner Author

Fix applied

Regression: as unknown as any was only reported as unsafe_double_type_assertion. Disabling that rule would silently hide the unsafe as any.

Fix: Added an inner check inside the double-assertion branch so unsafe_type_assertion is emitted independently when the target type is any.

Verification

  • input as unknown as any → both findings emitted
  • input as unknown as Foo → only double assertion (unchanged)
  • input as any → only any assertion (unchanged)
  • Suppressed chained assertions → no findings (unchanged)
  • severityOverrides: { "unsafe_double_type_assertion": "off" } → only unsafe_type_assertion reported

32/32 tests pass. Build succeeds. No unrelated changes.

Please re-review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/ai-slop-detector.behavior.test.ts`:
- Around line 282-290: Update findUnsafeAssertions to inspect inline suppression
directives on currentLine before its early return for first-line input. Ensure
`// eslint-disable-line` suppresses findings such as `const x = value as any; //
eslint-disable-line` on line 1, while preserving the existing preceding-line
suppression behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: de7bf31a-5414-42c2-95a0-2b6df67f44f3

📥 Commits

Reviewing files that changed from the base of the PR and between 9e13500 and 434c6d5.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • ai-slop-detector.ts
  • package.json
  • tests/ai-slop-detector.behavior.test.ts

Comment on lines +282 to +290
test('findUnsafeAssertions does not report as any when preceded by @ts-expect-error', () => {
const code = '// @ts-expect-error\nconst x = value as any;';
assert.equal(findUnsafeAssertions(code, 'x.ts').length, 0);
});

test('findUnsafeAssertions does not report as any when preceded by eslint-disable-next-line', () => {
const code = '// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst x = value as any;';
assert.equal(findUnsafeAssertions(code, 'x.ts').length, 0);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle first-line inline suppressions.

These tests only cover preceding-line directives. Line 184 returns before inspecting currentLine, so const x = value as any; // eslint-disable-line on line 1 still reports a finding.

Proposed fix
 const lineIsSuppressed = (line: number): boolean => {
-  if (line <= 1) return false;
-  const prevLine = lines[line - 2];
+  if (line < 1 || line > lines.length) return false;
+  const prevLine = line > 1 ? lines[line - 2] : '';
   const currentLine = lines[line - 1];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/ai-slop-detector.behavior.test.ts` around lines 282 - 290, Update
findUnsafeAssertions to inspect inline suppression directives on currentLine
before its early return for first-line input. Ensure `// eslint-disable-line`
suppresses findings such as `const x = value as any; // eslint-disable-line` on
line 1, while preserving the existing preceding-line suppression behavior.

@CodeDeficient

Copy link
Copy Markdown
Owner Author

Accepted follow-ups (non-critical findings)

Per review, these are accepted as non-critical — not fixed here:

…ection

The AST migration (f0c4ce2) dropped the old regex-path logic that
excluded test/spec/__tests__ files from unsafe_type_assertion
findings in default (non-quiet) mode.

Adding skipTests:true to the pattern definition restores this
behavior — the existing decorator guard in the AST findings loop
(analyzeFile, line 1202) already applies skipTests to AST findings.

Package-lock bumped to match 1.0.29.
@CodeDeficient

Copy link
Copy Markdown
Owner Author

Issue #26 (test-file exception) is now resolved by commit eef4363unsafe_type_assertion findings are once again excluded from test files in default mode, matching the pre-migration behavior.

…suppression

P1: The AST migration (f0c4ce2) only recognized as unknown as T as a
double assertion. Broaden condition to any nested AsExpression so that
value as Foo as Bar continues to produce unsafe_double_type_assertion.

P2: lineIsSuppressed returned false for line <= 1 before checking the
current line. Reorder so the current line is always checked for inline
suppressions (eslint-disable-line, @ts-ignore, etc.), and the previous
line is checked only when it exists.
… regex

Also removes orphaned blank lines left from the test-file exclusion
block removal in f0c4ce2.
Adds tests verifying exact finding counts for chained assertions at
every depth (1-chain->1, 2-chain->2, 3-chain->3, 4-chain->3) per
the user's requirement that findings reflect the precise AST count
with no deduplication.

Also adds a comment on the first /(?!)/ sentinel regex explaining
it is AST-driven and the pattern is a never-match placeholder.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ai-slop-detector.ts (1)

236-277: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the reported line when checking multiline suppressions.

Suppression is evaluated using node.getStart() (sourceLine), but direct and chained as any findings are reported using node.type.getStart(). In a multiline assertion, // eslint-disable-line on the line containing any will not suppress the finding. Check the effective finding line, or intentionally check both relevant lines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ai-slop-detector.ts` around lines 236 - 277, Update suppression handling for
unsafe_type_assertion findings in the chained and direct assertion paths to use
the effective reported line from node.type.getStart(sourceFile), rather than
only node.getStart(sourceFile). Ensure multiline as any assertions can be
suppressed by a directive on the line containing any, while preserving existing
suppression behavior for unsafe_double_type_assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ai-slop-detector.ts`:
- Around line 489-498: Update the unsafe_type_assertion rule’s fix
recommendation to remove “as unknown as TargetType” and advise only validated
conversion or implementing a runtime type guard. Keep the rule’s detection
behavior, message, and other metadata unchanged.
- Around line 185-200: Update the suppression detection logic around the
current-line and previous-line checks to parse only actual comment directives,
ignoring directive-like text inside strings or trailing non-directive content.
Apply each ESLint directive according to its target-line semantics, ensuring
eslint-disable-line affects only its own line and does not suppress the
following line, while preserving next-line behavior for eslint-disable-next-line
and TypeScript suppressions.
- Around line 236-246: Update the chained-assertion detection around
ts.isAsExpression(node.expression) to unwrap any ParenthesizedExpression layers
before checking for an inner AsExpression. Ensure patterns such as (value as
unknown) as any are classified as unsafe_double_type_assertion with
assertionForm chained_as, while preserving the existing generic handling for
non-chained assertions.

In `@tests/ai-slop-detector.behavior.test.ts`:
- Around line 403-411: Assert result.status === 0 in the excluded test-fixture
case before checking stdout, and assert result.status === 1 in the detected
high-severity source-fixture case. Apply these assertions in
tests/ai-slop-detector.behavior.test.ts at lines 403-411 and 424-432,
respectively.

---

Outside diff comments:
In `@ai-slop-detector.ts`:
- Around line 236-277: Update suppression handling for unsafe_type_assertion
findings in the chained and direct assertion paths to use the effective reported
line from node.type.getStart(sourceFile), rather than only
node.getStart(sourceFile). Ensure multiline as any assertions can be suppressed
by a directive on the line containing any, while preserving existing suppression
behavior for unsafe_double_type_assertion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f277a4ed-4bfb-4d68-802e-f7b389701609

📥 Commits

Reviewing files that changed from the base of the PR and between 434c6d5 and 3a9b942.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • CHANGELOG.md
  • ai-slop-detector.ts
  • tests/ai-slop-detector.behavior.test.ts

Comment thread ai-slop-detector.ts
Comment thread ai-slop-detector.ts
Comment thread ai-slop-detector.ts
Comment on lines +403 to +411
const result = spawnSync(
process.execPath,
['--import', 'tsx', path.resolve(process.cwd(), 'ai-slop-detector.ts'), fixtureFile],
{ encoding: 'utf-8', cwd: process.cwd() }
);

try {
assert.ok(!result.stdout.includes('unsafe_type_assertion'),
`should not report as any in test files. stdout:"${result.stdout}"`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the expected CLI exit codes.

Both tests can pass when the process fails without producing the checked stdout text.

  • tests/ai-slop-detector.behavior.test.ts#L403-L411: assert result.status === 0 for the excluded test fixture.
  • tests/ai-slop-detector.behavior.test.ts#L424-L432: assert result.status === 1 for the detected high-severity source fixture.
Proposed fix
   try {
+    assert.equal(result.status, 0, `Expected exit code 0 but got ${result.status}. stderr:"${result.stderr}"`);
     assert.ok(!result.stdout.includes('unsafe_type_assertion'),
       `should not report as any in test files. stdout:"${result.stdout}"`);
@@
   try {
+    assert.equal(result.status, 1, `Expected exit code 1 but got ${result.status}. stderr:"${result.stderr}"`);
     assert.ok(result.stdout.includes('unsafe_type_assertion'),
       `should report as any in non-test files. stdout:"${result.stdout}"`);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = spawnSync(
process.execPath,
['--import', 'tsx', path.resolve(process.cwd(), 'ai-slop-detector.ts'), fixtureFile],
{ encoding: 'utf-8', cwd: process.cwd() }
);
try {
assert.ok(!result.stdout.includes('unsafe_type_assertion'),
`should not report as any in test files. stdout:"${result.stdout}"`);
const result = spawnSync(
process.execPath,
['--import', 'tsx', path.resolve(process.cwd(), 'ai-slop-detector.ts'), fixtureFile],
{ encoding: 'utf-8', cwd: process.cwd() }
);
try {
assert.equal(result.status, 0, `Expected exit code 0 but got ${result.status}. stderr:"${result.stderr}"`);
assert.ok(!result.stdout.includes('unsafe_type_assertion'),
`should not report as any in test files. stdout:"${result.stdout}"`);
📍 Affects 1 file
  • tests/ai-slop-detector.behavior.test.ts#L403-L411 (this comment)
  • tests/ai-slop-detector.behavior.test.ts#L424-L432
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/ai-slop-detector.behavior.test.ts` around lines 403 - 411, Assert
result.status === 0 in the excluded test-fixture case before checking stdout,
and assert result.status === 1 in the detected high-severity source-fixture
case. Apply these assertions in tests/ai-slop-detector.behavior.test.ts at lines
403-411 and 424-432, respectively.

… anchoring

- Fix: safe_type_assertion guidance no longer recommends 'as unknown as TargetType', which is itself flagged by unsafe_double_type_assertion
- Fix: Multiline as any suppression now checks the 'any' token line, not the outer 'as' expression line
- Updated fixture comment and CHANGELOG with accurate description of test-file exclusion scope
@CodeDeficient

Copy link
Copy Markdown
Owner Author

Follow-up issues created from review comments

These items are tracked for validation and implementation in separate issues. They are not release blockers for 1.0.29.

Existing related issues:

@CodeDeficient
CodeDeficient merged commit 1257c85 into main Jul 27, 2026
2 checks passed
@CodeDeficient
CodeDeficient deleted the feat/ast-unsafe-type-assertion branch July 27, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant