Drive-In event ideas: an idea withdrawn for a rule change shows again when re-proposed
pauljd/davidson-ci: Davidson CI / quality (push) Failing after 2m19s
pauljd/davidson-ci: Davidson CI / ai-review (push) Failing after 1m42s

The box's third run proposed the Ant-Man double again under rules 4, but its
history entry from rules 3 was marked withdrawn, so it was recorded as known
and left off the Chair. A re-proposed idea now replaces its withdrawn entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-11-05 18:34:20 +00:00
co-authored by Claude Opus 5.5
parent 2c13978c2c
commit 3a7ae53f9e
2 changed files with 18 additions and 2 deletions
@@ -242,11 +242,14 @@ internal object EventIdeaHistory {
file.writeText(JSONArray(all.map { if (it.optInt("rules") < EVENT_IDEA_RULES && it.optString("decision") == "proposed") JSONObject(it.toString()).put("decision", "withdrawn: rules changed") else it }).toString())
}
fun record(file: File, ideas: List<EventIdea>, nowMs: Long) = runCatching {
val all = load(file); val known = all.map { it.optString("signature") }.toSet()
// An idea withdrawn only because the rules changed, and proposed again under the new ones, is shown again: its old entry goes.
val again = ideas.map { it.signature }.toSet()
val all = load(file).filterNot { it.optString("signature") in again && it.optString("decision").startsWith("withdrawn") }
val known = all.map { it.optString("signature") }.toSet()
val added = ideas.filter { it.signature !in known }.map { i ->
JSONObject().put("signature", i.signature).put("theme", i.theme).put("source", i.source).put("format", i.format.name).put("evening", i.evening?.toString())
.put("films", JSONArray(i.films.map { it.id })).put("titles", JSONArray(i.films.map { it.title })).put("reasons", JSONArray(i.reasons)).put("shownMs", nowMs).put("decision", "proposed").put("rules", EVENT_IDEA_RULES)
}
if (added.isNotEmpty()) file.writeText(JSONArray(all + added).toString())
if (added.isNotEmpty() || all.size != load(file).size) file.writeText(JSONArray(all + added).toString())
}
}
@@ -79,4 +79,17 @@ class EventIdeasTest {
val sat = ideaEvening(IdeaFormat.SaturdayTriple, LocalDate.of(2026, 11, 14), 0L, emptySet(), 6 * 3_600_000L, london)!!
assertEquals(LocalDate.of(2026, 11, 21), sat.toLocalDate()) // Universal Monsters has the 14th
}
@Test fun anIdeaWithdrawnOnlyForARuleChangeComesBackWhenProposedAgain() {
val file = java.io.File.createTempFile("history", ".json").apply { deleteOnExit(); writeText("[]") }
val idea = EventIdea("franchise:X|FridayDouble", "X Night", "franchise", IdeaFormat.FridayDouble, java.time.LocalDateTime.of(2026, 12, 4, 20, 0),
listOf(film("1", "X", setOf("Action")), film("2", "X II", setOf("Action"))), listOf("why"), 7.0)
EventIdeaHistory.record(file, listOf(idea), 1)
file.writeText(file.readText().replace("\"rules\":$EVENT_IDEA_RULES", "\"rules\":1"))
EventIdeaHistory.withdrawOld(file)
assertEquals("withdrawn: rules changed", EventIdeaHistory.load(file).single().optString("decision"))
EventIdeaHistory.record(file, listOf(idea), 2)
assertEquals("proposed", EventIdeaHistory.load(file).single().optString("decision"))
assertEquals(2L, EventIdeaHistory.load(file).single().optLong("shownMs"))
}
}