# Linter Principles

## Outcome

An Astrale domain should naturally compile, lint, and test toward the preferred architecture. Agents
and humans should not need to memorize a long style guide before receiving precise feedback.

Knowledge remains responsible for rationale, examples, and judgment. Mechanically decidable policy
belongs in executable tooling.

## Enforcement order

For every proposed convention, choose the earliest static layer that can enforce it correctly:

1. **SDK** uses its API, TypeScript types, schema compilation, and runtime contracts to reject invalid
   states directly.
2. **Oxlint** reports file-local syntax, scope, or control-flow violations.
3. **Astrale analyzer** reports cross-file, import-graph, schema-aware, or project-shape violations.
A later static layer must not duplicate a diagnostic already owned reliably by an earlier layer. If
none can decide the convention without guessing, keep it in tests, review, or knowledge rather than
weakening the linter.

## Product principles

### One native workflow

Authors run ordinary package scripts. They do not assemble Oxlint plugins, TypeScript parser services,
schema inspectors, or analyzer configuration themselves.

### Prevent before reporting

If an SDK signature can require `authorize`, a linter should not be the primary enforcement mechanism.
If a complete schema-derived handler map can be expressed as a TypeScript type, a filesystem scanner
should not guess whether it is complete.

### High signal

The default decision is not to automate. A rule earns implementation only when the linter can identify
the prohibited state and its legitimate exceptions from machine-visible evidence. Even a useful
principle should remain guidance when detection depends on guessing intent, ownership, or architectural
quality.

An error-level rule must have a deterministic detection contract and a very low false-positive rate.
Warnings are held to the same honesty standard: lower severity does not make recurring false positives
acceptable. Suppressions are an escape hatch for exceptional code, not compensation for a vague rule.

### Stable diagnostics, replaceable engines

Accepted `astrale/<slug>` identifiers are Astrale contracts. Oxlint, a TypeScript project service, or
any future engine is an implementation detail. Changing engines must not rename accepted rules,
suppressions, or CI output.

### Strict defaults, narrow exceptions

New domains receive the strict preset. Configuration exists to describe real domain structure or a
documented exception, not to recreate an arbitrary lint stack. Suppressions are local, reasoned, and
auditable.

### Safe fixes only

`pnpm lint:fix` may apply transformations that preserve behavior and intent. Moving a declaration into
a guessed bounded context, inventing an authorization target, or grouping mutations automatically is
not a safe fix.

### Measured speed

The fast path must remain interactive. New engines or rules are admitted only with cold, warm, and
changed-file measurements against representative domains.

## Rule admission bar

A proposed rule may become `accepted` only when all of the following are true:

- The prohibited behavior has a concrete failure mode.
- The preferred behavior is stable across more than one domain.
- The primary owner is exactly one of `sdk`, `oxlint`, or `analyzer`.
- Valid and invalid examples can be stated without relying on taste.
- Detection does not require guessing business intent.
- Representative legitimate alternatives do not trigger.
- Every documented exception is either machine-visible or explicitly outside the rule's scope.
- The expected prevention value exceeds the cost of review, suppression, maintenance, and lost trust
  from false positives.
- The diagnostic identifies a useful source location and remediation.
- Suppression semantics are defined.
- Runtime and maintenance cost are measured.

## Non-goals

The linter does not:

- Build a new JavaScript or TypeScript parser, formatter, or compiler.
- Replace `tsgo`, Oxlint, Vitest, schema compilation, or live domain verification.
- Infer the correct business bounded context from vocabulary alone.
- Prove that an authorization target expresses the intended business policy.
- Grade visual design quality or domain language by keyword.
- Promise zero migration work for arbitrary repositories that were not scaffolded with the system.
- Turn every recommendation into an error.
