# Check rules

Every rule prongs check applies, by profile: what it catches, how bad it is, and the fix. Each comes from the rule’s own package, so this page lists exactly what check runs.

Errors fail `prongs check`; warnings are reported but pass; info is a note. A deliberate exception takes `// prongs-ignore: <reason>` on the line above, and existing findings can be recorded in a baseline so only new ones fail.

## Every profile

### `unknown-intent` error

An intent that is not in the registry. Suggests the closest names, so a typo is one step from the fix.

Flagged

```tsx
<Action intent="action.delet">Delete</Action>
```

Instead

```tsx
<Action intent="action.delete">Delete</Action>
```

### `internal-intent` error

A ref-only intent (a look, a status, a level) used where code should name a meaning. Suggests the meaning intents built on it.

Flagged

```tsx
<Action intent="control.primary">Save</Action>
```

Instead

```tsx
<Action intent="action.save">Save</Action>
```

### `deprecated-intent` warning

An intent marked deprecated. Suggests the intent its "not for" line points to.

### `unknown-check` warning

An intent asks for a per-intent check its profile does not implement.

## UI

### `raw-element` error

A `<button>`, `<h2>`, `<input>` or styled `<p>`/`<span>`/`<a>` instead of a component. Suggests the closest intents.

Flagged

```tsx
<button className="rounded bg-red-600 px-4 text-white" onClick={remove}>Delete</button>
```

Instead

```tsx
<Action intent="action.delete" onClick={remove}>Delete</Action>
```

### `raw-surface` error

A `<div>` that draws its own box (background, border, shadow). Suggests a Layout intent that says what the region is.

Flagged

```tsx
<div className="rounded-lg border bg-white p-6">…</div>
```

Instead

```tsx
<Layout intent="layout.panel">…</Layout>
```

### `domain-mismatch` error

An intent rendered by the wrong component, like an action on [`<Text>`](https://www.prongs.dev/docs/components/text.md).

Flagged

```tsx
<Text intent="action.save">Save</Text>
```

Instead

```tsx
<Action intent="action.save">Save</Action>
```

### `leaf-classname` error

`className` on [`<Text>`](https://www.prongs.dev/docs/components/text.md), [`<Action>`](https://www.prongs.dev/docs/components/action.md), [`<Field>`](https://www.prongs.dev/docs/components/field.md), [`<Media>`](https://www.prongs.dev/docs/components/media.md), [`<Dialog>`](https://www.prongs.dev/docs/components/dialog.md) or [`<Popover>`](https://www.prongs.dev/docs/components/popover.md), which take intents and layout props only.

Flagged

```tsx
<Text intent="text.caption" className="text-red-600">…</Text>
```

Instead

```tsx
<Text intent="feedback.error">…</Text>
```

### `leaf-style` error

`style` on a component that takes no style. An inline style overrides the intent just like a className.

Flagged

```tsx
<Action intent="action.save" style={{ color: 'red' }}>Save</Action>
```

Instead

```tsx
<Action intent="action.delete">Delete</Action>
```

### `layout-visual-class` error

Colours, type or borders in a [`<Layout>`](https://www.prongs.dev/docs/components/layout.md) className, which is for layout and spacing only.

Flagged

```tsx
<Layout intent="layout.group" className="gap-4 bg-muted">…</Layout>
```

Instead

```tsx
<Layout intent="layout.panel" className="gap-4">…</Layout>
```

### `repeated-tweak` warning

The same layout class added to the same [`<Layout>`](https://www.prongs.dev/docs/components/layout.md) intent in three or more places, across the whole project. Each is allowed, but a tweak that repeats is a missing intent: points to an intent that already has it, or a ready `add-intent` command. `check --suggest` lists these with the overrides.

Flagged

```tsx
<Layout intent="layout.group" className="gap-4">…</Layout>  // and in 15 other places
```

Instead

```tsx
<Layout intent="layout.section">…</Layout>
```

### `raw-style` error

An inline style that sets colour, type or borders. Layout values and CSS variables are fine.

Flagged

```tsx
<div style={{ color: '#c00', fontWeight: 600 }}>…</div>
```

Instead

```tsx
<Action intent="choice.color" vars={{ '--choice-color': color }} />
```

### `unsafe-classname` warning

The escape hatch. A warning with a `// prongs-unsafe: <reason>` comment on the line above, an error without one; counted by `--max-unsafe`.

### `name-mismatch` warning

An action whose handler, label or text points to a different intent, through the intents’ keywords.

Flagged

```tsx
<Action intent="action.save" onClick={shareArticle}>Share</Action>
```

Instead

```tsx
<Action intent="action.share" onClick={shareArticle}>Share</Action>
```

### `raw-look` error

A plain element with look classes that the other rules do not cover: a `<div>` with text colours, a `<span>` drawn as a dot, a styled `<hr>` or `<iframe>`. Inline SVG and the document root are allowed.

Flagged

```tsx
<span className="h-2 w-2 rounded-full bg-[var(--accent)]" />
```

Instead

```tsx
<Text intent="text.indicator" aria-label="Unread" />
```

### `intent-selector` error

CSS or a class that selects elements by `data-intent`. The attribute is for finding elements (analytics, tests, A/B tools); looks come from the registry.

Flagged

```tsx
[data-intent="action.delete"] { color: red; }
```

Instead

```tsx
'action.delete': { refs: ['control.destructive'] }
```

### `unknown-token` error

A registry class that reads a CSS variable nothing declares, so it resolves to nothing. Variables count as declared when a CSS file sets them or code passes them through `vars`.

Flagged

```tsx
'tone.accent': { binding: { classes: 'text-[var(--brand-blue)]' } }
```

Instead

```tsx
'tone.accent': { binding: { classes: 'text-primary' } }
```

### `raw-value` warning

A colour the theme cannot change: a literal (`bg-[#e5383b]`) or a Tailwind palette colour (`text-sky-700`) in a registry class, or a literal colour set as a CSS variable in `style` or `vars`. White and black are allowed.

Flagged

```tsx
'tone.info': { binding: { classes: 'text-sky-700' } }
```

Instead

```tsx
'tone.info': { binding: { classes: 'text-info' } }
```

### `dynamic-intent` info

An intent computed at runtime, so it could not be checked. A ternary of literals can be.

Flagged

```tsx
<Action intent={intentFor(state)}>…</Action>
```

Instead

```tsx
<Action intent={following ? 'action.toggle' : 'action.add'}>…</Action>
```

## Errors

### `raw-error-response` error

An error response written by hand. Suggests the error intents with the same status.

Flagged

```tsx
return NextResponse.json({ ok: false, error: 'Profile not found.' }, { status: 404 });
```

Instead

```tsx
return fail('record.missing', 'Profile not found.');
```

### `leaked-error` error

An error’s own message (`error.message`, `String(err)`) sent to the caller. It can expose internals and changes with every library.

Flagged

```tsx
return NextResponse.json({ ok: false, error: error.message }, { status: 400 });
```

Instead

```tsx
return fail('failure.internal', undefined, { cause: error });
```

### `failure-with-200` warning

`ok: false` or `success: false` answered with 200, which clients and monitoring read as success.

Flagged

```tsx
return Response.json({ success: false, error: message });
```

Instead

```tsx
return fail('failure.internal', message);
```

## Logs

### `raw-console` warning

`console.*` in app code. Nothing says who needs to know, and it may run in production. Scripts, tests, config files and the helpers themselves are left alone.

Flagged

```tsx
console.error('[sync]', error);
```

Instead

```tsx
log('incident.failed', 'Sync stopped', { cause: error });
```

### `swallowed-error` error

A `catch` whose only job is to print the error, so nothing notices the failure.

Flagged

```tsx
try { await sync(); } catch (e) { console.log(e); }
```

Instead

```tsx
try { await sync(); } catch (e) { log('incident.failed', 'Sync stopped', { cause: e }); throw e; }
```

### `secret-in-log` error

Something named like a token, secret, password or cookie passed to a log, unless it goes through a masking function first.

Flagged

```tsx
log('security.token', 'Bad token', { token });
```

Instead

```tsx
log('security.token', 'Bad token', { tokenPresent: Boolean(token) });
```
