Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Flake in `tests/test_store.py::test_do_cleanup_logs_errors`.** Test was using the `caplog.at_level(...)` context manager plus `caplog.text` substring check. That pattern failed intermittently on CI (observed on Python 3.11 and 3.14) even though the code under test (`_do_cleanup`) is fully synchronous — the flake was in pytest's log-capture path, not in the production code. Rewritten to use `caplog.set_level(...)` at fixture scope and inspect `caplog.records` directly (logger name + level + message substring), which is sturdier across pytest/Python versions and produces a richer failure message when it does fire. Verified 10/10 consecutive local runs post-fix. Closes [#374](https://github.com/cmeans/mcp-awareness/issues/374).

### Security
- **RLS background-thread + pool edge-case coverage** — new `tests/test_rls_background.py` (11 tests) covers the execution contexts the request-path `rls_store` fixture doesn't exercise: the `_do_cleanup` daemon thread, the `upsert_embedding` path used by `server._embedding_pool`, and Postgres's transaction-local `set_config` semantics plus the combined pool/Postgres contract. Four cleanup tests and two embedding tests verify the full owner-scoped call paths (RLS policy + explicit `WHERE owner_id = %s` SQL filter + request-path `_set_rls_context`) catch cross-tenant regressions — tests pass only when all three defenses are intact, acknowledging the layered design rather than claiming any single layer is independently load-bearing. Five pool-guarantee tests: two use a raw `psycopg.connect` to directly verify Postgres's `set_config(..., is_local)` semantic (the `true` variant does NOT survive COMMIT; the `false` variant does), isolating the Postgres contract from `psycopg_pool`'s `RESET ALL` check-in reset; the remaining three codify the *combined* pool+Postgres behavior (no RLS residue across checkouts, after ROLLBACK, or across concurrent threads). Test-only change; no production code modified. ~2.6 s added to the suite; full suite: 998 → 1000 passing. Module docstring captures the audit summary: cleanup's owner enumeration relies on the pool role having `BYPASSRLS`, the per-owner DELETE is doubly scoped; embedding upsert is doubly scoped (SQL `owner_id = %s` + `_set_rls_context`). Closes R2 of [#359](https://github.com/cmeans/mcp-awareness/issues/359); closes [#362](https://github.com/cmeans/mcp-awareness/issues/362).
- **RLS migration-safety test** — new `tests/test_rls_migration_safety.py` walks the Alembic migration path (`N-1 → head`) with two-tenant data seeded at N-1, then asserts tenant isolation still holds after applying the head migration. Catches the class of bugs where a future migration regresses an RLS policy, weakens a `WITH CHECK`, renames `app.current_user`, or adds a new owner-scoped table without `ENABLE ROW LEVEL SECURITY` — failures no scanner catches at authoring time. Each test runs in its own database (`CREATE DATABASE` / `DROP DATABASE` inside the shared `pg_container`) for full isolation. ~2.5 s added to the suite. Closes R3 of [#359](https://github.com/cmeans/mcp-awareness/issues/359) (RLS harness coverage extension tracking); closes [#360](https://github.com/cmeans/mcp-awareness/issues/360). A follow-up companion test for the `_system`-schema carve-out migration specifically was prototyped but deferred — hit an unresolved FORCE-RLS/BYPASSRLS interaction on Postgres 17 during seed-path development; the core isolation invariant this PR ships is the scope R3 promised.
- **Third-party GitHub Actions pinned to full commit SHAs** (instead of floating `@vN` major-version tags). A moving major-version tag on a third-party action is an unreviewed supply-chain channel — the upstream owner can move the tag to any commit at any time, including after a repo compromise. Pinning to the commit SHA freezes the code under review. Affected references in `.github/workflows/`:
- `codecov/codecov-action@v6` → `@57e3a136…` (v6.0.0) in `ci.yml`
Expand Down
Loading
Loading