diff --git a/TODO.md b/TODO.md index 0f04328..cbdcbfb 100644 --- a/TODO.md +++ b/TODO.md @@ -173,6 +173,18 @@ the finish is supposed to leave behind. only what did not land. Everything that is *not* complete at victory - the latency table, the client's logs, the profiles - still goes at exit, because that is when the JVMs stop writing them. +- [x] **Artifacts are filed by what they are.** `launch/` is what the match was + given - the staged `scenario.mms` and `identity.json`, both sent at init, + so a match that never reaches victory still says what it was and who was + in it. `raw/` is MegaMek's own output kept byte-for-byte, which now + includes the things that used to be deleted with the container: the + action log, the round report, the end-of-game sheets and the MULs. + `derived/` is what arena made of it, and `derived/socials/` the pictures + we picked out of it: the board at victory, chosen from the thirty-one + MegaMek rendered, is the only one so far. The other thirty are no longer + uploaded - one is read and thirty are not, at 3.3MB each - and neither + are the per-phase minimap frames, which are the GIF's own. headquarters offers both layouts in the manifest, so this image runs + against a control plane that has not deployed them yet. - [ ] **The rest of the artifacts still ride the shutdown.** That window is a SIGTERM and a bounded wait on Fargate, and a diagnostic that does not finish inside it is gone. The logs could be shipped in rolling chunks and diff --git a/container/init/20-identity.sh b/container/init/20-identity.sh index ba5c73b..8055765 100755 --- a/container/init/20-identity.sh +++ b/container/init/20-identity.sh @@ -124,6 +124,20 @@ chmod 600 "$ARENA_RUN/players.env" jq '{matchId, players: [.players[] | {slot, control, did, handle}]}' "$MANIFEST" \ > "$ARENA_STATE/identity.json" +# Sent now, not at the end. +# +# It is also merged into the result document, and that used to be its only way +# out of the container - so a match that was abandoned, crashed or was reaped +# uploaded turn reports that no longer said who had been playing. This file is +# complete before the first turn and is 276 bytes; there is no reason for it to +# wait on a victory that may not come. +# +# Best-effort, like every other upload: a match does not fail because a +# 276-byte projection did not land. +if has_upload_key launch; then + upload "$ARENA_STATE/identity.json" launch identity.json || warn "identity.json was not sent" +fi + log "slots: $(jq -r '[.players[] | "\(.slot)=\(.control)"] | join(" ")' "$MANIFEST")" log "names: $(paste -sd' ' < <(awk -F'\t' '{ print $1 "->" $2 }' "$ARENA_RUN/names.tsv"))" if [ -s "$ARENA_RUN/teams.tsv" ]; then diff --git a/container/init/30-assets.sh b/container/init/30-assets.sh index 10a7b9f..c2cb033 100755 --- a/container/init/30-assets.sh +++ b/container/init/30-assets.sh @@ -79,6 +79,18 @@ else fi echo "ARENA_SCENARIO=$SCENARIO_DIR/match.mms" > "$ARENA_RUN/scenario.env" +# The staged file, sent as the match's own input. +# +# Both manifest forms end up here - a name picked out of this image's library +# and a `.mms` carried whole resolve to the same file - so this is the one +# artifact that says which fight was actually played. The name would not do: +# it points into a particular arena image, and the library changes between +# releases, so the same path in two images is not promised to be the same +# scenario. The bytes are what pins it. +if has_upload_key launch; then + upload "$SCENARIO_DIR/match.mms" launch scenario.mms || warn "the scenario was not sent" +fi + # --- camo ------------------------------------------------------------------- # Failure here is not fatal. A missing camo is a cosmetic loss; refusing to start # the match over it would turn a bad upload into a lost match.