Skip to content

Define canonical formatter ownership across editors, hooks, tasks, and CI #53

Description

@szmyty

Outcome

Define and prove one deterministic formatter-ownership contract so VS Code format-on-save, editor extensions, local tasks, hooks, EgoLint/MegaLinter, and Relay CI never compete over the same files.

Context

The universal MegaLinter convergence exposed a recurring class of formatter wars: multiple tools can technically format the same language, but running all of them creates churn, contradictory diffs, and poor developer experience.

Examples include:

  • Ruff versus Black/isort for Python;
  • Biome versus Prettier/ESLint assists for JavaScript/TypeScript/JSON;
  • language-native formatters versus generic Prettier coverage;
  • MegaLinter fix mode versus editor format-on-save;
  • native Taskfile fallback formatters where MegaLinter descriptors are incomplete.

The repository already prefers explicit ownership, deterministic builds, local/CI parity, and editor integration. This issue turns those preferences into a versioned contract.

Scope

Ownership matrix

For every supported language/file class, record:

  • canonical formatter;
  • compatibility/legacy formatter(s);
  • lint-only tools that must not format;
  • whether safe autofix is supported;
  • editor language ID and recommended extension;
  • Taskfile/EgoLint command;
  • hook behavior;
  • CI check/fix-preview behavior;
  • applicability/profile conditions.

Required behavior

  • Exactly one default formatter owns any given applicable file class.
  • Compatibility tools remain invokable without participating in default format-on-save or default fix flows.
  • Editor configuration derives from the same ownership matrix used by CLI/CI.
  • Format-on-save, code actions, import organization, and lint autofixes are distinguished explicitly.
  • CI validates formatting without mutating pull-request worktrees.
  • Local fix commands produce the same formatting result as the editor and CI checks.
  • Generated, vendored, fixtures, and intentionally preserved formatting exceptions remain explicit.

VS Code integration

  • Generate/validate recommended extensions and editor.defaultFormatter mappings from the canonical matrix.
  • Validate configured files.associations language IDs against installed/known contributions where feasible.
  • Add an EgoLint command such as egolint vscode validate or equivalent rather than relying on hand-maintained drift-prone settings.

Hooks and tasks

  • Define staged-file behavior and whether formatting is check-only or write-enabled locally.
  • Keep hooks fast and bounded; full repository formatting remains an explicit command.
  • Preserve long-form, discoverable task names and stable EgoLint commands.

Acceptance criteria

  • A versioned formatter ownership matrix covers every supported file class.
  • No default profile invokes two competing formatters for the same file.
  • Ruff/Black/isort compatibility behavior is explicit.
  • Biome/Prettier/Oxlint/ESLint ownership composes with Add a JavaScript package-quality profile with Oxlint, Biome, and publint #13.
  • VS Code recommendations and default formatter mappings are generated or validated from canonical policy.
  • Local tasks, hooks, editor behavior, MegaLinter/EgoLint, and Relay checks produce equivalent formatting decisions.
  • CI never mutates the source worktree as part of validation.
  • Fix-preview and explicit local write operations remain reviewable and reversible.
  • Fixtures prove at least Python, JavaScript/TypeScript, JSON/YAML, Markdown, shell, and one native-language formatter path.

Related

Non-goals

  • Requiring one formatter implementation for every language.
  • Keeping legacy formatters active merely because they are installed.
  • Allowing editor settings to become a second source of lint/format policy.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions