Lock the trigger set and write rules #91

Closed
opened 2026-08-26 06:55:42 +02:00 by SirStone · 2 comments
Owner

part-of: #88

Question

Fix the concrete save policy using the pinned inputs: metric = GA champion fitness per generation, single-observation replace, no cold-start case (#89); reachable moments per #90 — onRoundEnded is the only reliable periodic trigger, abort paths offer at most a best-effort onDisconnected.

Decide:

  • Exact trigger list honoring the rule of thumb "save at the first moment the GA can no longer improve": own death, game end, round-end periodic, disconnect handler — which combination?
  • Which snapshot a save writes given the async evo thread: last champion drained from the channel vs current population best; how much staleness is acceptable?
  • Confirm load order stays per-opponent → global → init under best-slot semantics (ADR 0001).
  • Crash-safe write procedure: atomic replace so a kill mid-write cannot corrupt the stored best.
  • Write-cost sanity check at 1000+ rounds if the round-end trigger is included.
part-of: #88 ## Question Fix the concrete save policy using the pinned inputs: metric = GA champion fitness per generation, single-observation replace, no cold-start case ([#89](https://git.fossellini.top/SirStone/SirRoboGarage/issues/89)); reachable moments per [#90](https://git.fossellini.top/SirStone/SirRoboGarage/issues/90) — `onRoundEnded` is the only reliable periodic trigger, abort paths offer at most a best-effort `onDisconnected`. Decide: - Exact trigger list honoring the rule of thumb "save at the first moment the GA can no longer improve": own death, game end, round-end periodic, disconnect handler — which combination? - Which snapshot a save writes given the async evo thread: last champion drained from the channel vs current population best; how much staleness is acceptable? - Confirm load order stays per-opponent → global → init under best-slot semantics (ADR 0001). - Crash-safe write procedure: atomic replace so a kill mid-write cannot corrupt the stored best. - Write-cost sanity check at 1000+ rounds if the round-end trigger is included.
SirStone added the wayfinder:grilling label 2026-08-26 06:55:42 +02:00
Author
Owner

claimed by orchestrator session (ox-alpha), 2026-08-26

claimed by orchestrator session (ox-alpha), 2026-08-26
Author
Owner

Resolution

Locked save policy:

  • Trigger — exactly one save point: onRoundEnded, firing every round, dead or alive. Dropped: onDeath (subsumed seconds later by round end), onGameEnded flush, onDisconnected — one code path saves weights, ever. Abort/kill loss window bounded to ≤ 1 round of generations.
  • Snapshot: last champion drained from the evo thread's channel (bot-thread-visible state); the live thread is never touched.
  • Gating: candidate replaces the stored best iff its GA fitness exceeds the stored fitness (metric per #89). Fitness travels inside the weights file as a metadata header line above the 745 floats. Legacy headerless files load normally and rank as never-better (−inf), replaced by the first improved candidate.
  • Load order: unchanged — per-opponent → global → init (ADR 0001).
  • Write procedure: temp file + atomic rename in the same directory; a kill mid-write cannot corrupt the stored best.
  • File location (ruling): all weight files live in the directory of the running bot binary, resolved at runtime — not compile-time source paths.
  • Cost: disk writes occur only on fitness improvement; self-limiting even at 1000+ rounds.
## Resolution Locked save policy: - **Trigger — exactly one save point**: `onRoundEnded`, firing every round, dead or alive. Dropped: `onDeath` (subsumed seconds later by round end), `onGameEnded` flush, `onDisconnected` — one code path saves weights, ever. Abort/kill loss window bounded to ≤ 1 round of generations. - **Snapshot**: last champion drained from the evo thread's channel (bot-thread-visible state); the live thread is never touched. - **Gating**: candidate replaces the stored best iff its GA fitness exceeds the stored fitness (metric per [#89](https://git.fossellini.top/SirStone/SirRoboGarage/issues/89)). Fitness travels inside the weights file as a metadata header line above the 745 floats. Legacy headerless files load normally and rank as never-better (−inf), replaced by the first improved candidate. - **Load order**: unchanged — per-opponent → global → init (ADR 0001). - **Write procedure**: temp file + atomic rename in the same directory; a kill mid-write cannot corrupt the stored best. - **File location** (ruling): all weight files live in the directory of the running bot binary, resolved at runtime — not compile-time source paths. - **Cost**: disk writes occur only on fitness improvement; self-limiting even at 1000+ rounds.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: SirStone/SirRoboGarage#91