Skip to content

feat: Add dynamic upper bound for speed test gauge based on historical data - #628

Merged
AustinChangLinksys merged 6 commits into
dev-2.0.0from
peter/speedtest-upper-bound-624
Feb 12, 2026
Merged

feat: Add dynamic upper bound for speed test gauge based on historical data#628
AustinChangLinksys merged 6 commits into
dev-2.0.0from
peter/speedtest-upper-bound-624

Conversation

@PeterJhongLinksys

Copy link
Copy Markdown
Collaborator

Summary

The speed test gauge now automatically adjusts its upper limit based on historical test results, providing better visualization across different network speed ranges.

Changes

  • Added helper methods to calculate maximum historical speed and round to nearest hundred
  • Implemented dynamic marker generation based on the upper bound
  • Updated meterView and _startButton methods to use dynamic markers instead of fixed 100 Mbps limit

Behavior

  • No history: Defaults to 100 Mbps (maintains backward compatibility)
  • With history: Uses maximum speed from history, rounded up to nearest hundred
    • Example: 345 Mbps → 400 Mbps upper bound
    • Example: 89 Mbps → 100 Mbps (minimum)
    • Example: 1234 Mbps → 1300 Mbps upper bound
  • Markers: Distributed appropriately for different speed ranges
    • 100-200 Mbps: [0, 10, 20, 30, 50, 75, 100, 150, upperBound]
    • 200-500 Mbps: [0, 50, 100, 150, 200, 250, 300, 400, upperBound]
    • 500-1000 Mbps: [0, 100, 200, 300, 400, 500, 750, upperBound]
    • 1000+ Mbps: [0, 200, 400, 600, 800, 1000, 1200, ...]

Testing

  • ✅ Static analysis passed (flutter analyze)
  • ✅ All functional tests passed (23/23)
  • ⚠️ Manual testing recommended: Test with different network speeds to verify gauge scaling

Files Changed

  • lib/page/health_check/shared_widgets/speed_test_widget.dart (+140, -15)

🤖 Generated with Claude Code

PeterJhongLinksys and others added 3 commits February 11, 2026 17:14
- Add Article XIV: UI Kit Library Principle with mandatory UI component usage rules
- Translate all remaining Chinese content in constitution.md to English
- Update "Last Amended" date to 2026-02-11

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ion compliance

Create new Claude Code skill that automatically enforces project constitution principles during feature implementation.

Key features:
- Requirements clarity check before implementation starts
- Integrates with brainstorming skill for unclear requirements
- Enforces UI Kit Library usage with component verification
- Mandates test coverage (Service ≥90%, Provider ≥85%, Overall ≥80%)
- Automates testing execution (unit tests + screenshot tests)
- Runs code formatting (dart format) and analysis (flutter analyze)
- Validates architecture compliance (layer separation, error handling)
- Provides decision trees and examples for common scenarios

The skill automatically triggers on keywords like 實作, 創建, 新增, 開發, 修改, 重構, 修正, etc., ensuring consistent adherence to constitution without manual reminders.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…l data

The speed test gauge now automatically adjusts its upper limit based on
historical test results, providing better visualization across different
network speed ranges.

Changes:
- Add helper methods to calculate maximum historical speed and round to
  nearest hundred
- Generate appropriate markers dynamically based on the upper bound
- Update meterView and _startButton to use dynamic markers instead of
  fixed 100 Mbps limit

Behavior:
- No history: defaults to 100 Mbps (maintains backward compatibility)
- With history: uses maximum speed from history, rounded up to nearest
  hundred (e.g., 345 Mbps → 400 Mbps upper bound)
- Markers are distributed appropriately for different speed ranges
  (100-200, 200-500, 500-1000, 1000+ Mbps)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Add dynamic speed test gauge scaling and constitution compliance automation

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add dynamic gauge upper bound calculation based on historical speed test data
• Implement adaptive marker generation for different speed ranges (100-1000+ Mbps)
• Replace fixed 100 Mbps limit with intelligent scaling using maximum historical speeds
• Add comprehensive constitution compliance skill for automated feature implementation
• Translate constitution.md to English and add UI Kit Library principle (Article XIV)
Diagram
flowchart LR
  A["Historical Speed Data"] -->|Calculate Max Speed| B["Round to Nearest Hundred"]
  B -->|Determine Range| C["Generate Adaptive Markers"]
  C -->|Apply to Gauge| D["Dynamic Upper Bound Gauge"]
  E["Constitution Requirements"] -->|Verify Compliance| F["Automated Implementation Skill"]
  F -->|Enforce Rules| G["Code Quality & Testing"]
Loading

Grey Divider

File Changes

1. lib/page/health_check/shared_widgets/speed_test_widget.dart ✨ Enhancement +140/-15

Implement dynamic gauge scaling with adaptive markers

• Add _calculateMaxHistoricalSpeed() method to extract maximum speed from historical and latest
 test results, with 100 Mbps default fallback
• Add _roundUpToHundred() method to round speeds up to nearest hundred with 100 Mbps minimum
• Add _calculateGaugeUpperBound() method to compute dynamic upper bound for gauge scaling
• Add _generateMarkers() method with range-specific marker distribution (100-200, 200-500,
 500-1000, 1000+ Mbps ranges)
• Update meterView() to use dynamic markers instead of fixed [0, 1, 5, 10, 20, 30, 50, 75, 100]
• Update _startButton() to apply dynamic markers based on historical data in idle state

lib/page/health_check/shared_widgets/speed_test_widget.dart


2. .claude/skills/implement-feature-with-checks/SKILL.md 📝 Documentation +384/-0

Create automated constitution compliance enforcement skill

• Create comprehensive skill for automated constitution compliance enforcement during feature
 implementation
• Define 6-phase execution workflow: requirements clarity check, constitution review, UI Kit
 verification, implementation, testing, and final verification
• Implement requirements clarity detection with decision tree to identify when brainstorming is
 needed
• Add UI Kit component verification with mandatory stop-and-ask pattern when components are missing
• Include test coverage requirements (Service ≥90%, Provider ≥85%, Overall ≥80%) and automated
 execution commands
• Provide architecture compliance verification commands and success criteria checklist
• Include 4 detailed examples covering feature creation, refactoring, bug fixes, and unclear
 requirements scenarios

.claude/skills/implement-feature-with-checks/SKILL.md


3. constitution.md 📝 Documentation +170/-95

Translate constitution to English and add UI Kit principle

• Translate all remaining Chinese content in constitution.md to English (Articles III, X, XI, XII,
 XIII)
• Add Article XIV: UI Kit Library Principle with mandatory component usage rules and stop-and-ask
 pattern
• Update file naming conventions section with English descriptions and examples
• Translate class naming patterns, test naming conventions, and error handling sections
• Translate Riverpod usage principles, Dirty Guard feature documentation, and error handling
 strategy
• Update "Last Amended" date from 2025-12-17 to 2026-02-11

constitution.md


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Feb 11, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Non-English text in SKILL.md 📘 Rule violation ✓ Correctness
Description
The newly added .claude skill documentation contains Traditional Chinese text, violating the
requirement that repository comments/documentation be English-only. This reduces consistency and may
hinder comprehension for English-only reviewers.
Code

.claude/skills/implement-feature-with-checks/SKILL.md[3]

+description: Automatically enforce constitution compliance, UI Kit usage, testing, and code formatting when implementing features with CLEAR and SPECIFIC requirements. Use AFTER brainstorming or requirements clarification is complete, when user provides concrete implementation details. Do NOT use if requirements are vague or unclear - suggest brainstorming first. Trigger keywords (English) - implement, create, add, build, develop, make, modify, update, change, refactor, fix, repair. Trigger keywords (Chinese) - 實作, 創建, 新增, 開發, 製作, 修改, 更新, 改動, 重構, 修正, 修復, 修好.
Evidence
PR Compliance ID 7 requires all new/modified comments to be written in English only. The added
SKILL.md includes multiple Traditional Chinese phrases (e.g., trigger keywords and example user
prompts), which violates this requirement.

CLAUDE.md
.claude/skills/implement-feature-with-checks/SKILL.md[3-3]
.claude/skills/implement-feature-with-checks/SKILL.md[75-75]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `.claude/skills/implement-feature-with-checks/SKILL.md` file contains Traditional Chinese text (e.g., trigger keywords and example phrases). Compliance requires repository comments/documentation to be English-only.
## Issue Context
This PR introduces a new skill documentation file. It should be consistent and universally understandable per the English-only requirement.
## Fix Focus Areas
- .claude/skills/implement-feature-with-checks/SKILL.md[1-384]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


✅ 2. Unsorted gauge markers 🐞 Bug ✓ Correctness
Description
For upperBound values between 600–700 Mbps, _generateMarkers() adds a 750 marker unconditionally,
producing markers that exceed upperBound and are not sorted. This can cause incorrect AppGauge
rendering and may trigger assertions/logic errors if the gauge assumes markers are within range and
ascending.
Code

lib/page/health_check/shared_widgets/speed_test_widget.dart[R169-182]

+    } else if (upperBound <= 1000) {
+      // 500-1000 Mbps range
+      // Generate markers at 100 Mbps intervals, with an extra marker at 750
+      final markers = <double>[0];
+      for (double i = 100; i <= 500; i += 100) {
+        markers.add(i);
+      }
+      markers.add(750);
+      if (upperBound != 1000) {
+        markers.add(upperBound);
+      } else {
+        markers.add(1000);
+      }
+      return markers;
Evidence
upperBound is derived by rounding up historical max speed to the nearest hundred (e.g., 600, 700 are
valid). In the 500–1000 branch, the code always inserts 750 before appending upperBound; if
upperBound is 600/700, the marker list contains a value above the upper bound and becomes
out-of-order (e.g., ... 750, 600).

lib/page/health_check/shared_widgets/speed_test_widget.dart[113-127]
lib/page/health_check/shared_widgets/speed_test_widget.dart[129-134]
lib/page/health_check/shared_widgets/speed_test_widget.dart[169-182]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`_generateMarkers()` can return marker values larger than `upperBound` and out-of-order (e.g., `upperBound=600` yields `... 750, 600`). This can break gauge rendering/logic.
### Issue Context
`upperBound` is computed by rounding historical max speed up to the nearest hundred, so values like 600 and 700 are expected.
### Fix Focus Areas
- lib/page/health_check/shared_widgets/speed_test_widget.dart[169-182]
- lib/page/health_check/shared_widgets/speed_test_widget.dart[113-134]
### Implementation notes
- Only add `750` when `upperBound &amp;amp;amp;gt;= 750`.
- Always append `upperBound` as the maximum marker.
- Optionally: `final sorted = {...markers}.toList()..sort();` and ensure all markers `&amp;amp;amp;lt;= upperBound`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

✅ 3. Constitution date mismatch 🐞 Bug ✓ Correctness
Description
constitution.md now contains conflicting “Last Amended” dates between the header and the new footer,
which can confuse contributors and any governance process relying on this metadata.
Code

constitution.md[1160]

+**Version**: 1.0.0 | **Ratified**: 2025-12-09 | **Last Amended**: 2026-02-11
Evidence
The document header still declares “Last Amended: 2025-12-22”, while the updated footer declares
“Last Amended: 2026-02-11”. After this PR’s addition of Article XIV and updated footer metadata,
these values disagree within the same file.

constitution.md[3-8]
constitution.md[1160-1160]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`constitution.md` contains two conflicting “Last Amended” fields (header vs footer). This inconsistency was amplified by updating the footer date while leaving the header unchanged.
### Issue Context
The header is typically treated as document metadata and should reflect the latest amendment date to avoid confusion.
### Fix Focus Areas
- constitution.md[3-8]
- constitution.md[1160-1160]
### Suggested approach
- Set header `**Last Amended:**` to `2026-02-11` (to match the footer), or
- Remove the footer date line and keep a single source of truth in the header.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@@ -0,0 +1,384 @@
---
name: implement-feature-with-checks
description: Automatically enforce constitution compliance, UI Kit usage, testing, and code formatting when implementing features with CLEAR and SPECIFIC requirements. Use AFTER brainstorming or requirements clarification is complete, when user provides concrete implementation details. Do NOT use if requirements are vague or unclear - suggest brainstorming first. Trigger keywords (English) - implement, create, add, build, develop, make, modify, update, change, refactor, fix, repair. Trigger keywords (Chinese) - 實作, 創建, 新增, 開發, 製作, 修改, 更新, 改動, 重構, 修正, 修復, 修好.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Non-english text in skill.md 📘 Rule violation ✓ Correctness

The newly added .claude skill documentation contains Traditional Chinese text, violating the
requirement that repository comments/documentation be English-only. This reduces consistency and may
hinder comprehension for English-only reviewers.
Agent Prompt
## Issue description
The new `.claude/skills/implement-feature-with-checks/SKILL.md` file contains Traditional Chinese text (e.g., trigger keywords and example phrases). Compliance requires repository comments/documentation to be English-only.

## Issue Context
This PR introduces a new skill documentation file. It should be consistent and universally understandable per the English-only requirement.

## Fix Focus Areas
- .claude/skills/implement-feature-with-checks/SKILL.md[1-384]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +169 to +182
} else if (upperBound <= 1000) {
// 500-1000 Mbps range
// Generate markers at 100 Mbps intervals, with an extra marker at 750
final markers = <double>[0];
for (double i = 100; i <= 500; i += 100) {
markers.add(i);
}
markers.add(750);
if (upperBound != 1000) {
markers.add(upperBound);
} else {
markers.add(1000);
}
return markers;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Unsorted gauge markers 🐞 Bug ✓ Correctness

For upperBound values between 600–700 Mbps, _generateMarkers() adds a 750 marker unconditionally,
producing markers that exceed upperBound and are not sorted. This can cause incorrect AppGauge
rendering and may trigger assertions/logic errors if the gauge assumes markers are within range and
ascending.
Agent Prompt
### Issue description
`_generateMarkers()` can return marker values larger than `upperBound` and out-of-order (e.g., `upperBound=600` yields `... 750, 600`). This can break gauge rendering/logic.

### Issue Context
`upperBound` is computed by rounding historical max speed up to the nearest hundred, so values like 600 and 700 are expected.

### Fix Focus Areas
- lib/page/health_check/shared_widgets/speed_test_widget.dart[169-182]
- lib/page/health_check/shared_widgets/speed_test_widget.dart[113-134]

### Implementation notes
- Only add `750` when `upperBound >= 750`.
- Always append `upperBound` as the maximum marker.
- Optionally: `final sorted = {...markers}.toList()..sort();` and ensure all markers `<= upperBound`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Fix marker generation bug in _generateMarkers for 500-1000 Mbps range.
Previously, when upperBound was less than 750 (e.g., 600 or 700), the
method unconditionally added 750 marker, resulting in unsorted list
that exceeded the upper bound.

Changes:
- Add conditional check before adding 750 marker (only if upperBound >= 750)
- Ensure markers list maintains ascending order
- Ensure all markers stay within upperBound

Before: upperBound=600 → [0, 100, 200, 300, 400, 500, 750, 600] (unsorted)
After: upperBound=600 → [0, 100, 200, 300, 400, 500, 600] (sorted)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PeterJhongLinksys and others added 2 commits February 12, 2026 15:26
Extract the 4 gauge calculation methods from SpeedTestWidget into a
reusable SpeedTestGaugeUtils class with comprehensive unit tests.

Changes:
- Create SpeedTestGaugeUtils class with 4 static methods:
  - calculateMaxHistoricalSpeed(): Find max speed from history
  - roundUpToHundred(): Round up to nearest hundred
  - calculateGaugeUpperBound(): Calculate dynamic upper bound
  - generateMarkers(): Generate appropriate markers for different ranges
- Add 39 comprehensive unit tests covering all edge cases
- Refactor SpeedTestWidget to use the new utils class
- Remove 4 private methods from SpeedTestWidget (130 lines)

Benefits:
- Improved testability: 100% test coverage for calculation logic
- Better code organization: Follows project pattern (feature/utils/)
- Reusability: Utils can be used in other contexts
- Maintainability: Centralized logic with clear documentation

Testing:
- All 39 utils tests pass
- All 23 existing health_check tests pass (regression)
- Static analysis clean

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

@AustinChangLinksys AustinChangLinksys left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

looks good to me

@AustinChangLinksys
AustinChangLinksys merged commit 20d57dd into dev-2.0.0 Feb 12, 2026
2 checks passed
@AustinChangLinksys
AustinChangLinksys deleted the peter/speedtest-upper-bound-624 branch February 12, 2026 07:55
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.

Clone: [Now-708][Speed Test] The widget UI should be adjusted to display correctly when the speed exceeds 100.

2 participants