Nobody has started this yet — be first.
Business impact
seed.Run is called unconditionally on every boot. In a real deployment, instances restart routinely -- deploys, crashes, autoscaling, node maintenance. If seeding isn't idempotent, every restart adds another copy of every seeded job, each with its own cron schedule quietly firing against the same target_url. For the built-in demo jobs this is wasted load and a confusing job list; if this exact pattern were ever reused to seed real customer-configured jobs, it would mean duplicate charges, duplicate notifications, or duplicate side effects proportional to however many times the service has restarted -- a slow, silent, cumulative correctness bug.
Problem
seed.Run fetches the existing jobs into a byName lookup map, but the loop that creates jobs never consults it -- it calls jobs.Create for every demo unconditionally. Every call to seed.Run (i.e. every process restart) creates three brand-new demo-* jobs, regardless of how many already exist.
Current behavior
After calling seed.Run twice in a row (simulating one restart), job "demo-always-succeed" exists 2 times instead of exactly 1.
Expected behavior
seed.Run should create each demo job at most once, ever, no matter how many times it's called against the same database.
Steps to reproduce
Why this matters
Idempotent seeding is what makes "restart-safe" mean anything. A seeding routine that isn't safe to call twice against the same state isn't really a seeding routine, it's an insert-on-every-boot routine that happens to look like seeding the first time.
Suggested approach
seed.Run already builds the byName map from the jobs that exist before this call. Look at what happened to the loop that's supposed to use it before deciding whether to create each job.
Acceptance criteria
Verification
TEST_DATABASE_URL="postgresql://chronos:chronos@localhost:5432/chronos?sslmode=disable" go test ./tickets/tests/... -run TestTicket02 -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
Sign in to create it automatically, or do it yourself:
$git checkout -b fix/seed-duplicate-jobsFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/seed-duplicate-jobsSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign inhttp://localhost:8081app-1http://localhost:8082app-2http://localhost:8090curl localhost:8081/healthzcurl localhost:8081/readyzWork the tickets in tickets/docs/ (ordered easy → hard); each names one Go test in tickets/tests/. Most tickets need a real Postgres (tickets 4, 11, and 18 are pure-function tests and do not):
export TEST_DATABASE_URL="postgresql://chronos:chronos@localhost:5432/chronos?sslmode=disable"
go test ./tickets/tests/... -run TestTicket08 -v # a single ticket
./tickets/run_tickets.sh # all 20, clean pass/fail summary
Use -race when working on tickets 15, 16, or 17 (the concurrency ones) -- run_tickets.sh already does this for every ticket. Tickets 15 and 16 are adjacent bugs in the same function (pkg/leader/leader.go's lock-release path); fix ticket 16 first, since ticket 15's test keeps failing for ticket 16's reason until that one is fixed too.
Level 1
Fix a bug
Read existing behaviour, correct it.