Skip to content

Report the account's job limit from its entitlement - #55

Merged
irl-dan merged 1 commit into
mainfrom
fix/job-limit-entitlement
Oct 9, 2026
Merged

irl-dan merged 1 commit into
mainfrom
fix/job-limit-entitlement

Conversation

@rawwerks

@rawwerks rawwerks commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

I'm an AI agent (Claude Code) opening this PR on behalf of Ray (@rawwerks). He asked for this fix and approved opening the PR, but he did not write the text below.

Bug

A paid account with unlimited jobs sees prose cli job list print Jobs: 0 of 5 allowed, and prose cli service triage --json report jobs.max: 5.

GET /triggers returns two fields:

  • max_triggers: always the free ceiling (5), kept for older clients.
  • trigger_limit: the account's actual entitlement. It is one of:
    • {"kind":"limited","max":N}
    • {"kind":"unlimited"}
    • {"kind":"unavailable"}, meaning the service could not check the entitlement; it's temporary.

The CLI showed max_triggers. Its job_limit projection also copied a limit key the service never sends, so even a limited account's own max was lost.

Fix

Projection. One projection, shared by job list and service triage, derives the limit:

  • job_limit mirrors trigger_limit as {kind, max?}.
  • An unknown or empty kind reads as unavailable, never guessed.
  • limited without a valid integer max ≥ 0 is SERVICE_PROTOCOL_INVALID, naming job_limit.max.
  • An older service without trigger_limit reads as limited at an integer max_triggers ≥ 0; otherwise it is unavailable. When trigger_limit is present, max_triggers is ignored.

Output.

  • max_jobs (job list) and jobs.max (triage) are the account's max when limited, and null otherwise.
  • Triage gains jobs.limit.
  • The human line reads Jobs: N of M allowed, Jobs: N (unlimited) or Jobs: N (limit unavailable; try again).

Compatibility. job_limit.limit is replaced by job_limit.max, and job_limit.kind is now an enum. max_jobs / jobs.max become null for unlimited accounts. These changes are in the changelog.

job create has no client-side limit wording; a service refusal passes through as before.

Files.

  • Rust service/{jobs,triage}.rs and Bun service/{jobs,triage}.ts, implemented independently, with unit tests in both.
  • Schemas: jobs.schema.json gains $defs.jobLimit, discovery.schema.json gains triage jobs.limit, and the response schema gains trigger_limit.max.
  • Corpus: 8 new cases (limited JSON and human; unavailable; unknown kind; older service; limited without max; triage limited JSON and human). The 10 existing cases whose fixtures say unlimited are refreshed, changing only the limit line. One fixture that used the never-sent limit key now uses max.
  • docs/service/{jobs,discovery}.md and CHANGELOG.md.

Evidence

Local, on macOS with Python 3.10.21 and Rust from rust-toolchain.toml. These gates pass:

  • shared-contracts, service-help, public-surface-files and service-operations-corpus
  • differential-conformance and service-coverage
  • service-operations-rust-build and service-operations-rust: 1097 cases, 0 failures
  • service-operations-bun-build and service-operations-bun: 1097 cases, 0 failures

On the first pass, rust-format, rust-clippy, bun-typecheck, the Rust service tests and the Bun job/discovery tests also passed.

Every new or refreshed case was accepted only where Rust and Bun produced identical bytes. An independent review agent read the diff before this was opened; its required doc fix and nits are applied.

🤖 Generated with Claude Code

GET /triggers keeps max_triggers as the legacy free ceiling and reports
the account's limit in trigger_limit: limited with max, unlimited, or
unavailable. job list and service triage showed max_triggers, so a paid
account read "Jobs: N of 5 allowed", and job_limit copied a key the
service never sends. job_limit now mirrors trigger_limit ({kind, max?});
max_jobs and triage jobs.max are the account's max when limited and null
otherwise; triage gains jobs.limit; the human line says "of M allowed",
"(unlimited)" or "(limit unavailable; try again)". An unknown kind reads
as unavailable, and an older service without trigger_limit reads as
limited at max_triggers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@irl-dan
irl-dan merged commit e31208c into main Oct 9, 2026
15 checks passed
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.

2 participants