feat: merge grammar and slop checks into unified blog-check workflow#4084
feat: merge grammar and slop checks into unified blog-check workflow#4084goranmoomin merged 3 commits intomainfrom
Conversation
Co-Authored-By: Sungbin Jo <goranmoomin@daum.net>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for hyprnote-storybook canceled.
|
| if (result.error) { | ||
| markdown += `Error: ${result.error}\n\n`; | ||
| } else { | ||
| const { feedback, totalScore } = result; |
There was a problem hiding this comment.
🟡 Crash when error.message is falsy: null feedback accessed in else branch
When checkSlop throws an error with a falsy .message (e.g., new Error("")), the error result at lines 369-374 sets error: error.message (empty string) and feedback: null. In the rendering loop at line 385, if (result.error) evaluates to false for an empty string, so the code falls into the else branch at line 387. There, const { feedback, totalScore } = result; destructures feedback as null and totalScore as undefined. The code then crashes at feedback.score.directness (line 393) with a TypeError: Cannot read properties of null.
Root Cause
The error result object (lines 369-374) stores error: error.message which can be an empty string (falsy). The guard at line 385 uses if (result.error) which is a truthiness check, not an explicit check for the presence of the error property. When error.message is "", the truthiness check fails and the code proceeds to access feedback.score on a null value.
Additionally, the error result object is missing frontmatterLines and totalScore properties that the else branch expects, so even if totalScore were accessed, it would be undefined.
Impact: The script crashes with an unhandled TypeError, producing no useful output for any of the files. The outer .catch() handler would write a generic failure message, losing all results from files that were successfully processed before the crash.
| if (result.error) { | |
| markdown += `Error: ${result.error}\n\n`; | |
| } else { | |
| const { feedback, totalScore } = result; | |
| if (result.feedback === null) { | |
| markdown += `Error: ${result.error || 'Unknown error'}\n\n`; | |
| } else { | |
| const { feedback, totalScore } = result; |
Was this helpful? React with 👍 or 👎 to provide feedback.
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" |
There was a problem hiding this comment.
🚩 Node.js version mismatch with project engine requirement
The workflow specifies node-version: "20" at .github/workflows/blog-slop-check.yml:27, but the root package.json declares "engines": { "node": ">=22" }. While npm install only warns (not errors) about engine mismatches by default, this is an inconsistency. The script itself likely works on Node 20 since it uses standard ES module features, but if the project ever enables engine-strict or if a dependency requires Node 22+, this workflow would break silently.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| - name: Install dependencies | ||
| if: steps.changed-files.outputs.has_files == 'true' | ||
| run: npm install ai @ai-sdk/anthropic zod |
There was a problem hiding this comment.
🚩 npm install in pnpm monorepo root may cause issues
The workflow runs npm install ai @ai-sdk/anthropic zod (line 42) in the repo root, which uses pnpm as its package manager ("packageManager": "pnpm@10.30.0" in root package.json). Running npm install in a pnpm workspace can create a node_modules directory alongside the existing pnpm structure, and may produce warnings or unexpected behavior. Since the script is run standalone with node .github/scripts/slop-check.mjs and doesn't depend on the monorepo's packages, it should resolve the three installed packages fine. But using npx or installing in a temp directory would be cleaner.
Was this helpful? React with 👍 or 👎 to provide feedback.
…ml workflow Co-Authored-By: Sungbin Jo <goranmoomin@daum.net>
…rd lists Co-Authored-By: Sungbin Jo <goranmoomin@daum.net>
feat: merge grammar and slop checks into unified blog-check workflow
Summary
Consolidates the blog post CI checks into a single workflow by renaming
blog-grammar-check.yml→blog-check.ymland adding a new AI slop detection step alongside the existing grammar check. Both checks run sequentially and their results are combined into a single PR comment.New file:
.github/scripts/slop-check.mjs— an AI-powered proofreading pass that flags writing patterns technical readers would recognize as LLM-generated content. The system prompt aggressively assumes all text is LLM-generated by default and checks against a comprehensive ruleset compiled from:Workflow changes:
grammar-check→blog-check---<!-- grammar-check-bot -->to<!-- blog-check-bot -->mainfromblog/*branches touchingapps/web/content/articles/**Review & Testing Checklist for Human
slop-check.mjsis entirely untested — thegenerateObjectcall, Zod schema validation, and markdown output have never been executed. Run locally:ANTHROPIC_API_KEY=... CHANGED_FILES="apps/web/content/articles/some-post.mdx" node .github/scripts/slop-check.mjsagainst a real blog post to verify end-to-end<!-- grammar-check-bot -->comments on existing PRs will be orphaned (new comments will use<!-- blog-check-bot -->). If there are open blog PRs with existing grammar-check comments, they'll get a duplicate comment instead of an updateclaude-haiku-4-5— verify this is the correct Anthropic SDK model identifier. The OpenRouter equivalent isanthropic/claude-haiku-4.5but the@ai-sdk/anthropicprovider may use a different formatgrammar-check.mjs(extractContent,extractFrontmatter,getFrontmatterLineCount,addLineNumbers) — decide whether to extract into a shared module or accept the duplicationTest plan: Open a test PR from a
blog/*branch that modifies a file inapps/web/content/articles/, confirm both grammar and slop check results appear in a single PR comment.Notes