Legend Populate Script — 30/30 Personas Complete

Status: ✅ 30/30 personas fully provisioned across all 7 services (0 errors)

Run date: 2026-05-20

Summary

scripts/legend-populate.py creates 10 users × 3 personas = 30 personas total. Each persona is registered for and uses:

  • Mailcow (mailbox auto-created via VDI launch → ensurePersonaMailbox)
  • Mattermost (self-signup + post to town-square)
  • Mastodon (account via tootctl + Rails token + post)
  • phpBB (account creation + test post)
  • HumHub (account creation + post)
  • Wallabag (account + bookmark save)
  • Pixelfed (account + photo post)

All credentials saved to vault via orchestrator API.

Fixes Applied This Run

Infrastructure

  • Mailcow domain limit: Raised legend.local mailbox limit from 20 → 100 via Mailcow API
  • VDI service IP exhaustion: Added cleanup_vdi_pods() at script start to delete all vdi-p-* pods/svcs (was: 170 stale pods exhausting ClusterIP range)
  • Keycloak token expiry: Now refreshes admin token before EVERY user (was: every 2 users → 404s for later users)

Mattermost

  • Bot now adds new users to default team before posting (new MM users have no team membership)
  • Bot fetches town-square channel ID via /teams/{id}/channels/name/town-square

Mastodon

  • Switched from API registration (5/hour rate limit) to tootctl accounts create (no rate limit)
  • Switched from password grant (not supported) to Rails Doorkeeper::AccessToken.find_or_create_for
  • Changed email domain from .local (fails MX) to @legend.paralla.org
  • Fixed pod label selector: app=mastodon,component=web (not app=mastodon-web)
  • Fixed X-RateLimit-Reset parsing: ISO 8601 string, not Unix timestamp

Pixelfed

  • Added --confirm_email=1 to artisan user:create (required flag)
  • OAuth password grant uses email address, not username
  • Duplicate user detection now checks for “duplicate”, “unique”, “1062” (not just “already”)

Wallabag

  • Fixed client_id format: 1_legend_test_client_2024 (FOSOAuthServerBundle {id}_{random_id} format)
  • Admin password: Legend2024! (not default wallabag)

Orchestrator Vault Save

  • Script sends password_encrypted field (deployed pod only reads this field, not password)

Known Issues / Deferred

  • Deployed orchestrator image is stale: Git has password || password_encrypted fallback fix but deployed image does not. Needs CI rebuild.
  • Hooks proxy allowlist: Currently uses blocklist (LOCAL_API_ROUTES). Proposed to pvs to convert to allowlist — awaiting approval.
  • Pixelfed artisan cache: Routes are ephemeral in pod fs. Need php artisan config:clear && route:clear && route:cache after each pod restart.

Script Location

/home/claude/code/legend/scripts/legend-populate.py