# `Foresight.Tenancy`
[🔗](https://github.com/fosferon/foresight/blob/v0.3.2/lib/foresight/tenancy/with_tenant_role.ex#L1)

Public tenant-schema provisioning and execution boundaries.

Consumers embedding Foresight should use `provision_mode_c_schema/4` to create
or upgrade a role-neutral Mode C schema. Role and tenant-key lifecycle remains
an opt-in concern of Foresight's HTTP deployment surface.

# `provision_mode_c_schema`

```elixir
@spec provision_mode_c_schema(module(), String.t(), String.t(), keyword()) ::
  {:ok,
   %{tenant_id: String.t(), prefix: String.t(), migrated_versions: [integer()]}}
  | {:error, term()}
```

Installs Foresight's control plane and provisions a Mode C tenant schema.

`:rls_enabled` is required and must be a boolean. The operation deliberately
does not create a PostgreSQL role or a tenant API-key record. It delegates the
schema work to the internal schema provisioner with runtime startup
disabled and returns that provisioner's result:

    {:ok, %{tenant_id: tenant_id, prefix: prefix, migrated_versions: versions}}

Additional options are passed to the schema provisioner. `:repo`,
`:tenant_id`, `:rls_enabled`, and `:start_runtime` cannot be overridden by
those options.

# `reset_connection`

```elixir
@spec reset_connection(pid()) :: :ok
```

Reset all tenant scoping on a freshly checked-out connection.

Used as a Postgrex `after_connect` hook: clears both the role and the
session-level `foresight.tenant_prefix` GUC. Both are set non-`LOCAL`, so if a
scope's `after` cleanup is ever skipped (process killed mid-flight), a stale role
or prefix could otherwise ride a pooled connection into the next tenant's request.

Also applies `hnsw.ef_search = 200` for HNSW recall-quality parity with Hindsight
(`memory_engine.py:1900-1905`) — pgvector's default of 40 under-searches the
per-fact_type semantic ANN queries. Set per connection (persists for its lifetime),
and best-effort: a build without the pgvector HNSW GUC must not kill the connection.

# `with_tenant_role`

```elixir
@spec with_tenant_role(Foresight.Context.t(), (-&gt; result)) :: result when result: var
```

Runs `fun` inside the database scope described by `ctx`.

# `with_tenant_role`

```elixir
@spec with_tenant_role(Foresight.Context.t(), (-&gt; result), keyword()) :: result
when result: var
```

Runs `fun` inside the database scope described by `ctx`.

Options include `:repo` and `:rls_enabled`. An explicitly supplied boolean
`:rls_enabled` always overrides application configuration.

---

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