Skip to content

fix: enforce ESLint in CI and add a check-only lint script #101

Description

@EmeditWeb

Problem

The @typescript-eslint/no-explicit-any rule is set to error in .eslintrc.js, and context/code-standards.md states it is "enforced by ESLint, not just documentation." It is not enforced anywhere that can block a merge.

.github/workflows/ci.yml runs three steps: npm ci, npm run build, and npm test. There is no lint step. A pull request reintroducing any passes CI cleanly.

The lint script compounds this. It is eslint "{src,apps,libs,test}/**/*.ts" --fix. Because of --fix, running it locally rewrites files rather than reporting failures, and it does not reliably exit non-zero on violations it cannot auto-fix. There is no check-only variant to call from CI.

The current state of the codebase is genuinely clean. All 32 explicit any usages were removed on 2026-07-16 and grep currently finds zero in src/. That work is unprotected. The next PR can undo it silently.

Ground Rules

This issue must be solved according to StepFi's established engineering standards. Before writing any code:

  1. Read context/architecture-context.md in full
  2. Read context/code-standards.md in full
  3. Read context/progress-tracker.md to understand what has already been built and why, so you do not duplicate or contradict recent work
  4. Read .github/workflows/ci.yml and .eslintrc.js before changing either
  5. Read .github/workflows/ci.yml in the StepFi-Web repo, which already runs npm run lint in CI, and match that approach so the two repos stay consistent

Your PR will be rejected regardless of whether CI passes if it conflicts with anything in these files, introduces patterns inconsistent with what already exists, or duplicates functionality that was solved differently elsewhere in the codebase.

What To Build

  1. Add a lint:check script to package.json: eslint "{src,apps,libs,test}/**/*.ts" --max-warnings=0. No --fix. This is the CI entry point.
  2. Keep the existing lint script with --fix for local developer use. Do not remove it. Developers rely on it.
  3. Add a Lint step to the build-test job in .github/workflows/ci.yml, running npm run lint:check. Place it after Install dependencies and before Build, so a lint failure reports quickly.
  4. Confirm the step actually fails the build. Temporarily introduce an any, push, and verify CI goes red. Include that evidence in the PR description. A lint step that silently passes is worse than none, because it creates false confidence.
  5. Do not add new rules or change rule severities in this PR. Scope is enforcement of the existing configuration only. Rule changes belong in their own issue with their own review.
  6. If lint:check surfaces pre-existing violations in test/ that the *.spec.ts override does not already exempt, fix them in this PR rather than weakening the rule or widening the override.

Files To Touch

  • package.json
  • .github/workflows/ci.yml

Acceptance Criteria

  • npm run lint:check exits non-zero when an explicit any is present in src/
  • npm run lint:check does not modify any file
  • CI runs lint:check on every pull request to main
  • A PR introducing any in src/ fails CI, demonstrated in the PR description
  • The existing lint script with --fix still works for local use
  • No ESLint rules were added, removed, or changed in severity

Mandatory Checks Before Opening PR

  • All context/ files read and understood
  • Code follows context/code-standards.md exactly
  • context/progress-tracker.md updated with an accurate entry describing the change and why
  • Build passes with zero errors (npm run build)
  • All existing tests still pass, test count has not decreased
  • No new any types
  • PR template filled out completely, including the "problem this solves" and "how it was tested" sections
  • PR references this issue number exactly

PRs that fail any check above will be closed without review, regardless of how much work went into them. No exceptions. This is a Grantfox-funded, quality-first project. Code that does not meet these standards will not be merged and will not be paid.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions