Skip to content

Add manual provider subscription reminder foundation#1137

Open
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:feature/manual-provider-subscription-reminders
Open

Add manual provider subscription reminder foundation#1137
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:feature/manual-provider-subscription-reminders

Conversation

@Yuxin-Qiao
Copy link
Copy Markdown
Contributor

Narrow, manual-only foundation PR for provider subscription reminders.

Adds:

  • Provider-neutral manual subscription snapshot model
  • Optional local config fields for manual renewal/expiry dates
  • Separate subscription menu line formatting (not quota/reset)
  • Dedupeable reminder timing logic (30/7/3/1 days, today, expired)
  • Focused tests

Does not add:

  • Billing-page scraping, cookie/session reads, or billing endpoint calls
  • Any diagnostic export changes
  • Any raw account/billing identifiers or raw provider payload storage

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 24, 2026

Codex review: needs real behavior proof before merge. Reviewed May 27, 2026, 12:11 PM ET / 16:11 UTC.

Summary
The branch adds provider-neutral manual subscription snapshots, config docs, a separate menu subscription row, renewal/expiry reminder notification logic with dedupe state, and focused tests.

Reproducibility: yes. for the review finding: source inspection shows every subscription reminder evaluation writes result.state through SettingsStore.updateConfig, which schedules persistence and bumps config revision. Runtime proof of the intended menu/notification behavior is still not present.

Review metrics: 2 noteworthy metrics.

  • Patch Surface: 15 files, +902/-13. The change crosses config, menu rendering, notifications, refresh paths, tests, and docs, so review needs more than a unit-test-only gate.
  • Persisted Config Fields: 2 added. subscriptionSnapshot and subscriptionReminderState become part of the local provider config contract and require upgrade-safety review.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • Add redacted built-app proof for the manual config, menu row, and reminder notification path.
  • Change reminder state persistence so unchanged state does not rewrite or bump local config.
  • Show validation after the persistence fix, preferably including the focused subscription reminder tests and repository check command expected by AGENTS.md.

Proof guidance:
Needs real behavior proof before merge: The PR discussion lists lint, filtered tests, and CI only; it still needs redacted screenshot/recording, terminal/live output, linked artifact, or logs showing the built app loading subscriptionSnapshot, rendering the Subscription row, and posting a reminder. Redact private details such as API keys, account identifiers, endpoints, and personal data; after adding proof, updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A short desktop proof would materially help because the change is visible in the CodexBar menu and macOS notification path, not only in unit tests. A maintainer can ask Mantis to capture proof by posting a new PR comment that starts with the OpenClaw Mantis account mention, followed by:

visual task: verify CodexBar with a redacted subscriptionSnapshot shows a separate Subscription row and posts one renewal/expiry reminder without changing quota reset rows.

Risk before merge

  • The new provider config schema stores both user-supplied subscription metadata and app-owned reminder dedupe state, so maintainers should explicitly accept that persisted config contract before merge.
  • Real behavior proof is still mock/CI-only; the PR discussion does not show the built app loading a redacted config, rendering the menu row, or posting a reminder.
  • As written, configured subscriptions can cause repeated config persist/revision churn on every refresh even when no reminder state changes.

Maintainer options:

  1. Stabilize Config Persistence First (recommended)
    Persist subscription reminder state only when it differs from the stored state, then add or update a focused test that fails on redundant config revision/persist churn.
  2. Accept Config-Backed Dedupe State
    Maintainers can intentionally accept app-owned dedupe state in the user config, but should do so with explicit upgrade/runtime proof for the manual config path.
  3. Pause For Storage Direction
    If reminder dedupe state should not live in user-editable provider config, pause this PR and move that state to an app-owned persistence store before landing the feature.

Next step before merge
Needs contributor real behavior proof and maintainer sign-off on the new config-backed notification state; the code defect is narrow, but the proof gate makes this human-owned for now.

Security
Cleared: No concrete security or supply-chain issue found; the diff adds manual config metadata, local notification logic, docs, and tests without new dependency, workflow, credential, cookie, scraping, or network-execution paths.

Review findings

  • [P2] Persist reminder state only when it changes — Sources/CodexBar/UsageStore.swift:905-906
Review details

Best possible solution:

Land a narrow version that only persists reminder state when it changes, keeps the manual metadata privacy boundary, and includes redacted built-app proof of the menu and notification path.

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

Yes for the review finding: source inspection shows every subscription reminder evaluation writes result.state through SettingsStore.updateConfig, which schedules persistence and bumps config revision. Runtime proof of the intended menu/notification behavior is still not present.

Is this the best way to solve the issue?

No as proposed: the feature boundary is narrow, but the implementation should avoid unchanged config writes and needs redacted built-app proof before it is the best merge path.

Full review comments:

  • [P2] Persist reminder state only when it changes — Sources/CodexBar/UsageStore.swift:905-906
    handleProviderSubscriptionReminders calls setProviderSubscriptionReminderState on every evaluation with a displayable subscription, even when result.state is identical and no event fired. Because updateConfig schedules persistence and bumps the config revision, a configured provider can rewrite/sync the user config on every refresh or failure poll; only persist when the stored state actually changes.
    Confidence: 0.87

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 83ed8e405541.

Label changes

Label justifications:

  • P2: This is a normal-priority feature PR with bounded user impact but a real config-persistence defect and missing runtime proof.
  • merge-risk: 🚨 compatibility: The PR adds persisted provider config fields and writes app-owned reminder state into local config, which can affect upgrade and sync behavior outside CI coverage.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR discussion lists lint, filtered tests, and CI only; it still needs redacted screenshot/recording, terminal/live output, linked artifact, or logs showing the built app loading subscriptionSnapshot, rendering the Subscription row, and posting a reminder. Redact private details such as API keys, account identifiers, endpoints, and personal data; after adding proof, updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Repository policy read: AGENTS.md was read fully; its guidance on focused provider/config tests, provider data siloing, and validating UI/runtime behavior against a fresh bundle is relevant here. (AGENTS.md:1, 83ed8e405541)
  • Actual merge surface: The GitHub merge result changes 15 files with 902 insertions and 13 deletions, confined to the subscription reminder/config/menu/test/doc surface rather than the stale direct head-vs-main diff. (f3dddca4e1bf)
  • Feature not already on main: Current main has provider-specific billing/subscription code, but no provider-neutral subscriptionSnapshot/ProviderSubscriptionSnapshot config surface or Subscription menu row matching this PR. (83ed8e405541)
  • New persisted config fields: The PR adds subscriptionSnapshot and subscriptionReminderState to ProviderConfig, which makes this a user-config compatibility surface rather than only in-memory UI logic. (Sources/CodexBarCore/Config/CodexBarConfig.swift:87, f3dddca4e1bf)
  • Redundant config persistence path: handleProviderSubscriptionReminders writes result.state back to settings on every evaluation; SettingsStore.updateConfig always schedules persistence and bumps config revision after mutation, even when the state did not change. (Sources/CodexBar/UsageStore.swift:905, f3dddca4e1bf)
  • Focused tests added: The PR adds tests for config round-trip, ISO-8601 date decoding, failure-path reminder evaluation, formatter output, dedupe behavior across relaunch, and menu separation from quota rows. (Tests/CodexBarTests/ProviderSubscriptionReminderFoundationTests.swift:1, f3dddca4e1bf)

Likely related people:

  • Peter Steinberger: Blame and shortlog show the current ProviderConfig, MenuDescriptor, SettingsStore config, and UsageStore surfaces are dominated by recent commits under this name, including the current main/release commit and provider usage expansion work. (role: recent area contributor; confidence: high; commits: 81cf30a6d5e1, d715648cf23d, daaa271c27e6; files: Sources/CodexBarCore/Config/CodexBarConfig.swift, Sources/CodexBar/MenuDescriptor.swift, Sources/CodexBar/UsageStore.swift)
  • Ratul Sarna: History shows substantial prior work in account/menu/config flows and multi-account behavior that this subscription row and provider config path builds beside. (role: adjacent owner; confidence: medium; commits: dd200dac317d, 89c6ce806648, a1813708d728; files: Sources/CodexBar/MenuDescriptor.swift, Sources/CodexBar/UsageStore.swift, Sources/CodexBarCore/Config/CodexBarConfig.swift)
  • Alekstodo: The quota warning controls and markers history is the closest existing per-provider warning/reminder pattern that this PR extends with subscription reminders. (role: adjacent notification contributor; confidence: medium; commits: 18eb73dde236; files: Sources/CodexBar/UsageStore.swift, Sources/CodexBar/SettingsStore+Config.swift, Tests/CodexBarTests/QuotaWarningNotificationLogicTests.swift)
  • Yuxin Qiao: Separate from authoring this PR, current main history shows prior merged display work touching the same usage/menu/config area. (role: recent adjacent contributor; confidence: medium; commits: e9b7e25f851b; files: Sources/CodexBar/UsageStore.swift, Sources/CodexBar/MenuDescriptor.swift, Sources/CodexBarCore/Config/CodexBarConfig.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.

Copy link
Copy Markdown

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

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: 111ccbf7d5

ℹ️ 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".

let backfilled = scoped.backfillingResetTimes(from: self.lastKnownResetSnapshots[provider])
self.handleQuotaWarningTransitions(provider: provider, snapshot: backfilled)
self.handleSessionQuotaTransition(provider: provider, snapshot: backfilled)
self.handleProviderSubscriptionReminders(provider: provider)
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 Evaluate subscription reminders outside success-only refresh

handleProviderSubscriptionReminders is only called in the successful usage-fetch path here, and it is likewise absent from the failure branches in the token-account refresh paths. That means reminder events never fire when a provider is temporarily failing (offline/auth errors), even though subscriptionSnapshot is local manual config and does not depend on live usage payloads. Users can therefore miss 30/7/3/1-day and expired reminders during outages; run reminder evaluation independently of fetch success (or in both success and failure paths).

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 May 24, 2026
@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels May 24, 2026
@Yuxin-Qiao
Copy link
Copy Markdown
Contributor Author

Current head proof (06bde3c), redacted:

  • Manual subscriptionSnapshot (ISO-8601 dates) loads from local config and renders as a separate Subscription row (not quota/reset).
  • Reminder evaluation now runs even when provider fetch fails (not success-only), covering 30/7/3/1 days, today, and expired thresholds.

Validation on this head:

  • ./Scripts/lint.sh lint ✅
  • swift test --filter ProviderSubscriptionReminderFoundationTests ✅
  • swift test --filter UsageStoreSessionQuotaTransitionTests ✅
  • PR CI checks ✅

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 24, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

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. P2 Normal priority bug or improvement with limited blast radius. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant