Repository navigation
Conversation
… imports - Remove the scheduled standby screen's delayed guards with it, and never lock from a closed screen - Resolve capture notifications and app-context toasts in the app's language - Reject roster CSV files dated in the future - Exclude the databases domain from cloud backup and device transfer - Ignore discard while weekly edits are saving and save the edits as tapped - Guard a missing battery dialog and reload servers after VPN consent in standby - Keep profile-less screens open when only the Platoon name or banner changes
- Resize the Platoon emblem sprites to their largest drawn size and store them, and the launcher art, as lossless WebP (2.77 MB to 0.30 MB) - Drop legacy launcher PNGs that minSdk 26 never selects - Stop v1 JAR signing and packaging unused Kotlin and androidx metadata - Build the protocol module as a plain Kotlin JVM library - Skip the duplicate release lint pass in CI and rebuild Pages only when the READMEs change Release APK: 3,186,124 to 1,054,123 bytes.
- Keep only navigation in WeeklyReportStateHolder; background work already supersedes stale renders - Export a single week read-only instead of recording a history revision - Check for exportable weeks without building every report - Require an explicit storage scope in per-Platoon preferences instead of a default that throws without a profile
A capture exactly at a reset records the closed previous game day. Add PlatoonPeriods.checkpointDay for that rule and use it for the Gunsmoke checkpoints and the weekly period snapshots, so the closing Sunday 05:00 capture finalizes the event score instead of being dropped.
The Standard solver dropped a capture exactly at the week's closing reset and then overwrote the exact closing-boundary Saturday with an unknown value. A reset capture now closes its previous day and pins that day's final stage.
The active span began on the first observed day, which credited merit earned after joining but before that capture to the wrong day. A member missing from a roster can join right after it, so the span now starts on the game day of the latest roster that omits the member.
Stopping used to mark the capture STOPPED as soon as it was requested, while the native join, the queued-chunk drain and the session reset still ran on the worker. Backup, CSV import/undo and profile edits gated on that phase could overlap the live loop, for example a drained roster recreating a deleted profile's database. Add a STOPPING phase that lasts the whole teardown and publish STOPPED only when it completes, including when the service is destroyed meanwhile. CaptureGuard now requests the stop and continues once a listener observes STOPPED, with a 20 second timeout that explains nothing was changed. Home shows the stopping state, and standby restarts a capture that is still stopping and only opens the game on a newer run.
A capture thread that failed AttachCurrentThread jumped to cleanup without calling onCaptureStopped, because an unattached thread cannot call into Java. The service stayed RUNNING over a dead VPN loop. nativeStart now waits for the thread's attach outcome. On failure it joins the thread, releases the context and returns false, which the service already reports as a failed native start.
replaceRestoredState ran its rollback in a catch outside withExclusiveDatabase, so another writer could take the lock between the failed install and the rollback, and the rollback would then discard that write. Run the rollback inside the same exclusive section.
restore() compared the post-import digest under one exclusive acquisition and installed the checkpoint under another, so an ingest in between was silently overwritten. Pass the expected digest down to restoreCheckpoint, which now compares it inside the exclusive section that replaces the database and replaces nothing on a mismatch. The earlier check stays as a fast failure before any evidence is quarantined.
Interrupted-import recovery only ran when a CsvImportCheckpointManager was constructed, which happens lazily from the Home undo row or the import flow. Automatic recording could ingest into the scope first, and the later recovery then restored the checkpoint over that evidence. Recover every registered scope at process start on a background thread, and again on the capture worker before any ingestion; the per-scope claim serializes the two. Startup recovery, including the existing full-restore recovery, now logs a failure and leaves its durable state for the next attempt instead of crashing every launch.
A baseline accepted up to 15 minutes before the reset can leave the previous day's login or patrol in the next day's delta, and a Daily Patrol fact kept such a delta as an exact value above the cap. A patrol fact now fixes the day at 90, and a delta above the cap keeps only its single valid split or stays unknown.
The final-event aggregate copied a Saturday login or patrol miss from the captured counters although both stay open until the 05:00 reset. Like the day projection, it now applies only a positive consensus to the open day.
…bounds A Merit This Week or Gunsmoke score counter that came back higher after its Monday or event-start reset was reported as the small difference. The comparison now knows the Platoon's reset zone and reports the newer counter as a lower bound, shown with the usual ≥ and exported as a certainty column.
A day captured before its three attempts made the next transition enumerate every tail score paired with every state, exhausting the run's search budget and dropping every later day. Recording once a day at 04:56 hit this for most members. The detailed search now skips tail score merits the interval's shared rounding remainder rules out, checks its budget before a transition it cannot finish, and caps partial states at 256. When it would stop, the run continues on attempt and Login / Daily Patrol classes with closed-form merit and score ranges, which admit every point split and stay conservative. Later days keep their patrol and lower bounds and the final-event totals can stay exact; a 50-member daily 04:56 week solves in well under 100 ms.
- Reload the Platoon and Weekly screens when a roster is saved while they are visible - Clear the Platoon list after a failed load and rebind rows when the time zone or latest roster changes - Restore list scroll only once rows exist - Save weekly cutlines off the main thread and report a failed write instead of crashing - Report a failed packet deletion, refuse clipboard copies over the binder limit, and show only the start of huge raw packets - Ask before removing the Discord webhook and keep it through transient Keystore errors - Add system-bar insets on top of the bars' minimum heights - Stop Settings from rescheduling on an instance it is recreating, and ellipsize long capture notices
# Conflicts: # docs/ARCHITECTURE.md
A client resumed after hours in the background can stop at a reconnection-failed notice, so its Recents card is closed before launch; the launch waits for the old process to be killed, and leaving the game only counts once it has been in front.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes from a full-code audit of 2.7.0, a two-thirds smaller APK, and the follow-up fixes found on the device. See CHANGELOG.md for the complete list.
Fixed
.partialfiles cleaned; diagnostics bounded; TLS detected only by a full record header; native start fails cleanly when the thread cannot attach.Changed
protocolis a plain Kotlin JVM module; CI skips the duplicate release lint pass; Pages deploys only on README changes.Testing
:protocol:test,:app:testDebugUnitTest,:app:lintDebug(68 warnings, down from 75),:app:compileDebugAndroidTestKotlin, signed:app:assembleRelease. New instrumented tests compile but were not run (they would wipe the debug app on the user's phone).