Rensei docs

Capacity Profiles

The capacity-profile contract: ordered pools, all six ordering policies, burst posture, disconnect reconciliation, and the org-authors/project-consumes grant model.

A capacity profile is the org-authored, project-granted object that declares which pools a project's sessions may land on, in what order, and under what postures. It replaced the per-project execution route (the preferredPoolIds / fallbackPoolIds pair you may remember from earlier versions of this page) in a single clean-break migration: project_execution_routes no longer exists as a table, and every route that referenced it was migrated into a named profile.

This page documents the profile object itself - its fields, its ordering policies, and its grant model. For the six-stage decision that reads a profile at dispatch time, see Placement, Selection & Routing Vocabulary. For the CLI verbs that manage profiles, see Capacity CLI reference. For the pools a profile orders, see Capacity Pools.

The profile object

FieldMeaning
id, orgId, name, descriptionIdentity. name is unique per org.
Ordered pool listThe declared candidate set and its order, stored as one row per (profile, pool, position) in a join table, not an array column - every pool id is foreign-key-validated against the org's pools on write.
orderingPolicyHow stage 4 orders survivors - one of six values, below. Default: declared.
preferenceVectorA cost / latency / quality posture, inherited org to project to node. Any narrower scope may tighten it; none may widen it.
reservationPosture{ mode: "none" | "wait", timeoutMs: number | null } - whether bind may wait for a reserved slot instead of failing immediately. Consumed at bind time (stage 5), never as a sort key.
burstPostureoff | manual | auto_when_entitled - whether the profile may reach capacity it does not name. See Burst posture.
Disconnect reconciliationThree fields - disconnectLostAfterMs, disconnectReplace, disconnectReconcile - covering the "host came back and two copies of the work are alive" case. See Disconnect reconciliation.
isOrgDefaultWhether this is the org's default profile, used when a project has no explicit grant. At most one per org.
revisionMonotonic; stamped into every decision record that resolves against this profile.

A profile has exactly one ordered pool list - there is no second, separately-authored fallback list. The ordered surviving subset of that list is the fallback chain: see the one fallback rule.

All six ordering policies

orderingPolicy selects how stage 4 (ranking) orders the candidates that already survived permission and viability. declared is the default and the only policy the open-source execution layer implements without the platform; the other five are a platform-hosted extension of the same seam.

ValueBehavior
declared (default)Take the survivors in the exact order the profile's author wrote them. Unscored - no cost/latency comparison, no cross-pool tie-break.
ordered_fallbackPreferred pools first, then the remaining eligible pools, in the profile's configured order.
least_loadedThe eligible pool with the most free session capacity.
round_robinRotate across eligible pools on a persisted cursor (the profile's rotationCursor field).
affinityPrefer the pool that most recently ran work for this project.
cost_awarePrefer the cheapest eligible pool by recorded 24-hour pool cost.

An ordering policy may only reorder the surviving candidate set - it can never remove a candidate. A policy that could drop a candidate is a filter mis-declared as an order, and is refused at the contract level. Richer (load-aware) policies also carry a shipping precondition: a pool with no enrolled machines scores as maximally idle under a naive load metric and would rank first, always - so a load-aware policy must correct for that before it ships. declared carries no such precondition, which is part of why it is the default.

Set the ordering policy with rensei capacity profile set --policy <value>; see Capacity CLI reference.

Burst posture

burstPosture decides whether a profile may reach capacity it does not name in its ordered pool list - most concretely, a platform-managed system pool made available by a plan entitlement.

ValueBehavior
off (default)Never bursts, even if the org holds a capacity entitlement. Entitlement alone is not consent.
manualAn operator or author may explicitly name the burst pool as a candidate; the entitlement gate still has to permit it.
auto_when_entitledThe burst pool enters the candidate set automatically once the entitlement resolves. This still shows up on the decision record as a permission event at stage 1 - attributed and explainable, never a silent routing surprise.

Burst is a permission question, not a ranking one: reaching capacity a profile does not name re-enters the composition law at stage 1 as an entitlement grant that widens the candidate set before viability, preference, and ranking run. See the one fallback rule.

What remains undesigned. Everything above is failure-triggered routing-around plus an explicit profile opt-in - there is still no predictive burst. Reaching for more capacity before a dispatch has actually failed would need a usage meter (token/credit budget telemetry) the platform does not currently collect, and no such meter, overflow policy, or exhaustion trigger exists today. Treat any description of pre-emptive or capacity-triggered bursting as a plan, not a shipped behavior.

Disconnect reconciliation

Three flat fields on the profile answer "the host that was running this work disconnected, then came back - now what":

FieldDefaultMeaning
disconnectLostAfterMs300000 (5 minutes)How long a disconnected host's work is held before it is considered lost.
disconnectReplacetrueWhether a replacement is placed once the work is considered lost.
disconnectReconcilebest_scoreWhat happens if the original host reappears after a replacement was already placed - one of keep_original, keep_replacement, best_score, longest_running.

Before this field existed, "the host came back and two copies of the work are alive" was undefined behavior. It is now a declared, per-profile policy rather than an accident of timing.

Org authors, project consumes

Profiles follow the org-provisions / project-consumes model:

  • An org admin authors profiles and grants them to projects. A project can never author a profile, add a pool to one, or widen what it was granted - it can only narrow.
  • A project selects among its granted profiles and may tighten: narrow the pool subset, tighten the preference vector, or pin a specific pool or peer. Tightening is a one-way ratchet, both for a single project and across the org-to-project-to-node inheritance chain generally - any level may restrict what a wider level granted; no level may restore what a wider level removed. This is the same intersection discipline the permission stage of the composition law uses: an allow must exist at every scope for a candidate to survive, so removing a grant at a wide scope has certain effect everywhere beneath it.
  • Grant records are append-only, never overwritten. A grant carries who granted it and, once revoked, who revoked it and when - revocation writes a new state on the same row rather than deleting history. At most one grant per project is marked primary (the project's selected profile) at a time; granting a new primary revokes the previous one in the same transaction.
  • Profile selection, when a project has none, follows a documented cascade: explicit selection, then the project's primary grant, then the org's default profile, then a loud error. A default never bypasses permission or viability, and an explicit invalid selector never silently falls back to a default.

Manage grants with rensei capacity profile grant; see Capacity CLI reference.

Two API surfaces, one object

Two live API surfaces read and write capacity, and they are not the same age:

  • /api/capacity/profiles (and /api/capacity/profiles/{profileId}, /api/capacity/profiles/{profileId}/grants) is the current, org-admin authoring surface for the object documented on this page.
  • /api/projects/{projectId}/capacity-route still exists as a transitional, project-scoped adapter - it now reads and writes through the capacity-profile tables rather than a project_execution_routes row (which no longer exists), but it has not been renamed. rensei capacity profile set writes through this same adapter for its project-scoped, patch-semantic edit path.
  • /api/projects/{projectId}/capacity-profile (and its /select and /effective-candidates children) is the newer project-side read surface: it returns the project's effective profile - the resolved result of its grants - rather than a route record.

If you are integrating directly against the API rather than through the CLI, prefer /api/capacity/profiles for authoring and /api/projects/{projectId}/capacity-profile for reading a project's effective profile; treat capacity-route as the legacy write path it is.

On this page