Skip to content

feat: factor weeklyProgressWorkDays into pace calculation#1357

Open
pstanton237 wants to merge 2 commits into
steipete:mainfrom
pstanton237:feat/workday-aware-pace
Open

feat: factor weeklyProgressWorkDays into pace calculation#1357
pstanton237 wants to merge 2 commits into
steipete:mainfrom
pstanton237:feat/workday-aware-pace

Conversation

@pstanton237

@pstanton237 pstanton237 commented Jun 8, 2026

Copy link
Copy Markdown

Live app proof (Mon 22:00 KST, Settings > Display > Work Days = 5)

Before (main, 7-day linear) After (feat, 5-day workday)
Before: 2% in deficit After: 9% in deficit
27% used, 2% in deficit 27% used, 9% in deficit

Same usage, same time — the 5-day model distributes expected usage across configured work days only.

Summary

Threads the existing weeklyProgressWorkDays setting into the pace calculation so the expected usage curve distributes 100% across only the configured work days. Non-work days contribute zero expected usage, making the pace indicator accurate for users who only work on weekdays.

  • Adds workDays parameter to UsagePace.weekly()
  • Introduces workdayAwareExpected() which walks calendar day boundaries and classifies each slice by its actual calendar weekday (Mon=1..Sun=7, workday if isoWeekday <= workDays)
  • Passes weeklyProgressWorkDays from settings through all call sites
  • Falls back to linear model when workDays is nil, 7, or window is not 10080 minutes

Before / After

Scenario (5-day user, Friday 18:00) Before After
Expected usage 82% (linear 7-day) 95% (workday-aware)
100% actual → pace verdict 18% deficit 5% deficit (on pace)

After-fix proof (test run output)

✔ Test "weekly pace hides when usage exists but no elapsed" passed after 0.001 seconds.
✔ Test "session pace computes delta and eta for five hour window" passed after 0.001 seconds.
✔ Test "weekly pace computes delta and eta" passed after 0.001 seconds.
✔ Test "weekly pace hides when reset missing or outside window" passed after 0.001 seconds.
✔ Test "workday aware pace falls back to linear when workDays is nil or 7" passed after 0.001 seconds.
✔ Test "weekly pace marks lasts to reset when usage is low" passed after 0.001 seconds.
✔ Test "workday aware pace ignores non weekly windows" passed after 0.001 seconds.
✔ Test "workday aware pace shows on track for five day user on friday" passed after 0.001 seconds.
✔ Test "workday aware pace shows on track midweek" passed after 0.001 seconds.
✔ Suite UsagePaceTests passed after 0.001 seconds.

Verified on macOS 15.4, Swift 6.1, swift test --filter UsagePaceTests (2026-06-08).

Compatibility note

This PR intentionally reuses the existing weeklyProgressWorkDays setting (Off/4/5/7 in Display preferences). Users who previously set this value for visual markers will now also get workday-aware pace. This is the natural intent of the setting — a user who configured "5 days" wants their quota framed around a 5-day work week, both visually and in pace calculation. If maintainers prefer a separate opt-in, this can be split, but we believe the unified setting is the correct UX.

When Codex historical pace is active (historicalTrackingEnabled), it takes precedence over the workday model because it already incorporates actual usage patterns. The workday model serves as the baseline for users without historical data or for non-Codex providers.

Test plan

  • workday aware pace shows on track for five day user on friday — verifies 7-day model reports deficit, 5-day model reports on-pace
  • workday aware pace shows on track midweek — Wed 18:00 with 60% used ≈ on pace for 5-day model
  • workday aware pace falls back to linear when workDays is nil or 7
  • workday aware pace ignores non weekly windows — session windows unaffected
  • All existing UsagePaceTests and HistoricalUsagePaceTests pass unchanged

Fixes #1356
Follow-up to #1096 (visual segmentation)

The existing weeklyProgressWorkDays setting only affected visual markers
on the progress bar. This change threads the work-days value into
UsagePace.weekly() so that the expected usage curve distributes 100%
across configured work days only. Non-work days contribute zero expected
usage, producing a flat curve on weekends.

Users who work Mon-Fri and consume 100% by Friday now see "on pace"
instead of a misleading ~29% deficit from the 7-day linear model.

Fixes steipete#1356
@clawsweeper

clawsweeper Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codex review: found issues before merge. Reviewed June 8, 2026, 9:23 AM ET / 13:23 UTC.

Summary
This PR adds a workDays parameter to weekly pace calculation, passes weeklyProgressWorkDays through menu/store pace call sites, and adds workday-aware UsagePace tests.

Reproducibility: not applicable. as a feature PR rather than a broken existing-behavior report. Source inspection confirms current main is linear, and the PR screenshots demonstrate the intended visible behavior change.

Review metrics: 1 noteworthy metric.

  • Persisted Setting Reused: 1 existing preference broadened. The diff changes the runtime meaning of stored weeklyProgressWorkDays values, which is the main merge decision.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🐚 platinum hermit ✨ media proof bonus
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Get maintainer approval for the unified Work Days semantics, or split marker and pace behavior before merge.
  • [P2] If unified behavior is approved, add explicit upgrade coverage or PR-body release-note context for existing saved 4/5-day settings.

Risk before merge

  • [P1] Existing users who already set Display > Work Days to 4 or 5 for visual markers will get different weekly pace labels immediately after upgrade, without a separate opt-in or migration.
  • [P1] For Codex accounts with successful historical pace, the same setting still does not control the displayed pace, so the unified-setting UX needs explicit maintainer acceptance.

Maintainer options:

  1. Approve Unified Setting
    Maintainers can intentionally accept that the existing Work Days display preference now also controls weekly pace and ask for explicit upgrade coverage or PR-body release-note context.
  2. Split Marker And Pace Semantics
    The contributor can preserve current marker-only behavior by adding a separate pace control or migration path, then test both old and new upgrade states.
  3. Pause For Linked Issue Decision
    If the product direction is not settled, keep this PR paused while the linked feature issue decides whether workday-aware pace belongs behind the existing preference.

Next step before merge

  • [P2] A maintainer needs to decide whether changing the semantics of the existing persisted Work Days preference is acceptable before this PR can merge.

Security
Cleared: The diff is limited to pace calculation, menu call sites, and tests; it does not touch dependencies, CI, secrets, auth, or code download paths.

Review findings

  • [P1] Do not reuse the marker preference without an upgrade decision — Sources/CodexBar/UsageStore+HistoricalPace.swift:12
Review details

Best possible solution:

Make the desired semantics explicit: either preserve marker-only behavior with a separate pace opt-in, or land the unified setting with maintainer sign-off plus upgrade coverage or documentation.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a feature PR rather than a broken existing-behavior report. Source inspection confirms current main is linear, and the PR screenshots demonstrate the intended visible behavior change.

Is this the best way to solve the issue?

Unclear until maintainers decide the product semantics. The calculation approach is bounded, but reusing the existing persisted marker preference is not clearly the safest upgrade path without explicit approval.

Full review comments:

  • [P1] Do not reuse the marker preference without an upgrade decision — Sources/CodexBar/UsageStore+HistoricalPace.swift:12
    This starts applying the persisted weeklyProgressWorkDays value to weekly pace calculations. That value was introduced for display-only weekly tick marks, so existing users who selected 4 or 5 days for markers will see different deficit/reserve labels after upgrade unless maintainers explicitly approve this compatibility change or the PR preserves marker-only semantics by default.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.87

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against db184430bc4b.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body now includes visible live app before/after screenshots showing the weekly deficit changing for the same usage, supplemented by focused test output.
  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body now includes visible live app before/after screenshots showing the weekly deficit changing for the same usage, supplemented by focused test output.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body now includes visible live app before/after screenshots showing the weekly deficit changing for the same usage, supplemented by focused test output.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: ⏳ waiting on author.

Label justifications:

  • P3: This is a useful but low-urgency UX/feature improvement around usage pace presentation.
  • merge-risk: 🚨 compatibility: The PR changes behavior for existing users who already saved the Work Days preference for visual markers only.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body now includes visible live app before/after screenshots showing the weekly deficit changing for the same usage, supplemented by focused test output.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body now includes visible live app before/after screenshots showing the weekly deficit changing for the same usage, supplemented by focused test output.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body now includes visible live app before/after screenshots showing the weekly deficit changing for the same usage, supplemented by focused test output.
Evidence reviewed

What I checked:

  • Repository policy read: AGENTS.md was read fully; its focused-test and macOS prompt guidance shaped the review, and VISION.md says new features and behavior changes need sign-off. (AGENTS.md:1, db184430bc4b)
  • Current main still uses linear weekly pace: UsagePace.weekly computes expected usage as elapsed divided by duration, with no workday input on current main. (Sources/CodexBarCore/UsagePace.swift:54, db184430bc4b)
  • Existing setting is a Display preference: The existing weeklyProgressWorkDays picker is in Display settings and currently feeds visual weekly marker placement. (Sources/CodexBar/PreferencesDisplayPane.swift:90, db184430bc4b)
  • PR reuses persisted setting for pace: The PR reads self.settings.weeklyProgressWorkDays in UsageStore.weeklyPace and passes it into generic weekly pace fallbacks. (Sources/CodexBar/UsageStore+HistoricalPace.swift:12, eb9a929110c7)
  • Real behavior proof inspected: Downloaded proof screenshots show the live app weekly row changing between 27% used / 2% in deficit and 27% used / 9% in deficit; the attachment order appears reversed relative to the PR table labels, but the after-fix behavior is visible.
  • Prior review feedback addressed in branch: The earlier bot review flagged non-midnight reset handling; the latest PR commit says it now splits intervals at calendar day boundaries. (Sources/CodexBarCore/UsagePace.swift:114, eb9a929110c7)

Likely related people:

  • Peter Steinberger: Recent commits adjusted Cursor and Codex Spark pace details, and the workday marker feature commit lists Peter as co-author. (role: recent area contributor; confidence: high; commits: 91824283af5f, 610bdbc9c39c, e9b7e25f851b; files: Sources/CodexBar/MenuCardView+ModelHelpers.swift, Sources/CodexBar/UsageStore+HistoricalPace.swift, Sources/CodexBar/MenuCardQuotaWarningMarkers.swift)
  • Yuxin Qiao: Authored the merged workday segmentation feature that added weeklyProgressWorkDays as a display-marker preference. (role: introduced related setting; confidence: high; commits: e9b7e25f851b; files: Sources/CodexBar/MenuCardQuotaWarningMarkers.swift, Sources/CodexBar/PreferencesDisplayPane.swift, Sources/CodexBar/SettingsStore+Defaults.swift)
  • Remedy92: Authored the original weekly pace indicator implementation and UsagePace core type. (role: introduced weekly pace behavior; confidence: medium; commits: a679311227fc; files: Sources/CodexBarCore/UsagePace.swift, Sources/CodexBar/UsagePaceText.swift, Tests/CodexBarTests/UsagePaceTextTests.swift)
  • zhulijin1991: Authored the Codex visible weekly pace detail change, one of the central call paths this PR updates. (role: adjacent feature contributor; confidence: medium; commits: 599c017483ba; files: Sources/CodexBar/MenuCardView.swift, Tests/CodexBarTests/MenuCardModelCodexProjectionTests.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ebdb2d2217

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Sources/CodexBarCore/UsagePace.swift Outdated
// (workDays=5 → Mon-Fri are work days)
var dayCursor = windowStart
while dayCursor < resetsAt {
let dayEnd = min(dayCursor.addingTimeInterval(daySeconds), resetsAt)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Split workday pace at local day boundaries

When the weekly reset is not at local midnight, this loop walks 24-hour slices anchored to windowStart and labels the entire slice by the slice's starting weekday. For example, with a Sunday 20:00 local reset and 5 workdays, Monday 00:00–20:00 is counted as Sunday/non-work, so expected usage stays at 0 for most of Monday and the whole workday curve is shifted by the reset time. Since resetsAt can be any Date, the workday-aware calculation should split intervals on calendar day boundaries before classifying them.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 8, 2026
Address Codex bot review feedback: when the weekly reset time is not at
midnight, the previous 24-hour-slice approach could misclassify hours
near day boundaries. Now uses calendar.startOfDay to split intervals at
local midnight, ensuring each slice is classified by its actual calendar
weekday regardless of reset time offset.
@clawsweeper clawsweeper Bot added P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: factor weeklyProgressWorkDays into pace calculation

1 participant