feat(federation): two-gateway test harness scaffold (FED-M3-02) #505

Merged
jason.woltje merged 3 commits from feat/federation-m3-harness into main 2026-04-24 03:01:26 +00:00
Owner

Summary

Adds tools/federation-harness/ — permanent M3+ federation E2E test bed.

  • docker-compose.two-gateways.yml: gateway-a/b each with Postgres+pgvector+Valkey, shared Step-CA; image digest-pinned (sha256:1069117740e00ccfeba357cae38c43f3729fe5ae702740ce474f6512414d7c02, sha-9f1a081 post-#491)
  • seed.ts: provisions scope variants A/B/C via real admin REST API; full enrollment flow (peer keypair to grant to token to redeem to cert store)
  • harness.ts: bootHarness/tearDownHarness/serverA/serverB/seed helpers for vitest; idempotent boot
  • README.md: prereqs, topology, troubleshooting, vitest integration

Scope variants

Variant Resources Filters Excluded
A tasks, notes include_personal: true (none)
B tasks include_teams: T1, no personal (none)
C tasks, credentials include_personal: true credentials

Bugs found in production code (NOT fixed - tooling-only PR)

  1. FederationController.generateToken derives enrollment URL from BETTER_AUTH_URL env - defaults to http://localhost:14242 when unset, wrong inside Docker network.
  2. Admin guard header name (x-admin-key) not documented in controller; seed assumes this header.

Test plan

  • docker compose up -d: 7 services come healthy
  • pnpm tsx tools/federation-harness/seed.ts: 3 grants enrolled
  • docker compose down -v: clean teardown
  • bootHarness() twice: second call returns ownedStack: false
  • pnpm typecheck / pnpm lint / pnpm format:check: all green

Followups

  • Image digest staleness: update if new build promoted before M3-11
  • Port collision: env var overrides documented in README
  • Subject user UUIDs are placeholders; M3-11 replaces with real auth API user creation

Closes #462

## Summary Adds tools/federation-harness/ — permanent M3+ federation E2E test bed. - docker-compose.two-gateways.yml: gateway-a/b each with Postgres+pgvector+Valkey, shared Step-CA; image digest-pinned (sha256:1069117740e00ccfeba357cae38c43f3729fe5ae702740ce474f6512414d7c02, sha-9f1a081 post-#491) - seed.ts: provisions scope variants A/B/C via real admin REST API; full enrollment flow (peer keypair to grant to token to redeem to cert store) - harness.ts: bootHarness/tearDownHarness/serverA/serverB/seed helpers for vitest; idempotent boot - README.md: prereqs, topology, troubleshooting, vitest integration ## Scope variants | Variant | Resources | Filters | Excluded | |---------|-----------|---------|----------| | A | tasks, notes | include_personal: true | (none) | | B | tasks | include_teams: T1, no personal | (none) | | C | tasks, credentials | include_personal: true | credentials | ## Bugs found in production code (NOT fixed - tooling-only PR) 1. FederationController.generateToken derives enrollment URL from BETTER_AUTH_URL env - defaults to http://localhost:14242 when unset, wrong inside Docker network. 2. Admin guard header name (x-admin-key) not documented in controller; seed assumes this header. ## Test plan - docker compose up -d: 7 services come healthy - pnpm tsx tools/federation-harness/seed.ts: 3 grants enrolled - docker compose down -v: clean teardown - bootHarness() twice: second call returns ownedStack: false - pnpm typecheck / pnpm lint / pnpm format:check: all green ## Followups - Image digest staleness: update if new build promoted before M3-11 - Port collision: env var overrides documented in README - Subject user UUIDs are placeholders; M3-11 replaces with real auth API user creation Closes #462
jason.woltje added 1 commit 2026-04-24 01:23:38 +00:00
feat(federation): two-gateway test harness scaffold (FED-M3-02)
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/pr/ci Pipeline failed
3bfd5195b2
Adds tools/federation-harness/ — the permanent test bed for M3+ federation
E2E tests. Boots two gateways (Server A + Server B) on a shared Docker bridge
network with per-gateway Postgres/pgvector + Valkey and a shared Step-CA.

- docker-compose.two-gateways.yml: gateway-a/b, postgres-a/b, valkey-a/b,
  step-ca; image digest-pinned to sha256:1069117740e... (sha-9f1a081, #491)
- seed.ts: provisions scope variants A/B/C via real admin REST API; walks
  full enrollment flow (peer keypair → grant → token → redeem → cert store)
- harness.ts: bootHarness/tearDownHarness/serverA/serverB/seed helpers for
  vitest; idempotent boot (reuses running stack when both gateways healthy)
- README.md: prereqs, topology, seed usage, vitest integration, port override,
  troubleshooting, image digest note

No production code modified. Quality gates: typecheck ✓ lint ✓ format ✓

Closes #462

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jason.woltje added 1 commit 2026-04-24 01:35:45 +00:00
fix(federation): harness CRIT bugs — admin bootstrap auth + peer FK + boot deadline (review remediation)
Some checks are pending
ci/woodpecker/push/ci Pipeline is running
ci/woodpecker/pr/ci Pipeline is running
190f12a971
CRIT-1: Replace nonexistent x-admin-key header with Authorization: Bearer <token>;
add bootstrapAdmin() to call POST /api/bootstrap/setup on each pristine gateway
before any admin-guarded endpoint is used.

CRIT-2: Fix cross-gateway peer FK violation — peer keypair is now created on
Server B first (so the grant FK resolves against B's own federation_peers table),
then Server A creates its own keypair and redeems the enrollment token at B.

HIGH-3: waitForStack() now polls both gateways in parallel via Promise.all, each
with an independent deadline, so a slow gateway-a cannot starve gateway-b's budget.

MED-4: seed() throws immediately with a clear error if scenario !== 'all';
per-variant narrowing deferred to M3-11 with explicit JSDoc note.

Also: remove ADMIN_API_KEY (no such path in AdminGuard) from compose, replace
with ADMIN_BOOTSTRAP_PASSWORD; add BETTER_AUTH_URL production-code limitation
as a TODO in the README.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jason.woltje added 1 commit 2026-04-24 02:13:49 +00:00
fix(federation): harness round-2 — email validation + host-side URL rewrite
Some checks failed
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/push/ci Pipeline failed
dc122e138b
- Bug-1: replace whitespace in admin email local-part (was breaking @IsEmail)
- Bug-2: rewrite enrollment URL to use host-accessible base in seed.ts (in-cluster URL not resolvable from host)
- Bug-3: correct README Known Limitations section
- eslint.config.mjs: add tools/federation-harness/*.ts to allowDefaultProject so pre-commit hook can lint harness scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jason.woltje force-pushed feat/federation-m3-harness from dc122e138b to 4cf9362e75 2026-04-24 02:55:11 +00:00 Compare
jason.woltje merged commit 89c733e0b9 into main 2026-04-24 03:01:26 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#505