# AwoooP RLS Canary Wave 1.1

This wave targets one low-row non-empty table:

- `awooop_mcp_tool_registry`

It does not include `awooop_projects`.

Status: applied to production on 2026-05-12.

## Why Not `awooop_projects`

`awooop_projects` has only two rows, but it is not safe to enable with a normal
tenant-only policy yet. `platform_operator_service.list_tenants()` currently
uses `get_db_context("awoooi")` while the API contract says Operator Console
returns all projects. A tenant policy on `awooop_projects` would hide the
`ewoooc` row from that endpoint.

Blocker before enabling `awooop_projects`:

- introduce an explicit platform-admin/bypass role path for Operator Console
  cross-tenant reads, or
- redesign list-tenants semantics so it is intentionally tenant-scoped.

## Scope

Latest live evidence before apply:

```text
awooop_mcp_tool_registry: ewoooc=4
```

Runtime read path:

- `McpGateway._gate3_tool()` filters by `ctx.project_id`, `tool_name`, and
  `is_active`.

## Apply

```bash
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 \
  -f scripts/ops/awooop-rls-canary-wave1-1-tool-registry.sql
```

The SQL aborts if:

- table is missing,
- `project_id` is missing,
- any `project_id` is NULL,
- row count exceeds the reviewed canary cap of 20 rows.

## Verification

Expected after apply:

- no context: `awooop_mcp_tool_registry` reads/writes are denied or return no
  rows, depending on query shape and privilege path.
- `app.project_id='ewoooc'`: the four active ewoooc tools are visible.
- `app.project_id='awoooi'`: no ewoooc tools are visible.
- global RLS preflight remains blocked only by later-wave tables.

## 2026-05-12 Production Evidence

Apply completed with `COMMIT` through the 188 postgres/operator socket path.

Post-apply relation state:

```text
awooop_mcp_tool_registry|rls=true|force=true|policies=1|fail_open=false
```

API pod behavior test:

```text
tool_registry_no_context=0
tool_registry_ewoooc_context=4
tool_registry_awoooi_context=0
tool_registry_insert_with_context=allowed_and_rolled_back
tool_registry_probe_rows_after=0
```

Operator/global count:

```text
ewoooc|4
```

Note: after RLS is enabled, API-pod `--exact-counts` are tenant-visible counts,
not global counts. Use postgres/operator evidence for global row-count checks.

## Rollback

```bash
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 \
  -f scripts/ops/awooop-rls-canary-wave1-1-tool-registry-rollback.sql
```

Rollback removes the Wave1.1 policy and disables RLS on
`awooop_mcp_tool_registry`. It does not modify data.
