# `Bylaw.Credo.Check.Elixir.NoLowLevelProcessPrimitives`
[🔗](https://github.com/ryanzidago/bylaw/blob/v0.1.0-alpha.1/lib/bylaw/credo/check/elixir/no_low_level_process_primitives.ex#L1)

## Basics

> #### This check is disabled by default. {: .neutral}
>
> [Learn how to enable it](`e:credo:config_file.html#checks`) via `.credo.exs`.

This check has a base priority of `high` and works with any version of Elixir.

## Explanation

Disallows direct usage of `Process`, `GenServer`, and `:ets`.

## Examples

Avoid:

      Process.put(:current_tenant, tenant_id)
      GenServer.call(MyApp.Registry, {:lookup, key})
      :ets.lookup(:cache, key)

Prefer:

      fetch_tenant(conn)
      MyApp.Registry.lookup(key)
      Cache.fetch(key)

## Notes

Stateful and process-based primitives are **exceptions, not
defaults**. They exist for very specific use cases and should only
be introduced after gaining explicit approval.

Most of the time the right answer is simpler than you think - plain
functions, passing values through arguments, or returning data from
the caller is almost always preferable to reaching for `Process`,
`GenServer`, `:ets`, or any other stateful primitive.

Note: `Agent` is not flagged because it cannot be reliably
distinguished from aliased application modules (e.g.
`MyApp.Agents.Agent`) at the AST level. `Task` is also not
flagged - it is a reasonable concurrency tool that does not
introduce hidden state.

**Before adding process-level machinery, ask yourself:**

1. Can I solve this with a plain function and its arguments?
2. Am I introducing state/concurrency where none is needed?
3. Have I gotten explicit approval to use process primitives here?

If the answer to all three is "yes, I really need this", disable the
check for the call site:

      # credo:disable-for-next-line Bylaw.Credo.Check.Elixir.NoLowLevelProcessPrimitives
      Process.put(:key, value)

Path exclusions are matched against the source filename and are intended for generated files or temporary migration areas.

The check uses static AST analysis, so dynamic code generation and macro-expanded code may fall outside its signal.

## Options

Configure options in `.credo.exs` with the check tuple:

```elixir
%{
  configs: [
    %{
      name: "default",
      checks: [
        {Bylaw.Credo.Check.Elixir.NoLowLevelProcessPrimitives,
         [
           excluded_paths: ["test/support/"]
         ]}
      ]
    }
  ]
}
```

- `:excluded_paths` - List of path prefixes or regexes to exclude from this check.

## Usage

Add this check to Credo's `checks:` list in `.credo.exs`:

```elixir
%{
  configs: [
    %{
      name: "default",
      checks: [
        {Bylaw.Credo.Check.Elixir.NoLowLevelProcessPrimitives, []}
      ]
    }
  ]
}
```

## Check-Specific Parameters

Use the following parameters to configure this check:

### `:excluded_paths`

  List of path prefixes or regexes to exclude from this check.

*This parameter defaults to* `[]`.

## General Parameters

Like with all checks, [general params](`e:credo:check_params.html`) can be applied.

Parameters can be configured via the [`.credo.exs` config file](`e:credo:config_file.html`).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
