feat(seeder): add additive growth pass for trend detection

Why

The dashboard's Trends view is empty. Trends are computed by comparing the current analysis run against a previous run dir, but the demo is a single snapshot: all seeded activity is timestamped at collection time, so the collector cannot date-window an earlier snapshot.

What

A two-phase additive seed. After the baseline seed and a first collect/analyze (snapshot A), a new growth pass adds modest activity to a deterministic subset of the existing non-dormant seeded users. A second collect/analyze with the previous-dir pointing at snapshot A then shows those users' scores rising (genuine improving trajectories) while the rest stay stable. The pass is purely additive, so there are no declines (expected and accepted).

New seed-growth subcommand and seeder.RunGrowth

  • Discovers existing seeded groups/projects/users via the API (no recreation, no clean). Parses each archetype from the manifold-<archetype>-NN username and reconstructs group memberships from the API.
  • Deterministically selects a --fraction (default 0.40) of non-dormant users via a seeded RNG (--seed). Dormant experts stay dormant.
  • Mints a fresh PAT per subset user, reusing the existing createUserPAT.
  • Adds small per-user volumes (1-3 MRs, 2-4 pipelines, a few pushes) by reusing the existing activity primitives (createMR, the pipeline trigger, gitPushes). A per-user failure warns and continues rather than aborting the whole pass.
  • Logs a final summary: subset size, MRs/pipelines/pushes added, API request count.

Existing Run/seed behavior is unchanged apart from adding an optional Config.Seed field for RNG determinism.

Usage

MANIFOLD_GITLAB_TOKEN=<admin-pat> manifold seed-growth --url https://gitlab.example.com --fraction 0.40 --seed 42 --yes

Tests

All use a mock HTTP GitLab (no network):

  • TestArchetypeFromUsername / TestArchetypeFromUsernameRoundTrip — archetype parsing incl. multi-digit suffixes (manifold-builder-247) and underscore archetypes (manifold-solo_contributor-04).
  • TestSelectGrowthSubset* — deterministic selection (same seed -> same subset), fraction respected, dormant excluded, minimum-one, no-candidates.
  • TestCreateUserPATRequestShape / TestGrowthMintsPATForEachSubsetUser — PAT-mint request path/shape.
  • TestRunGrowthDiscoversAndGrows / TestRunGrowthNoSeededUsers / TestRunGrowthDefaultsBadFraction — end-to-end discover + subset + PAT + activity against a fake GitLab.
  • TestSeedGrowthRegistered / TestSeedGrowthFlagParsing — subcommand registration and flag contract.

Validation

make check (go vet + go test, no race) all green. Full -race suite green. golangci-lint clean. Coverage 71.8% (floor 65%).

The real GitLab integration is validated separately by the coordinator on GCE.

🤖 Generated with Claude Code

Merge request reports

Loading