Pools & cross-pooling
What it is
A pool is the smallest part of the org hierarchy that owns people — every employee has a home pool. Cross-pooling lets the allocation engine staff one pool's work with another pool's employees, but only when an admin has created an explicit, dated pool-lending rule that permits it.
Why it exists
Work doesn't always line up with team boundaries: one pool is short, another has spare capacity. Cross-pooling lets a planner borrow across pools without dissolving the org structure — the lending stays controlled, directional, and time-bounded, and every cross-pool decision the engine makes is explainable.
Key concepts & terms
- Pool — a group of workers under a department; an employee's home pool is their primary pool.
- Default pool of a department — the demand for a department is "owned" by its default pool (derived as the lowest-id active pool in that department; it is not a stored flag).
- Pool-lending rule — an admin grant that says "source pool A may lend to target pool B," between two dates, optionally requiring approval.
- Directional — a rule only grants A→B; B→A needs its own separate rule.
- Requires-approval — a flag on a lending rule; in v1 a value of true blocks the lending.
- Cross-pool eligibility rule — the hard rule in the allocation engine that enforces lending at run time.
How it works
There are two halves, joined at the hip: configuration (pools and lending rules) and enforcement (the engine).
An admin manages pools and, in a pool's detail page, the lending rules under the source pool ("Pool A lends to…"). That CRUD surface only stores the grants. The enforcement happens inside an allocation run: when the engine considers an employee from pool A for demand owned by pool B, the cross-pool eligibility hard rule decides:
flowchart TD
E["Candidate from Pool A (home)"] --> Q{"Demand owned by Pool B"}
Q -->|A = B| Same["Same pool → passes (no cross-pool check)"]
Q -->|A ≠ B| L{"Effective A→B lending rule?"}
L -->|no rule / outside its dates| F1["Fails hard — not eligible"]
L -->|rule exists, requires approval| F2["Fails hard — needs approval (no workflow in v1)"]
L -->|rule exists, auto-approved, in window| Pass["Passes — cross-pool eligible"]
This is the most foundational gate in the engine — it runs first (before certification, leave, rest, and so on), so an ineligible cross-pool candidate is rejected fast, with a precise reason. Same-pool candidates skip the check entirely.


Rules & what's enforced
- Lending is directional and dated. A rule grants source→target between an effective-from and an (optional) effective-to; bounds are inclusive. "A lends to B" does not imply "B lends to A."
- No lending rule means no cross-pool allocation. By default an employee can only be used for their own pool's demand.
Requires approval = trueblocks in v1. There is no approval workflow yet, so a rule that requires approval rejects the cross-pool candidate. Onlyrequires approval = falserules actually let someone through. (The flag defaults to true.)Max concurrent borrowsis stored but not enforced — the engine cannot currently cap how many people are borrowed at once.- Deleting a pool is blocked while any active employee still has it as their primary pool.
- Lending-rule identity (source, target) is fixed — to re-target, delete and recreate.
What's live vs planned
- Live (v1): pools and pool-lending rules (full create/edit and web UI), the default-pool-per-department invariant, and runtime enforcement of lending via the cross-pool eligibility hard rule (snapshot-backed, with a matching database fallback).
- Planned / deferred: the per-rule concurrency cap (
max concurrent borrows), the approval workflow that would clear a "requires approval" rule, and a lending-request ledger.
One operational gotcha: if a department is missing its default pool, the cross-pool check passes rather than fails (a deliberate "never reject without a citation" safeguard) — so a missing default pool surfaces as checks silently passing, not as an error.
Related
- Terminals, departments & nodes — where pools sit in the hierarchy.
- Allocation rules — the hard/soft rule framework this gate belongs to.
- Rosters & allocation runs — the run that evaluates cross-pool eligibility.