Skip to content

Both effect-executor fix texts offer only relocation, never a reachable deletion #162

Description

@younna-ai-opencode

labels:
priority: p3
type: documentation
area: tooling
metadata:
pinned_commit: 1574bfa
rule_ids: ["OX-EF2"]

Problem Statement

packages/oxlint-plugins/AGENTS.md carries a rule that a lint rule's fix text must let the reader arrive at "delete it" when the code defends nothing, and forbids a fix whose only outcome is a new address for the same code. Both fix strings shipped by the phase-order work offer exactly one route: move the code somewhere else. An agent that trips either rule goes looking for a new home and never considers that the call, or the phase, should not exist.

Goal

REQUIRES_DESCRIPTION_FIX and IO_IN_PURE_PHASE_FIX each either name deletion as a reachable outcome or state why relocation is the only correct end for that violation, and the fix strings asserted in both RuleTester suites match the shipped text.

Evidence: the rule being broken

  - id: OX-EF2
    title: A fix must be able to end in deletion
    dont: write a `{{fix}}` whose only outcome is a new address for the same code, or one that can be satisfied by editing the offending string instead of the design
    check: "review -- no executable gate exists. Each `_FIX` constant either names deletion as a reachable outcome or states why relocation is the only correct end for that violation."

Source: packages/oxlint-plugins/AGENTS.md:37-42 at 1574bfaa3c95d37c08475aff3806d5cf084c3dd0

Evidence: both shipped fixes are relocation-only

export const IO_IN_PURE_PHASE_FIX =
  "hoist the I/O into the description's read or write phase and pass the value in; a pure phase body must only transform the value it receives" as const

Source: packages/oxlint-plugins/effect-executor/src/rules/executor-no-io-in-filling.config.ts:24-25 at 1574bfaa3c95d37c08475aff3806d5cf084c3dd0

REQUIRES_DESCRIPTION_FIX (executor-requires-description.config.ts:23-24) is the same shape: import Cell, express the call site as a chained description, apply it. Neither string admits that the offending code might simply go.

Orientation

The code cited here lands via branch feat/phase-order-as-description and is not on main yet. Every line reference is pinned to commit 1574bfaa3c95d37c08475aff3806d5cf084c3dd0; read it there.

  • The two constants live in packages/oxlint-plugins/effect-executor/src/rules/*.config.ts. Their exact text is asserted by fixtures in src/rules/__tests__/, so both halves move together.
  • OX-EF2's harm clause records two measured cases where a relocation-shaped fix sent an agent to invent a new home rather than delete: 41 gherkin scenarios restating a lookup table, and executor-import-boundary inducing an import path absent from disk. Those are the failure mode to design against.
  • Sibling _FIX constants elsewhere under packages/oxlint-plugins/*/src/rules/ show the house style; the compliant ones are the pattern to match.
  • This is text-only work. Neither rule's predicate, severity, nor configs.recommended membership is in scope.

Non-Counting Outcomes

  • Appending a bare "or delete it" to each string. The rule asks for a decision procedure that reaches deletion, not a disclaimer.
  • Rewriting the fixture expectations to match new text without changing the text's substance.
  • Changing either rule's check or severity to sidestep the wording question.
  • Adjudicating the other plugins' fix strings here. Repo-wide message work is Rule messages may assert properties their single-file checks cannot decide #139; this issue covers the two constants this branch shipped.

Acceptance Criteria

  • Gatekeeper. pnpm --filter @systemfsoftware/oxlint-plugin-effect-executor test exits 0 with the fixture-asserted fix strings equal to the shipped constants.
  • Each of the two _FIX constants either names deletion as a reachable outcome or states why relocation is the only correct end, judged against the OX-EF2 check text quoted above.
  • Each fix still names the failure mode, so the message stays actionable and is not reduced to a bare rejection.
  • git diff for this work touches message text, its data, and the fixtures asserting it -- no predicate, severity, or registration change.
  • pnpm check:local exits 0 after the last edit, and the package carries a .changeset/ intent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions