fix(collector): exclude the authenticated collecting user from the roster

What

The collector excluded ghost and bot users from the adoption roster but not the authenticated collecting account whose token runs the report. Because the collector requires an instance-admin token (CheckAdmin fetches GET /api/v4/user), the operator -- typically GitLab root (user_id=1) -- was swept into the population and counted as an adopter in their own report. That is the off-by-one behind "dashboard shows 1,001 users but exactly 1,000 were seeded"; it also cascades into the per-user gap count.

Fix

Exclude only the single collecting account, not all admins. A real customer may have admin-developers who are genuine adopters, so dropping every is_admin user would undercount. This drops just the account whose token runs the collection.

  • CheckAdmin now returns (int, error), surfacing the authenticated user's id alongside the admin check.
  • New AuthenticatedUserID helper resolves the same id on the --skip-admin-check path (where CheckAdmin is not called but exclusion must still work). Both share fetchAuthenticatedUser.
  • CollectRoster(ctx, client, cfg, excludeUserID int) skips that user in the filter loop, mirroring the ghost/bot skips. excludeUserID <= 0 excludes no one.
  • The orchestrator captures the id from whichever path runs and threads it into CollectRoster.

Tests

  • Adds TestCollectRoster_ExcludesCollectingUser: drives CollectRoster with a user set that includes the collecting user's id and asserts that user is absent from both the returned roster and identities.json. Verified fail-on-old: with the skip block removed the test goes red (4 users instead of 3, collecting user present); restored and green.
  • Updates roster/orchestrator/incremental/integration/robustness tests for the new signatures, using a dedicated collecting account id distinct from the seeded population (so the seeded admin-developer at id=1 correctly remains an adopter).

Validation

make check (go vet ./... + go test ./... -count=1, no -race) passes; all packages green.

🤖 Generated with Claude Code

Merge request reports

Loading