fix: serve healthz path/address and seeder archetype constants
Problem
Three local-server and seeder defects.
-
serveprinted a malformed URL and ignored config. The format stringhttp://localhost%swithaddr127.0.0.1:8080producedhttp://localhost127.0.0.1:8080(two hosts mashed together). Separately,runServenever loadedmanifold.yml, so aserve.addrsetting was silently ignored even thoughconfig.LoadFilealready merges it. -
Seeder archetypes diverged from the schema constants.
internal/seeder/(seeder.go,users.go,activity.go) hardcoded hyphenated and short labels (solo-contributor,platform-engineer,emerging,dormant) whileinternal/schema/analyzer.godefines the canonical Personal Access Token user archetype constantsArchetype*(solo_contributor,platform_engineer,emerging_user,dormant_expert). Seeded fixtures therefore never matched real analyzer output. -
/healthzwas reported as always returning 503 because the handler checks<dir>/data/summary.json. Investigation found that path is already correct (see below), so no code change to the handler was warranted; the gap was the absence of a regression test.
Fix
-
serve: print the real address with
http://+ addr, and wire config loading with the sameFlagSet.Visitprecedence pattern used bycollect/run. An explicit--addrflag wins; otherwise themanifold.ymlserve.addr(then default) is honored. Address resolution and URL formatting are extracted into pure helpers (resolveServeAddr,serveURL) for direct testing. -
seeder: replace every archetype assignment with the matching
schema.Archetype*constant via a sharedarchetypeOrderslice. The username slug now reflects the canonical value (e.g.manifold-solo_contributor-01), valid for GitLab usernames. Existing seeder tests updated to the constants. -
healthz: the renderer writes
summary.jsontoOutputDir/data/(render.go), the dashboard JavaScript fetchesdata/summary.json(app.src.js), andservedefaults to--dir public, so the served file lives atpublic/data/summary.json. The handler's<dir>/data/summary.jsoncheck is correct. Added regression tests; left the handler unchanged.
Validation
make check(go vet plus full test suite): pass on Go 1.24.2.go test -race ./...: pass on Go 1.24.2.
Fails-on-old proofs:
- seeder: reverting one
archetypeOrderentry tosolo-contributormakesTestSeededArchetypesMatchSchemaConstantsfail (archetypeDistribution(N) produced non-schema archetype "solo-contributor"); restoring the constant passes. - healthz: changing the handler to the flat
<dir>/summary.jsonmakesTestHealthz_PresentSummaryfail with 503 when data is present (want 200, got 503); the existingdata/path passes 200-present / 503-absent. This confirms the flat path is the regression, not the fix.
Tests shipped
internal/server/server_test.go:TestHealthz_PresentSummary,TestHealthz_AbsentSummary.cmd/manifold/serve_test.go:TestServeURLWellFormed,TestResolveServeAddr,TestServeConfigAddrHonored.internal/seeder/seeder_test.go:TestSeededArchetypesMatchSchemaConstantsplus existing tests migrated to schema constants.