# FED-M3-10 — Federation M3 Integration Tests ## Objective Add single-gateway gateway integration tests for M3 acceptance #6 and #7. ## Branch / base - Branch: `feat/federation-m3-integration` - Base: `origin/next` (`838701bd` after M3-06/#683 merge) - PR base when unblocked: `next` ## Scope - Real PostgreSQL via `@mosaicstack/db`. - Mocked TLS context / Fastify request shim for `FederationAuthGuard`. - Direct controller calls using the real M3 route contract: `POST /api/federation/v1/list/:resource` with body `{ limit?, cursor? }`. - Gated by `FEDERATED_INTEGRATION=1`. - No federation harness dependency. ## Fixture notes Aligned with the B2 seed design vocabulary: - `tasks` visibility uses personal `projects` + `missions` chain. - `notes` are `mission_tasks.notes`; the integration suite asserts subject-only note visibility on an authorized mission. - Seed includes a second user and unauthorized team/project tasks to prove exclusion from the max-row-cap list result. - Grants/peers are direct DB fixtures; cert auth still runs through `FederationAuthGuard` using real X.509 certs generated by existing test helpers. ## Current implementation Added `apps/gateway/src/__tests__/integration/federation-m3-list.integration.test.ts` covering: 1. M3 #6 — cert missing Mosaic OIDs returns 401 federation `unauthorized` envelope. 2. M3 #6 — valid cert whose grant row is `revoked` returns 403 federation `forbidden` envelope. 3. M3 #7 — active grant with `max_rows_per_query: 2` caps `list tasks`, returns `_truncated` + `nextCursor`, source-tags rows, and excludes other-user / unauthorized-team tasks. 4. Cross-user notes invariant — subject can list their own `mission_tasks.notes` row while another user's note on the same authorized mission is excluded. 5. Unsupported-resource invariant — `list widgets` fails closed with a federation `scope_violation` envelope. ## Verification - `pnpm --filter @mosaicstack/types build` — PASS. - `pnpm --filter @mosaicstack/db build` — PASS. - `pnpm --filter @mosaicstack/storage build` — PASS. - `pnpm --filter @mosaicstack/brain build` — PASS. - `pnpm --filter @mosaicstack/queue build` — PASS. - `pnpm --filter @mosaicstack/config build` — PASS. - `pnpm --filter @mosaicstack/auth build` — PASS. - `pnpm --filter @mosaicstack/gateway test -- src/__tests__/integration/federation-m3-list.integration.test.ts` — PASS skipped when `FEDERATED_INTEGRATION` unset (5 skipped). - `FEDERATED_INTEGRATION=1 pnpm --filter @mosaicstack/gateway test -- src/__tests__/integration/federation-m3-list.integration.test.ts` — PASS (5 tests) after local `docker compose up -d postgres` + `pnpm --filter @mosaicstack/db db:push`. - `pnpm --filter @mosaicstack/gateway typecheck` — PASS. - `pnpm --filter @mosaicstack/gateway lint` — PASS. - `pnpm format:check` — PASS. - `~/.config/mosaic/tools/codex/codex-code-review.sh --uncommitted` — PASS; approve, no findings. - `~/.config/mosaic/tools/codex/codex-security-review.sh --uncommitted` — PASS; risk level none, no findings. ## Push / PR - #683 landed in `next`; branch rebased onto `origin/next` before push. - CI is serialized; run queue guard before push.