10 lines
1.7 KiB
Markdown
10 lines
1.7 KiB
Markdown
# One mortar response per delivered observation
|
|
|
|
The first firing experiment exposed a second order for the same unchanged observation after the native activity was cancelled. A cooldown alone does not make a report new. Each physical battery now owns a bounded ledger of attempted report message IDs, retained through cancellation and activity completion.
|
|
|
|
Scheduling checks report eligibility before creating a downlink; `BeginRequest` claims it before cancelling an older order or incrementing the order ID. A failed/interrupted delivery consumes that battery's attempt at that observation. A newly observed and actually delivered report has a new HQ message ID and can authorize a later attempt; the code never renews observation timestamps. Different batteries maintain independent histories, although the current authored mission has one battery.
|
|
|
|
Entries expire only after the original report is older than the unchanged 60-second report lifetime. The ledger rejects future, negative and stale observation times, invalid message IDs and excessive live entries. Its 128-entry bound exceeds the HQ's 64 retained contacts; a full ledger fails closed until entries expire. Each new mission owns a fresh ledger.
|
|
|
|
`test_mortar_report_ledger.py` executes the actual availability/claim bodies, including repeated reads without a claim, A/B/A replay, attempted timestamp renewal, exact freshness boundary, expiry pruning, capacity and fresh-round ownership. Scheduler ordering is also checked. The new native `mortar-expiry` fixture retains an unchanged report while HQ continues running; its native result is still pending at this document's initial checkpoint. This is not full salvo, hit accuracy or multiplayer qualification.
|