Skip to content

SCRUM-222 — Config concurrency integration tests

Plan ref: CFG-E2 (docs/11-admin-plane-plan.md). Stacked on SCRUM-221.

What exists

Against real Postgres, with -race, skipped without CONFIG_TEST_DATABASE_URL (runs in CI's Test stage, which sets it). Goroutines start behind a barrier so they really race; tests that move the dev head take the dev-head advisory lock and restore the head.

Test Guarantee
TestConcurrentDraftSavesHaveOneWinner / …ThroughTheLiveServer 8 saves at one revision → 1 success, 7 stale_revision; one audit row
TestChainedDraftSavesHaveNoLostUpdates read → save → retry-on-stale loops: final revision = start + N×K, no lost entry
TestConcurrentPublishesThroughTheLiveServer 8 publishes on one base → 1 201, 7 409 stale_release; head moved once; one release, one audit row, one NOTIFY
TestVersionWhileEditingRace versioning never captures content other than the revision it was asked for
TestConcurrentSchemaReplacesThroughTheLiveServer schema versions n+1..n+N, distinct, no gaps
TestAuditFailureRollsBackTheChange / TestAuditFailureIsA500… a test-only trigger makes the audit insert fail: draft save, version, schema, publish and namespace create each leave no change

Spec fix on the way: a 409 stale_revision now carries the current draft in error.details.draft (CFG-B3 / doc 02 §5 asked for it; it was missing). COM-5 error bodies gained an optional details field (omitted when empty).

How to verify

cd services/config
. ../../handoff/pg-env.sh
CONFIG_TEST_DATABASE_URL=postgres://auth_rw:pw@127.0.0.1:5433/config_test?sslmode=disable \
  go test -race -count=2 ./...

Results at time of writing

  • gofmt, go vet, go test -race -count=2 with the DB (9 packages): pass.

How it was built

DeepSeek run scoped (Landlock) to services/config (390 s, ~47k output tokens, reasoning effort low); no locking bugs found; it reported the missing 409 details, which Claude added with an assertion in the existing draft test.