Skip to content

fix: correct Astra free and Pro feature claims - #797

Merged
thomasluizon merged 2 commits into
redesign/mainfrom
thomasluizon/ticket-236-pro-claims
Oct 19, 2026
Merged

thomasluizon merged 2 commits into
redesign/mainfrom
thomasluizon/ticket-236-pro-claims

Conversation

@thomasluizon

@thomasluizon thomasluizon commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Fixes thomasluizon/orbit-tickets#236 (ORB-230).

Astra's embedded explanations described free-tier gamification, streak freezes, and AI goal reviews as Pro unlocks. The content now follows the access checks on redesign/main.

Approach

  • freezes.md: the plan sentence now reads "Streak freezes are part of Orbit Pro. Some free accounts have them too." (Pro access, or a per-account flag; no internal name is shown to people). Keep automatic coverage wording.
  • gamification.md: the same rule in product language for XP, levels, and achievements: "XP, levels, and achievements are part of Orbit Pro. Some free accounts have them too." The later ticket comment supersedes the original achievements-as-Pro requirement.
  • paygate.md: remove freezes, gamification, and AI goal reviews from the Pro list. Preserve the shipped daily 5/50 quota and completed-habit exclusion, which match PayGateService.
  • Extend existing gamification, goal-review, and automatic-freeze behavior tests to assert the embedded claims after exercising the real service or handler. Add daily quota and default Pro-gate tests in FeatureExplanationDriftTests, plus chat/MCP content parity in FeatureToolsTests. Keeping these assertions beside the enforcing behavior makes a plan change fail alongside its stale claim.

No access predicate, quota, database row, DTO, or external interface changed. Both tools still read IFeatureExplanationService. The build regenerated OpenAPI with no resulting diff.

Content audit

File Sources checked Result
frequencies.md HabitScheduleService.IsHabitDueOnDate, window start/end, remaining completions No plan-gating claim; unchanged.
notifications.md ReminderSchedulerService relative/scheduled selection and ShouldSendScheduledReminder No plan gate in those reminder paths; unchanged.
schedule-math.md Monthly/yearly matching, overdue checks, DefaultOverdueWindowDays No plan-gating claim; unchanged.
streaks.md ComputeStreakAsOf, UserStreakService.LoadStreakDataAsync, calendar fallback, lookback constant No separate Pro claim; unchanged.
ai-memory.md Not read Already removed from this branch by its owning work; not restored or audited here.

The corrected claims also apply to the inspected origin/main: its gamification and automatic-freeze predicates use Pro-or-flag, its goal-review handler consumes the AI quota, and its affected content has the same stale claims. This PR targets redesign/main as ordered.

Assumptions

  • Keep the existing seven supported feature keys after AI memory removal, rather than restoring the original body's obsolete eighth key. Existing resource and tool-key tests verify the seven-key inventory.

The later round-2 instructions govern the copy. Source identifiers remain in provenance metadata.

Test evidence

Before changing tests or content, existing tests passed with the defects present:

dotnet test tests/Orbit.Application.Tests --no-restore --filter 'FullyQualifiedName~FeatureExplanationDriftTests|FullyQualifiedName~ProcessHabitLogged_FreeUserWithFlag_EarnsXpAndLiftoff|FullyQualifiedName~Handle_FreeUser_GeneratesReview' --nologo
# Exit 0: 7 passed.
dotnet test tests/Orbit.Infrastructure.Tests --filter FullyQualifiedName~ActivateMissedDayFreezes_FreeTierFlagOnlyCoversTargetedAccount --nologo
# Exit 0: 1 passed.

After strengthening tests, with the original markdown still present, the same application selection exited 1 with 2 failures and 7 passes; the automatic-freeze selection exited 1 with 1 failure. Red output:

Orbit.Application.Tests.Queries.Goals.GetGoalReviewQueryHandlerTests.Handle_FreeUser_GeneratesReview [FAIL]
Orbit.Application.Tests.Services.GamificationServiceTests.ProcessHabitLogged_FreeUserWithFlag_EarnsXpAndLiftoff [FAIL]
Orbit.Infrastructure.Tests.Services.StreakFreezeAutoActivationServiceTests.ActivateMissedDayFreezes_FreeTierFlagOnlyCoversTargetedAccount [FAIL]

The new list test was also run before the content fix:

dotnet test tests/Orbit.Application.Tests --no-restore --filter FullyQualifiedName~Paygate_ProUnlocksMatchEnforcedGates --nologo
# Exit 1: 2 failed.
Expected unlocks to contain exactly 4 items in any order because paygate.md must list the features these default plan gates enforce, but found extraneous items "- AI goal reviews" (at index 0), "- Streak freezes" (at index 4), "- Gamification: XP, levels, and achievements" (at index 5)

After the content fix:

dotnet test tests/Orbit.Application.Tests --no-restore --filter 'FullyQualifiedName~FeatureExplanation|FullyQualifiedName~ProcessHabitLogged_FreeUserWithFlag_EarnsXpAndLiftoff|FullyQualifiedName~Handle_FreeUser_GeneratesReview' --nologo
# Exit 0: 19 passed.
dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter 'FullyQualifiedName~ActivateMissedDayFreezes_FreeTierFlagOnlyCoversTargetedAccount|FullyQualifiedName~FeatureToolsTests' --nologo
# Exit 0: 4 passed.

Post-commit verification (all exit 0):

dotnet build Orbit.slnx --nologo
# 0 errors; existing dependency/compiler warnings only.
dotnet test tests/Orbit.Domain.Tests --no-build --nologo
# 797 passed.
dotnet test tests/Orbit.Application.Tests --no-build --nologo
# 5445 passed.
dotnet test tests/Orbit.Infrastructure.Tests --no-build --nologo
# 3938 passed.
dotnet test tests/Orbit.Analyzers.Tests --no-build --nologo
# 40 passed.

Focused selections were also rerun after the commit with --no-build: 19 application and 4 infrastructure checks passed. Commit hooks passed formatting, dash, timeless, root-allowlist, and suppression checks; the push hook passed branch protection. No app server or browser was started. Mutation testing and CI monitoring remain with CI and the orchestrator.

  • Existing tests passed with the defect present: 14 passed.
  • New guard failed before the fix: exit 1, identifying leaked names.
  • Focused tests after the fix: 15 passed.
  • dotnet build Orbit.slnx: exit 0, zero errors.
  • Full suites: Domain 797, Application 5,446, Infrastructure 3,938 passed. Each exited 0.
  • OpenAPI unchanged; commit hooks passed.

Manual steps

Copy approved with /second-opinion (DISAGREE on the claimed defect, posted on this pull request). Normal API deployment. No configuration or database changes required. Confirm deployment through the updated describe_feature responses.

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes Checked all eight changed files against the enforcing access checks and the shared chat/MCP explanation path.

  • Conditional access claims: Freeze and gamification explanations now match Pro access or account-level gamification_free_tier eligibility.
  • Pro feature list: Removes goal reviews, freezes, and gamification from the Pro unlock list without changing entitlement enforcement or quota behavior.
  • Regression coverage: Adds daily-quota and default-plan gate checks, ties explanation assertions to existing behavior tests, and verifies chat/MCP content parity. Focused verification passed all 19 application tests and 4 infrastructure tests; the full suite was not rerun during this review.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

@thomasluizon

Copy link
Copy Markdown
Owner Author

Copy approval for the feature explanation change in ee8ca29 (/second-opinion, claude-opus-5-5, framed as a claimed copy defect so DISAGREE approves):

  • freezes.md: "Streak freezes are part of Orbit Pro. Some free accounts have them too."
  • gamification.md: "XP, levels, and achievements are part of Orbit Pro. Some free accounts have them too."

Verdict: DISAGREE (high confidence), so the copy is approved. Reasoning: "The new copy accurately states the rule (Pro, or some free accounts via a per-account flag) while removing the internal flag name, which the brand voice forbids; it is short, plain, and unhyped. Astra separately sees the person's profile to answer whether they personally have freezes, so the explanation needn't say how to tell."

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes Reviewed the changes since 6b3d6472, with the full PR diff as context.

  • Replaced internal terminology: Expressed freeze and gamification eligibility in product language while preserving availability for Pro and eligible free accounts.
  • Removed implementation names: Kept numeric freeze, overdue, and streak limits intact while removing constant identifiers and simplifying the overdue heading.
  • Strengthened content checks: Added a guard against internal identifiers in explanation bodies and explicit expected-copy assertions for chat/MCP parity. Focused verification passed 20 application tests and 4 infrastructure tests; the full suite was not rerun.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

@sonarqubecloud

Copy link
Copy Markdown

@thomasluizon
thomasluizon merged commit 45548c5 into redesign/main Oct 19, 2026
22 checks passed
@thomasluizon
thomasluizon deleted the thomasluizon/ticket-236-pro-claims branch October 19, 2026 22:28
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.

1 participant