GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(eslint-plugin-oracles): load and parse with the consumer's parser by KyleAMathews · Pull Request #13 · TanStack/oracles

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Summary

import oracles from '@tanstack/eslint-plugin-oracles' threw in any repo whose TypeScript is 7 or absent. oracle/no-unit-test imported @typescript-eslint/parser at module load, and that parser refuses TypeScript 7 ("typescript-eslint does not support TS 7.0"). Because of this, every config of the plugin failed to load. The field report came from nanostores, which pins TypeScript 7.0.2.

The rule now parses each imported test module with the parser and parser options that ESLint already uses for the file it lints. It parses through ESLint's own Linter, so any configured parser works, espree included, and the module gets ESLint's scope analysis and parent links. @typescript-eslint/parser moves from dependencies to devDependencies.

The new oracle coverage found two more defects, and the repo's own lint found two problems in the first draft:

  • espree scopes. Under espree, the rule filtered out every reference, because only typescript-eslint's scope manager sets reference.isValueReference. It then reported a reaching test as undeclared. It now treats a reference as a value unless the scope manager marks it otherwise.
  • Silent parse failures. A module that did not parse was skipped silently. Now the rule reports each import, re-export, or star export of a module that does not parse (unparsedModule), with the parser's error. It does this when a file has a test that reaches no part. The rule never throws on it.
  • Typed-lint interference (first draft). A nested parse that kept project: true changed the program that the consumer's type-aware rules read for that module. This happened in typescript-eslint's single-run mode (the CLI and CI). The repo's own eslint . reported strictNullChecks errors. The nested parse now drops project, projectService, and programs, because the rule needs only syntax and scope.
  • Eager reports (first draft). packages/oracles/vitest.oracle-framework.config.mjs (espree) imports the TS ./vite.config. No test depends on that import, so the unparsedModule report applies only when a test is unreached.

Evidence

  • Law:
    1. The plugin and its configs load whether typescript is absent, 5.x, or 7.x (field report round 3).
    2. Rules never throw (maintainer decision 2026-11-08, fix(eslint-plugin-oracles): rules never throw, and oracle rules cannot be disabled inline #6).
    3. An imported module is parsed as ESLint parses the linted file (consumer-parser task).
    4. An unparsed import is reported beside an unreached test.
    5. The nested parse must not change what type-aware rules read.
  • Reach: The new lint.part-reach.parsers family gates espree-oracle, espree-oracle-test-uses-part, and oracle-imports-type-syntax-under-espree (fixed seed: 82, 24, and 56 of 103 histories). lint.part-reach.unparseable-companion gates oracle-imports-unparseable-companion (20). The new lint.part-reach.parser-switch law (one ESLint instance lints the TS oracle file, then the JS one, against the same modules) gates oracle-imports-type-syntax-under-espree (22). The TS environment is a one-shot environment fact. A focused test, tests/consumer-typescript.test.js, covers it with 3 child-process cases.
  • RED: On the d1b508a rule, 13 of 84 tests fail:
    • Absent TS: Cannot find module 'typescript'.
    • TS 7 stub: typescript-eslint does not support TS 7.0.
    • espree: - "unit:t0" + "undeclared:t0".
    • Broken import: - "unparsed:broken.ts" + [].
  • GREEN: The plugin suite passes (17 files, 4310 tests, 2 workers). typecheck, root and package eslint (0 errors), prettier --check, sherif, and publint --strict all pass. In a copy of the nanostores repro, the plugin loads, and it lints an espree-readable oracle file.
  • Mutant: Each mutant fails a named check:
    • (a) top-level parser import restored: consumer-typescript.
    • (b) fixed espree, or fixed typescript-eslint: parsers, parser-switch, and others.
    • (c) a parse error that throws: recorded as threw: by the charge helper.
    • (d) the isValueReference check restored: parsers.
    • (e) a parse cache that ignores the parser: parser-switch.
    • (f) type-aware options kept: typed-lint-isolation.
    • (g) eager reports: parsers and unparseable-companion.
  • Limits:
    • The nested parse uses the linted file's language options, not the imported module's own. A JS oracle that imports a TS module with type syntax cannot follow reach through it, and gets the report when a test is unreached.
    • Only direct declarations are reported. A transitive unparseable module is not.
    • Only two parsers are exercised.
    • The TS 7 check uses a stub of TS 7's shape. The real 7.0.2 package was exercised only in the nanostores copy.
    • ESLint 10 was not run.
    • Under TS 7, typescript-eslint itself cannot load, so a TS 7 repo still cannot lint .ts oracle files with ESLint.

Review round

A code review found no high-severity defect. This PR fixes these findings:

  • Only the read and the parse of an imported module are caught now. An error in the rule's own analysis of a parsed module is a rule bug. The rule no longer reports it as a parse failure.
  • The nested Linter ignores the imported module's eslint comments (noInlineConfig). So they run no core rules and print no environment warnings.
  • The changeset states two behaviors that adopters will see. The rule parses a module with the linted file's parser. Only direct imports report a parse failure.

One finding is older than this PR and is not fixed here: isProductionModule parses a package.json without a guard, so a malformed manifest makes the rule throw. It goes to the follow-up that makes every rule report malformed settings and files instead of throwing. The parse cache compares language options by identity, so a lint that alternates .ts and .tsx files parses shared helpers again. That costs time only, and the cache holds one entry for each file.

Code weight

no-unit-test.js grows by 269 bytes min+gzip (5833 to 6102). The plugin no longer installs @typescript-eslint/parser and its tree (about 2.5 MB), or that tree's typescript peer. Removing setParents paid for part of the growth, because ESLint's Linter sets parents. The rest is the fatal-message check, the type-aware option strip, the report, and the cache key.

For the maintainer

  • Check law 4: the unparsedModule report applies only when a test in the file reaches no part. The brief asked for a report on every parse failure. That broke the repo's own lint on a legal JS config that imports a TS config.
  • Check the type-aware option strip (law 5). It departs from "use its parserOptions" for those three keys.
  • Consider docs for TS 7 adopters. With this fix the plugin loads, but typescript-eslint does not support TS 7.0, so .ts oracle files need the TS 6 side-by-side setup that typescript-eslint documents.

This pull request and its description were written by Isaac.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
KyleAMathews and others added 2 commits November 10, 2026 19:02
@KyleAMathews Isaac
fix(eslint-plugin-oracles): load and parse with the consumer's parser
f6ffc96
`oracle/no-unit-test` imported `@typescript-eslint/parser` at module load.
That parser refuses TypeScript 7, so importing the plugin, and every one of
its configs, threw in a repository that pins TypeScript 7.0.2 (field report
round 3, nanostores). It also threw when `typescript` was absent.

The rule now parses each imported test module with the parser and parser
options that ESLint uses for the file it lints, through ESLint's own Linter,
so any configured parser works, espree included. The parse cache is keyed on
those language options too. typescript-eslint's type-aware options are left
out of that parse: the rule reads syntax and scope only, and a nested
`project` parse changed the program that type-aware rules then read (single-
run mode). `@typescript-eslint/parser` moves to devDependencies.

Also fixed, found by the extended oracle: under espree the rule dropped every
reference (espree scopes have no `isValueReference`) and reported reaching
tests as undeclared. And a module that did not parse was skipped silently:
when a test reaches no part, each import of a module that the file's parser
cannot read is now reported (unparsedModule) with the parser's error. The rule
never throws on it.

Evidence

- Law: the plugin loads whatever the consumer's TypeScript (field report);
  rules never throw (maintainer decision 2026-11-08, #6); an imported module
  is parsed as ESLint parses the linted file (consumer-parser task). The
  narrowing of the report to files with an unreached test, and the strip of
  type-aware options, need maintainer confirmation.
- Reach: new lint.part-reach.parsers family gates espree-oracle,
  espree-oracle-test-uses-part, oracle-imports-type-syntax-under-espree
  (fixed seed 82, 24, 56 of 103); unparseable-companion gates
  oracle-imports-unparseable-companion (20); new parser-switch law gates the
  type-syntax state (22). The TS environment is a focused test
  (consumer-typescript.test.js, 3 child-process cases).
- RED (d1b508a rule): 13 of 84 fail. TS 7 stub: "typescript-eslint does not
  support TS 7.0."; absent: "Cannot find module 'typescript'"; espree:
  "unit:t0" read as "undeclared:t0"; broken import: "unparsed:broken.ts"
  missing.
- GREEN: plugin suite 17 files, 4310 tests; typecheck, eslint, prettier,
  sherif, publint clean. A copy of the nanostores repro loads the plugin and
  lints an espree-readable oracle file.
- Mutant: top-level parser import (consumer-typescript), fixed espree or
  fixed typescript-eslint (parsers, parser-switch), a throwing parse error
  (charged as threw:), the old isValueReference test (parsers), a cache that
  ignores the parser (parser-switch), kept type-aware options
  (typed-lint-isolation), eager reports (parsers, unparseable-companion).
- Limits: the linted file's options, not the imported module's own, so a JS
  oracle importing a TS module with type syntax gets the report when a test
  is unreached; transitive unparseable modules are not reported; two parsers;
  a stub of TS 7's shape; ESLint 10 not run. Under TS 7, typescript-eslint
  itself cannot load, so .ts oracle files still cannot be linted there.
  no-unit-test.js grows 269 bytes min+gzip; the install drops the
  @typescript-eslint/parser tree.

Co-authored-by: Isaac <[email protected]>
@KyleAMathews Isaac
fix(eslint-plugin-oracles): report only parse failures as unparsed; i…
24fbde4
…gnore inline config in imported modules

Review round on the consumer-parser change:
- Only reading and parsing an imported module is caught. An error in the
  rule's own analysis of a parsed module is a rule bug and is no longer
  reported as a parse failure.
- The nested Linter ignores the imported module's eslint comments
  (noInlineConfig), so they run no core rules and print no env warnings.
- The changeset states the two behaviors to expect: a module is parsed with
  the linted file's parser, and only direct imports report a parse failure.

Co-authored-by: Isaac <[email protected]>
@changeset-bot

changeset-bot Bot commented Nov 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 24fbde4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tanstack/eslint-plugin-oracles Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@coderabbitai

coderabbitai Bot commented Nov 11, 2026

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 181f371c-efda-4c1c-9f48-81875cc290f9
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

  • X
  • Mastodon
  • Reddit
  • LinkedIn
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pkg-pr-new

pkg-pr-new Bot commented Nov 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/TanStack/oracles/@tanstack/eslint-plugin-oracles@13
npm i https://pkg.pr.new/TanStack/oracles/@tanstack/oracles@13

commit: 24fbde4

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@KyleAMathews
KyleAMathews merged commit 745502b into main Nov 11, 2026
8 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@KyleAMathews
KyleAMathews deleted the fix/plugin-consumer-parser branch November 11, 2026 02:32
KyleAMathews added a commit that referenced this pull request Nov 11, 2026
@KyleAMathews Isaac
docs(oracles): write the general law down, and trigger the design gra…
573c671
…mmar

Agents go from examples to a general law only when made to write it
down, and no agent in three validation rounds opened the design-grammar
card, because it triggered on judgment ("a hard law").

- Design step 1: before the law sheet, each law gets a written block:
  the examples with sources, what varies and what stays, the law as one
  "For every ..." sentence with its edges, a new case it predicts, and
  every example rebuilt from the sentence alone.
- Five concrete triggers send the agent to the design-grammar card; the
  evidence says which fired.
- Review: "Law as examples" and "Skipped design grammar" findings.
- Evaluate-review: the causal condition is written as a sentence over
  histories, with a second history it predicts.
- Setup: TypeScript 7 is an environment limit (typescript-eslint), and
  the plugin's `unparsedModule` report for a `.js` oracle file that
  imports TypeScript (#13).
- Design: the interim exit-wording bullet is gone with #12; the rule not
  to write those words in a report stays.

Co-authored-by: Isaac <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@KyleAMathews
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.