A teammate’s pull request lets admins build lists from other lists by name: engineering includes platform, so an edit to platform reaches every list that includes it. Including by name also makes loops possible (on-call includes platform, platform includes on-call), so the pull request stops a send three lists down. QA reports that the on-call engineer did not get a company-wide notice, and that a list including a team that was deleted last week sends without any sign of it. You are reviewing the pull request.
People at the bottom of a deep list silently miss messages, and how deep is too deep depends on how admins happened to nest things. A deleted list drops its people without anyone being told.
Reproduce
Lists: engineering[include old-infra, fay@], and old-infra was deleted. Send "Outage" to engineering: fay should get it and the result should end with “missing list: old-infra”; today it says nothing about old-infra. Then lists company[include engineering]; engineering[include platform, fay@]; platform[dana@, include on-call]; on-call[zoe@]: a send to company should reach dana, zoe and fay (count 3); today zoe is missing and the count is 2.
Acceptance criteria
- A send reaches everyone under the list, however deep the includes go.
- Lists that include each other, or themselves, still finish, with one copy per person.
- An include that names no list adds “missing list: <name>” after the deliveries, and the rest of the send goes ahead; the count counts people only.
- Every send starts fresh, and an edit to a list is seen by the next send to any list that includes it.
Notes
- Each send prints its lines joined by “ | ” (or “(nobody)”), then “(count N)”; a case’s sends are joined by “ || ”. Cases send to a list by name, through an Include.
- Keep the names and signatures of Address, MailingList, Include, register, send and recipientCount (Go: Register, Send, RecipientCount; Rust: register, send, recipient_count); the checker clears the directory before each case.