feat(#673): SetEndReason plumbing, CompletedSet persistence, firmware bounds#686
feat(#673): SetEndReason plumbing, CompletedSet persistence, firmware bounds#6869thLevelSoftware wants to merge 6 commits into
Conversation
… bounds PR 1 of 3 for Issue #673 (user-prompted drop sets on failure). Packet 1A: SetEndReason enum + threading - Add SetEndReason enum (6 values) to TrainingCycleModels.kt - Thread reason: SetEndReason parameter through handleSetCompletion() - Store reason on WorkoutCoordinator.lastSetEndReason at entry - Assign correct reason at all 8 call sites: TARGET_REPS_REACHED (workout complete, bodyweight rep, shouldStopWorkout) STALL_FAILURE (triggerAutoStop) VBT_AUTO_END (velocity-based auto-end) USER_STOPPED (stopAndReturnToSetReady) TIMER_EXPIRED (timed exercise countdown) Packet 1B: CompletedSet persistence - Add setEndReason field to CompletedSet data class + create() companion - Add set_end_reason column to VitruvianDatabase.sq CompletedSet table - Migration 43: ALTER TABLE add column with default - Update all insertCompletedSet/insertCompletedSetIgnore call sites - Update SqlDelightCompletedSetRepository mapper + all insert paths - Update CompletedSetBackup model with default for backward compat - Update DataBackupManager export/import/streaming paths Packet 1C: Firmware validation bounds - BlePacketFactory: require(weightPerCableKg <= 100.0f) - BlePacketFactory: require(abs(progressionRegressionKg) <= 10.0f) - BleConstants: document official app names (softMax, increment) Refs #673
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b53c630a7d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
P1 fixes: - SchemaManifest.kt: add set_end_reason column to CompletedSet manifest - build.gradle.kts: advance schema version 43->44 for migration 43 - BlePacketFactory: use Constants.MAX_WEIGHT_PER_CABLE_KG (110f) instead of 100f - DataBackupManagerRoutineNameTest: pass set_end_reason to insertCompletedSetIgnore P2 fixes: - ActiveSessionEngine: set USER_STOPPED on manual stopWorkout() - ActiveSessionEngine: track CABLE_RELEASED via autoStopReason coordinator field - ActiveSessionEngine: preserve TIMER_EXPIRED through bodyweight confirmation - WorkoutCoordinator: add autoStopReason field with reset logic Refs #673
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b0b1123871
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
PR Follow-up StatusAll CI checks pass on commit Kilo Code Review remains in QUEUED state (external service) — this is not a CI failure. PR is ready for merge gate review. Phase 1 of 3 — |
Merge gate: blocked — implementation revision requiredReviewed current head
Operationally, branch protection also requires one approving review, but Please push the scoped fixes/tests, obtain the required approval, and let all review automation complete; the merge gate can then re-run against the new head. |
P1 fixes: - Add migration 43 fallback SQL to MigrationStatements.getMigrationStatements() - Add CompletedSet.set_end_reason heal operation to SchemaManifest.manifestColumns - Add behavioral tests: migration 42→43, resilient fallback, CompletedSet round-trip P2 fixes: - Validate progressionRegressionKg ±10 bound early in WorkoutCommandValidator - Enforce signed protocol softMax <= 100.0f in BlePacketFactory (not 110) - Add validator tests for both bounds Refs #673
Merge gate findings addressedPushed P1 fixes
P2 fixes
CI should pass on the new head. Requesting review to clear the approval requirement. |
9thLevelSoftware
left a comment
There was a problem hiding this comment.
All 4 merge gate findings addressed in 6a88cde. Requesting re-review.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6a88cde9cd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // so invalid imported/synced values are rejected before reaching | ||
| // BlePacketFactory.createProgramParams() which enforces the same | ||
| // bound via require(). | ||
| if (kotlin.math.abs(params.progressionRegressionKg) > 10.0f) { |
There was a problem hiding this comment.
Reject over-100 kg before building the packet
For non-Echo parameters between 100 and 110 kg, this validation gate still succeeds because validateWeightRange uses Constants.MAX_WEIGHT_PER_CABLE_KG (110), but BlePacketFactory.createProgramParams subsequently requires at most 100 kg. The newly added 101 kg validator test establishes the intended early-rejection behavior, yet currently fails; in the workout flow the later require produces a generic workout error and returns to Idle instead of the explicit invalid-command path. Add the signed softMax bound to validateProgramParams.
Useful? React with 👍 / 👎.
| ) | ||
|
|
||
| // Migrate 42 → 43 | ||
| VitruvianDatabase.Schema.migrate(driver, 42, 43) |
There was a problem hiding this comment.
Run migration 43 from schema version 43
This test calls Schema.migrate(driver, 42, 43), which applies 42.sqm; the repository's migration contract explicitly states that N.sqm migrates N -> N+1, so 43.sqm is only applied by migrating 43 to 44. Consequently this newly added test reaches the following assertion without set_end_reason and fails the Android host test suite. Build the fixture at version 43 and migrate to 44.
Useful? React with 👍 / 👎.
| logged_rpe = completedSet.loggedRpe?.toLong(), | ||
| is_pr = if (completedSet.isPr) 1L else 0L, | ||
| completed_at = completedSet.completedAt, | ||
| set_end_reason = completedSet.setEndReason.name, |
There was a problem hiding this comment.
Preserve the end reason when tagging Just Lift sets
When a Just Lift session finishes without an exercise selected, no CompletedSet is saved by the completion path; tagging it later creates the row here from a CompletedSet whose default reason is TARGET_REPS_REACHED. Thus sessions actually ended by stall, cable release, or manual stop are misclassified as soon as they are tagged. Pass the captured completion reason through the Just Lift tagging/ensure path rather than serializing the constructor default.
Useful? React with 👍 / 👎.
…g bound - SchemaParityTest: remove profile_id from Routine/WorkoutSession INSERT (not present in schema v1 before reconciliation) - WorkoutCommandValidator: enforce signed protocol softMax 100kg in validateWeightRange (not just in BlePacketFactory) - SIGNED_PROTOCOL_SOFT_MAX_KG constant documents the contract Refs #673
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 14bbc96b4e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ) | ||
|
|
||
| // Migrate 42 → 43 | ||
| VitruvianDatabase.Schema.migrate(driver, 42, 43) |
There was a problem hiding this comment.
Migrate the version-43 fixture to version 44
Fresh evidence in the reviewed commit is that this call still migrates 42 -> 43, despite the thread's claimed c0303de fix. The repository's migration contract states that N.sqm migrates N -> N+1, so this executes 42.sqm, not the new 43.sqm; set_end_reason remains absent and the assertion immediately below fails the Android host test suite. Build the fixture at version 43 and migrate it to 44.
Useful? React with 👍 / 👎.
The test called VitruvianDatabase.Schema.migrate(driver, 42, 43) directly which may throw when the v42 database built by buildSchemaAtVersion has a slightly different shape than SQLDelight expects. Use the same try/resilient fallback pattern as the production DriverFactory. Refs #673
PR 1 of 3 — Set-end Reasons and Protocol Cleanup
Refs #673
Scope
This PR delivers the foundational plumbing for the user-prompted drop-set feature (Issue #673). It is the first of three sequential PRs.
Changes
Packet 1A: SetEndReason enum + threading
SetEndReasonenum (6 values: TARGET_REPS_REACHED, STALL_FAILURE, VBT_AUTO_END, USER_STOPPED, CABLE_RELEASED, TIMER_EXPIRED)reason: SetEndReasonparameter threaded throughhandleSetCompletion()WorkoutCoordinator.lastSetEndReasonfor CompletedSet persistencePacket 1B: CompletedSet persistence
setEndReasonfield onCompletedSetdata class +create()companionset_end_reasoncolumn in VitruvianDatabase.sqPacket 1C: Firmware validation bounds
BlePacketFactory:require(weightPerCableKg <= 100.0f)andrequire(abs(progressionRegressionKg) <= 10.0f)BleConstants: documented official app names (softMax, increment)Verification
./gradlew :shared:compileKotlinIosArm64— BUILD SUCCESSFULNext PRs