Skip to content

Add local CodeFactor parity lint tooling - #383

Merged
unbraind merged 4 commits into
mainfrom
fix/codefactor-parity-lint-tooling
Jun 26, 2026
Merged

unbraind merged 4 commits into
mainfrom
fix/codefactor-parity-lint-tooling

Conversation

@unbraind

@unbraind unbraind commented Jun 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Adds pnpm lint as a local CodeFactor parity gate: ESLint maintainability rules, jscpd duplicate reporting, and the existing static quality profile.
  • Wires pnpm lint into the CI static gate and locks the new dev tooling.
  • Documents the lint workflow and release gate mapping, regenerates CHANGELOG.md with pm-changelog, and closes the CodeFactor parity/complexity/duplication PM items.

Verification

  • pm test pm-6sqo --run --progress
  • pnpm lint
  • node scripts/run-tests.mjs test -- tests/integration/ci-workflow-contract.spec.ts tests/integration/release-automation-contract.spec.ts tests/integration/release-readiness-runtime.spec.ts
  • pnpm typecheck
  • pnpm quality:static
  • pnpm contracts:check
  • pnpm security:scan
  • pnpm audit --audit-level moderate
  • pnpm changelog:pm:check
  • node scripts/run-tests.mjs coverage -> 256 files, 5133 tests, 100/100/100/100
  • npm pack --dry-run --silent
  • node dist/cli.js package doctor --project --detail deep --json
  • pm health --check-only --summary --json
  • node scripts/release/sentry-telemetry-gate.mjs --json --telemetry-mode best-effort
  • Manual isolated temp smoke in /tmp/tmp.ExXdcpRd86 with todos package doctor
  • Strict warning-free isolated temp smoke in /tmp/tmp.vRdXivNLZS with item temp-codefactor-lint-zbd9

Notes

  • jscpd currently reports the known 30-clone / 0.34% baseline and fails above the configured 0.35 threshold, so current main passes while new duplication regresses locally and in CI.
  • GitHub issue Auto Release blocked: scheduled run failed #374 remains an external RELEASE_PAT environment blocker; no code-side fix is pending in this branch.

Summary by Sourcery

Introduce a unified local lint command that mirrors CodeFactor maintainability, complexity, and duplication gates and wire it into the documented and automated release workflow.

New Features:

  • Add a top-level pnpm lint script that runs ESLint maintainability rules, duplication checks, and the existing static quality gate in a single command.

Enhancements:

  • Configure ESLint (including unicorn and TypeScript support) and jscpd to align local linting with CodeFactor’s maintainability and duplication signals.
  • Extend testing and release-readiness contracts to validate the presence and shape of the new lint script in package.json.
  • Record CodeFactor-driven complexity and duplication remediation, and the new parity tooling, in the changelog and internal PM artifacts.

Build:

  • Add eslint, eslint-plugin-unicorn, typescript-eslint, jscpd, and shared ESLint/jscpd config to the development toolchain.

CI:

  • Integrate pnpm lint into the main CI static gate so CodeFactor-aligned linting runs on every pipeline.

Documentation:

  • Document the lint workflow in TESTING and RELEASING guides, clarifying how the new lint command maps to CodeFactor parity and existing static quality gates.

Tests:

  • Update CI and release automation integration tests to assert that the new lint command is present and enforced in the workflow.

Chores:

  • Track and close CodeFactor parity, complexity, and duplication chores via updated PM task and history files.

Summary by cubic

Adds a local CodeFactor-parity lint gate with pnpm lint and fixes a Windows atomic write flake by retrying transient rename errors. Aligns jscpd/ESLint generated-directory ignores and updates release docs to reflect the actual static quality gate.

  • New Features

    • Adds pnpm lint composed of lint:eslint, lint:duplicates (jscpd), and lint:codefactor (delegates to quality:static).
    • Adds eslint.config.mjs with CodeFactor-like rules and .jscpd.json (threshold 0.35); mirrors ESLint generated-directory ignores in jscpd.
    • Updates CI to run pnpm lint (replaces quality:static step); updates docs and tests for the new workflow and clarifies the release static gate scope.
  • Bug Fixes

    • Retries transient EPERM/EBUSY on Windows during fs.rename in writeFileAtomic with bounded backoff; adds unit tests. Addresses the Windows regression tracked in pm-2kkl.

Written for commit 11be3ca. Summary will update on new commits.

Review in cubic

Add pnpm lint as a local CodeFactor parity gate backed by ESLint maintainability rules, jscpd duplicate reporting, and the existing static quality profile.

Wire the lint gate into CI, document the workflow, lock the new dev tooling, regenerate the pm-changelog output, and close/release the CodeFactor complexity/duplication/parity PM items with verification evidence.

Verification: pm test pm-6sqo --run --progress; pnpm lint; focused workflow/release contract tests; pnpm typecheck; pnpm quality:static; pnpm contracts:check; pnpm security:scan; pnpm audit --audit-level moderate; pnpm changelog:pm:check; node scripts/run-tests.mjs coverage (100/100/100/100); npm pack --dry-run; package doctor; pm health; Sentry/telemetry gate; isolated temp smokes.
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@sourcery-ai

sourcery-ai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Adds a new pnpm lint command that reproduces CodeFactor maintainability, complexity, and duplication checks locally, wires it into CI and release documentation, and locks in the required ESLint/jscpd tooling and workflow contracts.

Flow diagram for new pnpm lint CodeFactor parity gate

flowchart LR
  Dev[Developer or CI job]
  Dev --> A[pnpm lint]

  A --> B[pnpm lint:eslint]
  A --> C[pnpm lint:duplicates]
  A --> D[pnpm lint:codefactor]

  B --> E[eslint.config.mjs
CodeFactor maintainability rules]
  C --> F[jscpd
.jscpd.json]
  D --> G[static-quality-gate.mjs
--max-complexity 260
--duplicate-window 24
--max-duplicate-chunks 8]

  subgraph CI_static_gate[CI static gate]
    Dev
  end

  subgraph Local_CodeFactor_parity[Local CodeFactor parity]
    A
    B
    C
    D
  end
Loading

File-Level Changes

Change Details Files
Introduce local CodeFactor-parity lint pipeline and supporting configs
  • Add top-level pnpm lint script that chains ESLint, jscpd, and the existing static-quality gate entrypoint with stricter thresholds
  • Define lint:eslint, lint:duplicates, and lint:codefactor helper scripts to separate concerns and reuse existing static gate script with CodeFactor thresholds
  • Add eslint.config.mjs with shared ignores and CodeFactor-aligned maintainability rules for JS/TS using eslint, typescript-eslint, and eslint-plugin-unicorn
  • Add .jscpd.json configuration (and .gitignore/pnpm-lock updates) to support repository-wide duplication detection
package.json
eslint.config.mjs
.jscpd.json
.gitignore
pnpm-lock.yaml
Wire linting into CI and release contracts
  • Update CI workflow static gate job to run pnpm lint before quality:static
  • Extend integration tests to assert pnpm lint is present in CI workflow commands and release automation contracts
  • Ensure release readiness runtime tests assert the exact lint script wiring in package.json
.github/workflows/ci.yml
tests/integration/ci-workflow-contract.spec.ts
tests/integration/release-automation-contract.spec.ts
tests/integration/release-readiness-runtime.spec.ts
Document lint workflow and release gate behavior
  • Update testing docs to include pnpm lint in the standard local verification sequence and describe how it parallels CodeFactor checks versus the static quality gate
  • Update releasing docs to list the new local CodeFactor parity lint gate in the release pipeline and clarify its relationship to the static quality gate
  • Regenerate CHANGELOG to record CodeFactor duplication/complexity fixes and the new parity tooling
docs/TESTING.md
docs/RELEASING.md
CHANGELOG.md
Update PM agent/task history for CodeFactor work items
  • Add or update PM chore/task and history artifacts for CodeFactor parity, complexity reduction, and duplication cleanup work items
.agents/pm/chores/pm-6sqo.toon
.agents/pm/history/pm-6sqo.jsonl
.agents/pm/history/pm-arzz.jsonl
.agents/pm/history/pm-fmjy.jsonl
.agents/pm/tasks/pm-arzz.toon
.agents/pm/tasks/pm-fmjy.toon

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@unbraind

Copy link
Copy Markdown
Owner Author

@codex review
/gemini review
@gemini-code-assist
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a local lint parity command built from ESLint and jscpd, wires it into CI and release/testing docs, updates integration contracts for the new scripts, and closes related tracker records with resolution and evidence metadata.

Changes

Lint parity tooling and workflow

Layer / File(s) Summary
Lint config and scripts
eslint.config.mjs, package.json, .jscpd.json, .gitignore
Adds the ESLint flat config, lint scripts and dependencies, jscpd settings, and the .pnpm-store/ ignore rule.
CI gate and docs
.github/workflows/ci.yml, docs/RELEASING.md, docs/TESTING.md, CHANGELOG.md
Replaces the CI static-analysis command with pnpm lint and updates release, testing, and changelog text to match the lint workflow.
Contract checks
tests/integration/ci-workflow-contract.spec.ts, tests/integration/release-automation-contract.spec.ts, tests/integration/release-readiness-runtime.spec.ts
Updates the CI and release contract tests to require pnpm lint and the new package script strings.

Tracker closeout records

Layer / File(s) Summary
pm-6sqo closeout record
.agents/pm/chores/pm-6sqo.toon, .agents/pm/history/pm-6sqo.jsonl
pm-6sqo is marked closed with resolution, result, evidence, file, test, doc, and close reason fields, and its history gains the related lifecycle and verification entries.
pm-fmjy scope update
.agents/pm/tasks/pm-fmjy.toon, .agents/pm/history/pm-fmjy.jsonl
pm-fmjy is marked closed with narrowed acceptance criteria, resolution, result, and close reason fields, and its history records the related closeout and follow-up entries.
pm-arzz closeout record
.agents/pm/tasks/pm-arzz.toon, .agents/pm/history/pm-arzz.jsonl
pm-arzz is marked closed with resolution, result, and close reason fields, and its history records the related comment, close, and release entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding local CodeFactor parity lint tooling.
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.
Description check ✅ Passed The description accurately matches the changeset: it adds pnpm lint, wires it into CI, updates docs/tests, regenerates the changelog, and closes PM items.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

@unbraind I'll do a full review of this PR again.

✅ Action performed

Full review finished.

@sourcery-ai sourcery-ai 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.

Hey - I've left some high level feedback:

  • The static-quality thresholds (e.g., --max-complexity 260, --duplicate-window 24, --max-duplicate-chunks 8) are now hard-coded both in eslint.config.mjs and the lint:codefactor script; consider centralizing these values (e.g., via a small config module or shared constants) so updating CodeFactor parity thresholds only requires a single change.
  • You’ve added @eslint/js and @typescript-eslint/typescript-eslint as devDependencies but the flat config doesn’t currently extend or use any of their recommended rule sets; if the intent is to mirror only CodeFactor’s maintainability rules, you could either remove unused dependencies or explicitly wire in the presets you intend to rely on.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The static-quality thresholds (e.g., `--max-complexity 260`, `--duplicate-window 24`, `--max-duplicate-chunks 8`) are now hard-coded both in `eslint.config.mjs` and the `lint:codefactor` script; consider centralizing these values (e.g., via a small config module or shared constants) so updating CodeFactor parity thresholds only requires a single change.
- You’ve added `@eslint/js` and `@typescript-eslint`/`typescript-eslint` as devDependencies but the flat config doesn’t currently extend or use any of their recommended rule sets; if the intent is to mirror only CodeFactor’s maintainability rules, you could either remove unused dependencies or explicitly wire in the presets you intend to rely on.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 18 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread .agents/pm/tasks/pm-fmjy.toon Resolved
Comment thread .github/workflows/ci.yml Resolved
@codecov

codecov Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Reuse the shared quality:static profile from lint:codefactor and remove the duplicate CI static gate invocation after pnpm lint. Drop the unused @eslint/js dev dependency and update the release/testing contract docs and tests accordingly.

Also update pm-fmjy acceptance criteria through pm to reflect the narrowed generated-marker remediation scope and record fresh pm-6sqo review-follow-up evidence.
@unbraind

Copy link
Copy Markdown
Owner Author

Review follow-up pushed in a68a93c: addressed Sourcery and cubic feedback, removed duplicate CI static work, and updated PM evidence. Please review the current head again.\n\n@codex review\n/gemini review\n@gemini-code-assist\n@coderabbitai full review\n@coderabbitai review\n@sourcery-ai review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

@unbraind I'll do a full review of the current head, including the follow-up in a68a93c9.

✅ Action performed

Full review finished.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@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 @.jscpd.json:
- Around line 10-19: The jscpd ignore list is missing the generated-directory
exclusions that ESLint already applies, so duplicate scanning can still hit
ignored content. Update the .jscpd.json ignore entries to mirror the
generated-dir patterns from eslint.config.mjs, specifically adding the .codex/**
and .gemini/** paths alongside the existing ignores so the lint workflow stays
consistent.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1ecb08c6-58b7-4501-8950-3abbf90734bc

📥 Commits

Reviewing files that changed from the base of the PR and between 699db57 and a68a93c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • .agents/pm/chores/pm-6sqo.toon
  • .agents/pm/history/pm-6sqo.jsonl
  • .agents/pm/history/pm-arzz.jsonl
  • .agents/pm/history/pm-fmjy.jsonl
  • .agents/pm/tasks/pm-arzz.toon
  • .agents/pm/tasks/pm-fmjy.toon
  • .github/workflows/ci.yml
  • .gitignore
  • .jscpd.json
  • CHANGELOG.md
  • docs/RELEASING.md
  • docs/TESTING.md
  • eslint.config.mjs
  • package.json
  • tests/integration/ci-workflow-contract.spec.ts
  • tests/integration/release-automation-contract.spec.ts
  • tests/integration/release-readiness-runtime.spec.ts

Comment thread .jscpd.json Resolved

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 11 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread docs/RELEASING.md Resolved
Handle transient EPERM/EBUSY failures from Windows fs.rename during atomic writes by retrying with bounded backoff before cleanup.

Covers the PR #383 Windows regression where background test-run record persistence failed on windows-latest with EPERM during rename.

PM: pm-2kkl
@unbraind

Copy link
Copy Markdown
Owner Author

Windows regression follow-up pushed in 68b8631.

Changes since the prior review:

  • added bounded Windows EPERM/EBUSY retry handling to atomic file replacement for background run records
  • added focused fs-utils coverage for transient retry success, retry exhaustion cleanup, and non-transient retry failure cleanup
  • restored full coverage to 100/100/100/100 after the source change

Fresh local verification:

  • PM_RUN_TESTS_SKIP_BUILD=1 node scripts/run-tests.mjs test -- tests/unit/core/fs/fs-utils.spec.ts -> 9 tests passed
  • pm test pm-2kkl --run --progress -> 6 linked tests passed
  • pnpm typecheck
  • pnpm lint
  • pnpm audit --audit-level moderate
  • pnpm security:scan
  • npm pack --dry-run --silent
  • pnpm changelog:pm:check unchanged with pm-changelog 2026.6.20
  • pm health --check-only --summary --json -> ok, 0 warnings
  • pm validate --check-resolution --check-history-drift --json -> ok with known validate_resolution_missing_fields:258 warning; history_drift ok
  • git diff --check
  • node scripts/run-tests.mjs coverage -> 256 files / 5136 tests, 100/100/100/100

@codex review
/gemini review
@gemini-code-assist
@coderabbitai full review
@coderabbitai review
@sourcery-ai review

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

Mirror ESLint generated-directory ignores in jscpd and correct release docs to describe the actual release static quality gate.

Addresses CodeRabbit and cubic PR #383 feedback.

PM: pm-6sqo
@unbraind

Copy link
Copy Markdown
Owner Author

Review follow-up pushed in 11be3ca.

Addressed current review feedback:

  • CodeRabbit: mirrored ESLint generated-directory ignores in .jscpd.json by adding .codex/** and .gemini/**
  • cubic: corrected docs/RELEASING.md to describe the actual release workflow static quality gate instead of implying release.yml runs pnpm lint directly

Fresh focused verification:

  • pnpm lint
  • pnpm quality:docs-links
  • node scripts/run-tests.mjs test -- tests/integration/release-automation-contract.spec.ts tests/integration/ci-workflow-contract.spec.ts tests/integration/release-readiness-runtime.spec.ts -> 3 files / 54 tests
  • pnpm changelog:pm:check unchanged with pm-changelog 2026.6.20
  • git diff --check

@codex review
/gemini review
@gemini-code-assist
@coderabbitai full review
@coderabbitai review
@sourcery-ai review

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

@unbraind I'll re-review the current head, including the follow-up in 11be3cac. Thanks for the fixes and for sharing the focused verification results.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

✅ Action performed

Full review finished.

@unbraind
unbraind merged commit 13c3417 into main Jun 26, 2026
19 checks passed
@unbraind
unbraind deleted the fix/codefactor-parity-lint-tooling branch June 26, 2026 22:57
unbraind added a commit that referenced this pull request Jun 26, 2026
Release pm-2kkl after PR #383 merged while keeping the item open for scheduled Windows nightly confirmation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant