Skip to content

chore(lint): forbid bare as casts (blindCast + ratchet), ported from prisma-next - #14

Closed
wmadden-electric wants to merge 1 commit into
mainfrom
claude/no-bare-cast-lint
Closed

chore(lint): forbid bare as casts (blindCast + ratchet), ported from prisma-next#14
wmadden-electric wants to merge 1 commit into
mainfrom
claude/no-bare-cast-lint

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

Imports prisma-next's bare-as-cast enforcement into makerkit, adapted to this repo.

What lands

  • UtilitiesblindCast<T, "Reason"> / castAs<T> in @makerkit/core/casts, plus assertDefined / invariant in @makerkit/core/assertions as the safe narrowing alternatives.
  • Biome pluginbiome-plugins/no-bare-cast.grit fires on every bare as (except as const) in production files, at info severity so it never breaks a build. Test files are exempt; the exclusion regexes mirror this repo's existing overrides test-file patterns.
  • CI ratchetpnpm lint:casts counts plugin diagnostics at HEAD vs the PR base and fails on any per-PR increase. A PR-only cast-ratchet CI job runs it; pnpm test:scripts covers the ratchet itself (8 unit tests).
  • Rules docs.cursor/rules/no-bare-casts.mdc + type-predicates.mdc.

Notes for review

  • Self-bootstrapping. The ratchet scans the base in a temp worktree using HEAD's config + plugin (copied in, auto-discovered), so the base is measured under the new rule even though it predates it. The repo's ~43 existing casts become the baseline (delta=0); only new casts fail.
  • Config anchoring. Copying the config into each scanned tree (rather than --config-path) is deliberate: it anchors this repo's relative files.includes excludes (!docs, !prisma-next) to the same root for both scans, so the two counts are comparable. An empty .gitignore is dropped into fixture trees that lack one (vcs.useIgnoreFile requires it).
  • Credential-free CI. The ratchet job points origin/main at the PR base sha (already in history via fetch-depth: 0), so it needs no authenticated fetch and keeps persist-credentials: false.
  • Deliberately dropped from the prisma-next port: as-contract-cast-smell.mdc (about prisma-next's schema-Contract serializer seam, unrelated to makerkit's R6 Contract) and the standalone plugin fixtures dir (the ratchet test is self-contained, avoiding a lint-staged config).

🤖 Generated with Claude Code

Forbid bare `as` casts in production TS in favour of auditable helpers.

- blindCast<T, "Reason">/castAs<T> in @makerkit/core/casts, plus
  assertDefined/invariant in @makerkit/core/assertions as the safe
  narrowing alternatives.
- no-bare-cast GritQL Biome plugin (info severity; test files exempt,
  matching the existing biome test-file overrides).
- lint:casts CI ratchet + unit tests: counts plugin diagnostics at HEAD
  vs the PR base and fails on any per-PR increase. Scans the base in a
  worktree using HEAD's config+plugin, so it self-bootstraps — the 59
  existing casts are the baseline, delta=0.
- PR-only cast-ratchet CI job (credential-free: points origin/main at the
  base sha already in history) + .cursor rules docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@wmadden-electric

Copy link
Copy Markdown
Contributor Author

Folded into #13 rather than landing separately. The cast machinery and the R6 cast cleanup now live in #13: R6 no longer adds bare as casts (net -4 vs main), so the ratchet passes there. Keeping it one PR per your call. Closing this.

@wmadden-electric
wmadden-electric deleted the claude/no-bare-cast-lint branch July 9, 2026 06:51
wmadden-electric added a commit that referenced this pull request Jul 23, 2026
The port's "app code unchanged" constraint was dropped; open-chat now
consumes the service node directly and the launcher/env-shim scaffolding
is gone. One capability gap remains as finding #14: the hydrated
StreamsClient has no routing-key support and no public accessor for its
raw connection values, so an app multiplexing chats over one per-user
stream must keep the configKey() reach-around.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
wmadden-electric added a commit that referenced this pull request Jul 23, 2026
The port's "app code unchanged" constraint was dropped; open-chat now
consumes the service node directly and the launcher/env-shim scaffolding
is gone. One capability gap remains as finding #14: the hydrated
StreamsClient has no routing-key support and no public accessor for its
raw connection values, so an app multiplexing chats over one per-user
stream must keep the configKey() reach-around.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
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.

2 participants