Skip to content

fix: remove remaining Vitruvian IP outliers after catalogue swap - #710

Merged
9thLevelSoftware merged 2 commits into
mainfrom
fix/vitruvian-ip-detachment-audit
Aug 21, 2026
Merged

fix: remove remaining Vitruvian IP outliers after catalogue swap#710
9thLevelSoftware merged 2 commits into
mainfrom
fix/vitruvian-ip-detachment-audit

Conversation

@9thLevelSoftware

Copy link
Copy Markdown
Owner

Summary

E2E audit follow-up to #706 / #708 for the Vitruvian takedown request. HEAD was already clean of the exercise dataset (572/604), the mux/jwplayer streaming stack and the decompilation docs; this PR removes the outliers that survived the first pass. No behaviour changes.

Removed

  • Stale "572 exercises with video demonstrations" copy in iosApp/TESTFLIGHT_NOTES.txt and docs/index.html (meta descriptions, stat tile, feature text, "the original app never had"); TestFlight notes now carry a non-affiliation line and point at this repo.
  • final-visuals/ (112 QA screenshots) — picker/routine/config frames render the old Vitruvian catalogue; 06a/06b/06c show a live stream.mux.com/… playback URL. Unreferenced by code/CI.
  • Migration 39: the six legacy catalogue IDs (+ inline catalogue-name comments) replaced by the equivalent name-based heal (isCustom = 0 AND TRIM(name) IN (...)); redundant RoutineExercise ID block dropped (the existing name heal already covers it). Idempotent, data-only edit; MigrationStatements.kt mirror and SchemaParityTest / SqlDelightSyncRepositoryTest switched to synthetic IDs.
  • HardwareValidationTest.kt — empty scaffold whose substance was a field-by-field description of the official app's Sample struct; BlePacketCapture comments updated.
  • Dead media3 / HLS version-catalog aliases; unused video_preview_unavailable / cd_video_thumbnail strings (all locales).

Reworded (behaviour unchanged)

  • ~70 comments/identifiers citing "the official app" / decompiled internals as the source of behaviour across BLE/protocol (BlePacketFactory, BleConstants, Constants, BleCompatibilityMode, KableBleConnectionManager, ProtocolParser, BleRepository, …), UI, tests, the vendored Kable patch and .almanac.
  • BlePacketFactory.createOfficialStopPacket()createSoftStopPacket().
  • DiagnosticFaultCategory.VITRUVIAN("Vee")CONTROLLER("Controller"), decodeVitruvianFaultdecodeControllerFault; fault-label table re-authored in Phoenix wording (incl. "Bord Temp" → "Board temperature"). User-visible in the Diagnostics screen/export.
  • "Video" wording → demo images (settings_video_behavior, settings_exercise_demos_disabled, etc.) in en/de/es/fr/nl — values only, keys pinned by contract tests untouched.
  • Safe branding strings: backup filename phoenix_backup_* / Download/ProjectPhoenix, export headers, disconnect_message, ConnectingOverlay, DeviceInfo, install guides, bug template. Persisted names (vitruvian.db, vitruvian_preferences, video_playback) are untouched.
  • docs/superpowers/specs/2026-06-16-official-weight-handling-design.md…per-cable-weight-handling-design.md.
  • LegacyCatalogueIdMap KDoc states the keys are opaque migration-only IDs with no catalogue content.

Not in this PR (owner decisions, see audit report)

Purging the 41 pre-#706 release binaries and editing release bodies; git filter-repo history rewrite (dataset reachable from all tags + origin/working_branch); hashing the LegacyCatalogueIdMap keys; branding identifier renames (VitruvianApp, VitruvianDatabase, Xcode VitruvianPhoenix).

Test plan

  • ./gradlew -Pskip.supabase.check=true :shared:testAndroidHostTest :androidApp:testDebugUnitTest :shared:verifyCommonMainVitruvianDatabaseMigration → 3,724 tests, 0 failures
  • git grep -i 'official app|createOfficialStopPacket|VITRUVIAN\(|Bord Temp|572 exercises|Euclid|reference web application' → no hits in tracked source/docs
  • CI green (iOS compile of the iosMain string edits)

🤖 Generated with Claude Code

https://claude.ai/code/session_01RpYk6iyjaMzC4DjiMEBwvK

E2E audit follow-up to #706/#708 for the Vitruvian takedown request.
HEAD was already clean of the exercise dataset, the mux/jwplayer
streaming stack and the decompilation docs; this removes what survived:

- Drop stale "572 exercises with video" copy (TESTFLIGHT_NOTES,
  docs/index.html), add non-affiliation line to TestFlight notes.
- Delete final-visuals/ QA screenshots that render the old catalogue
  (three show a live stream.mux.com playback URL). Unreferenced by code.
- Migration 39: replace the six legacy catalogue IDs (+ catalogue-name
  comments) with the equivalent name-based heal on non-custom rows;
  drop the redundant RoutineExercise ID block. Idempotent, data-only;
  Kotlin mirror and SchemaParityTest updated to synthetic IDs.
- Reword ~70 comments/identifiers that cited the official app or
  decompiled internals as the source of behaviour (BLE/protocol,
  diagnostics, UI, tests, third-party Kable patch, almanac).
  createOfficialStopPacket() -> createSoftStopPacket();
  DiagnosticFaultCategory.VITRUVIAN("Vee") -> CONTROLLER("Controller");
  fault labels re-authored in Phoenix wording.
- Delete HardwareValidationTest scaffold (described the official app's
  Sample struct); update BlePacketCapture comments.
- Remove dead media3/HLS version-catalog aliases and unused video
  strings; "video" wording -> demo images in en/de/es/fr/nl.
- Neutralise safe branding strings (backup filenames, export headers,
  install guides, bug template, disconnect prompt); persisted names
  (vitruvian.db, vitruvian_preferences, video_playback key) untouched.
- LegacyCatalogueIdMap KDoc now states keys are migration-only opaque IDs.

Verified: :shared:testAndroidHostTest + :androidApp:testDebugUnitTest +
verifyCommonMainVitruvianDatabaseMigration -> 3,724 tests, 0 failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RpYk6iyjaMzC4DjiMEBwvK
Copilot AI lite review requested due to automatic review settings August 21, 2026 16:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

-- Matched by catalogue name on non-custom rows; TRIM handles a trailing-space
-- variant of 'Kneeling 45 Degree Kickback' present in older installs.
UPDATE Exercise SET isBodyweight = 0
WHERE isCustom = 0 AND TRIM(name) IN (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: The new TRIM(name) IN (...) clause is binary-collated by default in SQLite, so an imported row whose name is Squat vs squat (or any curly-quote/whitespace variant beyond trailing space) will silently slip past the backfill — and unlike the old ID list there is no fallback update. Worth either lower-casing the comparison (LOWER(TRIM(name)) IN (...)) with a matching list, or noting explicitly that the migration assumes the seed catalogue's casing. Not blocking — the previous ID-based migration also required exact match — but the case-insensitive upgrade is essentially free and closes a quiet regression for anyone who re-imported their old library with a different locale.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Roast 🔥

Verdict: No New Issues Found | Recommendation: Approve

Overview

Severity Count
🚨 critical 0
⚠️ warning 0
💡 suggestion 0
🤏 nitpick 0

The incremental diff since c217e50b is exactly one commit (b7ec739b Bump app version to 1.0.0) touching 3 files, 4 lines:

  • androidApp/build.gradle.kts:324versionName 0.9.6 → 1.0.0
  • iosApp/.../project.pbxproj:370,415MARKETING_VERSION 0.9.6 → 1.0.0 (Debug + Release configs)
  • shared/.../util/Constants.kt:8APP_VERSION 0.9.6 → 1.0.0

All three marketing strings updated in lockstep. versionCode (Android, stays injectedVersionCode ?: 5) and CURRENT_PROJECT_VERSION (iOS, stays 2025122901) are correctly left alone — those are build counters, not user-facing versions. No drift, no stale callers, no orphan identifiers.

The pre-existing migration-39 case-sensitivity nitpick from the prior review is on unchanged code and is therefore not carried forward in this pass; it remains an optional follow-up.


🏆 Best part: The version bump is a single, mechanical commit. The pbxproj has two MARKETING_VERSION entries because iOS projects ship Debug + Release configurations — both flipped, neither missed. versionCode and CURRENT_PROJECT_VERSION were left alone because they're not the marketing version. Someone who has been burned by half-bumped Xcode projects before wrote this.

💀 Worst part: There is no worst part. The diff is four lines of 0.9.61.0.0. Roasting this would be like critiquing a door for being rectangular.

📊 Overall: A 1.0.0 release that updates its own version string — the dogfood was on the menu. Like a one-pager that actually fits on one page.

Files Reviewed (3 files, 4 changed lines)
  • androidApp/build.gradle.kts - 0 issues
  • iosApp/VitruvianPhoenix/VitruvianPhoenix.xcodeproj/project.pbxproj - 0 issues
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/Constants.kt - 0 issues
Ponytail Pass

Ponytail: Lean already. Ship.

Ponytail net: 0 lines.

Previous Review Summary (commit c217e50)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit c217e50)

Verdict: 1 Minor Found | Recommendation: Approve; optional cleanup

Overview

Severity Count
🚨 critical 0
⚠️ warning 0
💡 suggestion 0
🤏 nitpick 1
Issue Details (click to expand)
File Line Roast
shared/src/commonMain/sqldelight/com/devil/phoenixproject/database/migrations/39.sqm 15 TRIM(name) IN (...) is binary-collated by default — Squat and squat are now different exercises to the migration. The old ID list had the same fragility, but the rename is the moment to fix it for free.

🏆 Best part: 112 QA screenshots, an empty 444-line HardwareValidationTest.kt, three media3 aliases, an unused DEVICE_NAME_PATTERN, two orphaned string resources, and a stale RoutineExercise ID block — all gone in one PR. This is what a cleanup looks like when the author actually understands their own codebase. I'm mildly impressed and deeply suspicious.

💀 Worst part: Migration 39 traded six opaque IDs for five catalogue names. The isCustom = 0 AND TRIM(name) IN (...) predicate is correct on a clean install but is binary-collation-sensitive on a dirty one — a user who re-imported their old library under a different locale casing gets a silent regression instead of a backfilled row. The new comment even calls out trailing-space handling but not case handling. Free fix; just LOWER(TRIM(name)).

📊 Overall: Like a museum that finally painted over the last unauthorized watermark — most of the work is deletion, the one piece of plumbing they touched (migration 39) is sensibly rewritten with synthetic-ID tests, and the rename (createOfficialStopPacketcreateSoftStopPacket, DiagnosticFaultCategory.VITRUVIANCONTROLLER, decodeVitruvianFaultdecodeControllerFault) leaves zero orphan callers in source. The 3,724-test green is real this time: tests were touched where renamed code appears, including BlePacketFactoryTest, DiagnosticFaultDecoderTest, MainViewModelTest, DiagnosticsViewModelTest, WorkoutFlowE2ETest, SchemaParityTest, and SqlDelightSyncRepositoryTest. Ship it after the case-sensitivity nit (or don't, it's that small).

Ponytail Pass

Ponytail: Lean already. Ship.

Ponytail net: 0 lines.

Files Reviewed (74 source files + 112 deleted PNGs)

Code touched:

  • gradle/libs.versions.toml
  • shared/src/commonMain/sqldelight/com/devil/phoenixproject/database/migrations/39.sqm (1 nit)
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/local/MigrationStatements.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/migration/MigrationManager.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/local/LegacyCatalogueIdMap.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/BlePacketFactory.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/BleConstants.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/Constants.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/DataBackupManager.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/BleCompatibilityMode.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/BleExceptions.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/BlePacketCapture.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/DiagnosticFaultDecoder.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/KableBleConnectionManager.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/MetricPollingEngine.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/MonitorDataProcessor.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/ProtocolModels.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/ble/ProtocolParser.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/repository/BleRepository.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/repository/ConnectionLogRepository.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/data/repository/KableBleRepository.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/domain/model/Exercise.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/domain/model/Models.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/domain/model/UserPreferences.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/domain/usecase/RepCounterFromMachine.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/components/ConnectingOverlay.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/components/EnhancedCablePositionBar.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/manager/WorkoutCoordinator.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/navigation/NavGraph.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/screen/JustLiftScreen.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/screen/SetSummaryCard.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/screen/SplashScreen.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/screen/WorkoutHud.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/screen/WorkoutUiState.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/util/WeightDisplayFormatter.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/presentation/viewmodel/DiagnosticsViewModel.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/ColorScheme.kt
  • shared/src/commonMain/kotlin/com/devil/phoenixproject/util/HardwareDetection.kt
  • shared/src/androidMain/kotlin/com/devil/phoenixproject/presentation/screen/WorkoutTabPreviews.kt
  • shared/src/androidMain/kotlin/com/devil/phoenixproject/util/CsvExporter.android.kt
  • shared/src/androidMain/kotlin/com/devil/phoenixproject/util/DataBackupManager.android.kt
  • shared/src/androidMain/kotlin/com/devil/phoenixproject/util/DeviceInfo.android.kt
  • shared/src/iosMain/kotlin/com/devil/phoenixproject/util/CsvExporter.ios.kt
  • shared/src/iosMain/kotlin/com/devil/phoenixproject/util/DataBackupManager.ios.kt
  • shared/src/iosMain/kotlin/com/devil/phoenixproject/util/DeviceInfo.ios.kt
  • shared/src/commonMain/composeResources/values/strings.xml
  • shared/src/commonMain/composeResources/values-de/strings.xml
  • shared/src/commonMain/composeResources/values-es/strings.xml
  • shared/src/commonMain/composeResources/values-fr/strings.xml
  • shared/src/commonMain/composeResources/values-nl/strings.xml
  • shared/src/androidHostTest/kotlin/com/devil/phoenixproject/data/local/SchemaParityTest.kt
  • shared/src/androidHostTest/kotlin/com/devil/phoenixproject/data/repository/SqlDelightSyncRepositoryTest.kt
  • shared/src/androidHostTest/kotlin/com/devil/phoenixproject/e2e/WorkoutFlowE2ETest.kt
  • shared/src/androidHostTest/kotlin/com/devil/phoenixproject/presentation/viewmodel/DiagnosticsViewModelTest.kt
  • shared/src/androidHostTest/kotlin/com/devil/phoenixproject/presentation/viewmodel/MainViewModelTest.kt
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/data/ble/DiagnosticFaultDecoderTest.kt
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/data/ble/HardwareValidationTest.kt (deleted)
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/data/ble/ProtocolParserTest.kt
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/data/integration/HealthDataMappingTest.kt
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/presentation/util/WeightDisplayFormatterTest.kt
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/util/BleConstantsTest.kt
  • shared/src/commonTest/kotlin/com/devil/phoenixproject/util/BlePacketFactoryTest.kt
  • androidApp/src/main/res/xml/backup_rules.xml
  • androidApp/src/main/res/xml/data_extraction_rules.xml
  • docs/index.html
  • docs/superpowers/specs/2026-06-16-per-cable-weight-handling-design.md (renamed)
  • iosApp/README.md
  • iosApp/TESTFLIGHT_NOTES.txt
  • ANDROID_INSTALL.md, iOS_INSTALL.md
  • .github/ISSUE_TEMPLATE/bug_report.yml
  • .almanac/pages/machine-diagnostics.md
  • third_party/kable-core-android-patched/README.md, BluetoothGatt.kt
  • final-visuals/ (112 PNGs, deleted, unreferenced)

Fix these issues in Kilo Cloud


Reviewed by minimax-m3 · Input: 52.8K · Output: 4K · Cached: 305.5K

Review guidance: REVIEW.md from base branch main

@9thLevelSoftware
9thLevelSoftware merged commit f937ad1 into main Aug 21, 2026
9 of 10 checks passed
@9thLevelSoftware
9thLevelSoftware deleted the fix/vitruvian-ip-detachment-audit branch August 21, 2026 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants