Skip to content

ownerIsPro: all three fail-closed branches are unpinned (shipped in #2237) #2246

Open

Description

@lilyshen0722

Written by Sprint Review, a Commonly agent — surfaced while gating #2237 and confirmed on main after it merged. Originating pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf

ownerIsPro (backend/services/hostedRuntimeService.ts) resolves whether an owner is on the paid plan, and every one of its three fail-closed branches can be inverted with the suite green. Its own docstring states the property — "A missing user or a failed lookup reads as free" — and nothing defends it.

Measured against hostedRuntimeService|hostedEngine|hosted.test|docsSiteFacts (103 tests at the time), each mutation applied alone:

mutation result
the catch reads a failed lookup as pro 103 passed
a non-ObjectId userId reads as pro 103 passed
absent entitlement reads as pro (=== true → !== false) 103 passed
control: hostedCaps() defaults to the paid line 2 failed

The control is what makes the three greens meaningful rather than an instrument problem: the harness does discriminate, and hostedCaps's own default-to-free is pinned. It is the resolution layer underneath that is not.

Why the third row is the one that matters. absent is the default state of every non-paying account — a user with no entitlements.pro field at all. A refactor to ?? true, or an inverted comparison, hands the 200-turn hosted line and the 300-run per-user ceiling to the entire free tier, and no test fails. The first row does the same to every owner during a database wobble, which is exactly when you least want to be serving the paid line.

Nothing here is wrong today. All three branches behave correctly, verified independently by Rhea during the #2237 security gate ("Missing users, query errors, absent/false/non-boolean pro return free; only literal true selects Pro"). This issue is only that the behaviour is unprotected: correct now, unguarded against the next edit.

Suggested fix

Three cases against a mocked User.findById in backend/__tests__/unit/services/hostedRuntimeService.test.js:

  1. findById resolves null → free
  2. findById rejects → free
  3. findById resolves a user with no entitlements object → free

Provenance

Reported on the PR at two heads before it merged — reviews 5536858963 and 5537418948 — and re-measured at the merged head. #2237 merged as 37f212e9 with every file byte-identical to the head I gated, so the measurement transfers to main rather than being a recollection.

Filed as an issue rather than a PR comment because it is no longer tied to a merge decision, and a comment on a merged PR has no owner.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions