How can a group of evaluators, each with their own opinions, decide how to allocate a pool of money? The S-Process — short for simulation process — is a deterministic algorithm that turns each evaluator's preferences into a fair final allocation.
Imagine two evaluators, A and B, each with a budget of $500k to allocate between proposals P and Q. Both evaluators really want to support P, so P is initially the highest priority for both evaluators. But P is just one guy with a fixed budget, whose work can't be easily scaled up, so it only makes sense to allocate $250k to it. Q is clearly a lower priority initially, but it can absorb much more funding, so both evaluators agree that it should receive the rest of the funding after P has received $250k.
Three ways this could play out:
| P | Q | |
|---|---|---|
| A | ||
| B |
By the way, this type of problem occurs in many more contexts. It could be deciding among a group of roommates how a shared budget should be used, or a tech company deciding how computing resources should be allocated among projects. In general, it could be any problem where multiple evaluators need to decide how fungible resources are allocated (with the additional modeling assumption that the things being funded have decreasing marginal utility, that is, they become less and less worthwhile as you continue funding them).
One way for A and B to express their preferences is with a tranche table. Each row (tranche) says how the next slice of the shared budget should be spent, in priority order. In our example, both evaluators have the same preferences, so they both write the same tranche table:
| Tranche | P | Q |
|---|---|---|
| 1 | $250k | — |
| 2 | — | $750k |
This says that the first $250k should flow to P, and then the rest (up to $750k) should flow to Q. Note that even though A and B each only have a budget of $500k, they both write tranche tables saying what should be done up to the entire shared budget of $1m. This function from budget to allocation is called a unilateral allocation function (UAF).
A tranche table can also be converted to a set of marginal value functions (MVFs), one function per proposal, visualized below. To spend a budget, sweep a horizontal line down from the top (always spending dollars on the most valuable proposals available) until you've spent the budget. Drag the sweep line yourself:
| 1 | P $250k |
| 2 | Q $750k |
In the case above, where A and B agree exactly on what should be done with the first $250k, they'll evenly split paying for it: each will contribute $125k. After that they again exactly agree on what should be done with the remaining $750k of their shared budget and will again split it evenly.
Now, even though A and B each only directed $125k to P, the first priority for each was to ensure that P would receive at least $250k (before the first dollar went to Q). Hence the concept of endorsement levels: how much each evaluator ensured that each proposal would receive, whether they were paying for it or someone else was. The amount actually deducted from an evaluator's budget is their contribution.
Since we have two evaluators, each endorsed dollar might only "cost" ½ of that, if both evaluators agree on how it should be spent (in general, endorsement levels can be up to n times contributions, if there are n evaluators). We can create an endorsement-levels table, and compare it to the contributions table:
| P | Q | |
|---|---|---|
| A | $250k | $750k |
| B | $250k | $750k |
| P | Q | |
|---|---|---|
| A | $125k | $375k |
| B | $125k | $375k |
Contributions are always less than or equal to endorsement levels. In this case, A and B both endorsed P at $250k, but they were able to split the contribution evenly.
Recall how the unilateral allocation function was phrased in terms of endorsement levels rather than contributions. This means that at each step of the process the "evaluator" (represented in the algorithm as a tranche table) looks at the level of funding each proposal is currently receiving (from all evaluators), then adjusts their spending so that proposals which are under-funded (according to their UAF) receive more.
When several evaluators endorse the same dollar, who pays how much of it? The rule is: in proportion to their budgets. In the case above, both evaluators have the same budget, so they have equal accountability for any dollar they both endorse, but if Alice had a budget twice that of Bob’s, she’d be accountable for ⅔ of each shared dollar.
Why split proportionally rather than evenly? The problem with splitting each dollar evenly is that the preferences of the evaluator with less funding get washed out: if A's budget is $100k but B's budget is $900k, the result will look exactly like B's preference. In contrast, when sharing proportionally to total budget, the smaller evaluator can have an effect.
It's easy to compute contributions from endorsement levels: for each dollar that multiple evaluators endorse, we split the contribution for that dollar in proportion to their budgets. We just need to find the contribution level for each evaluator that won't put them over budget.
Knowing that, we can let each evaluator endorse a safe amount, for which we know their contribution will be less than (or equal to) their budget. Initially the safe amount is just their budget, but once we've let each evaluator endorse that amount, we see how much they were actually "charged". If they endorsed $1,000 but were only charged $750, we know it's safe to let them endorse $1,250 next time, since only in the worst case will they be liable for all of the additional $250.
So the algorithm iteratively increases each evaluator's endorsement level by the maximum safe amount, converging on the endorsement levels which cause them all to spend their whole budget. You might imagine this as a kind of simulation: we simulate what each evaluator would do with a larger budget than they're actually in charge of, then charge them only for the part of it they're responsible for.
The playground below runs a real implementation. Pick a preset scenario or edit anything by hand — tranche entries are the marginal dollars each tranche adds, in $k — then scrub through epochs to watch it converge. Below the tables, the endorsement towers — the same view the production app draws — show what the numbers mean: how each proposal's funding is built up from bands of jointly endorsed money.
Read a tower bottom-up. Its height is the highest amount anyone endorsed the proposal for — which is exactly what it receives. Each horizontal band is a layer of money, sliced among the evaluators who endorsed at least that high, with slice widths proportional to their budgets. Hover a slice or a legend entry to isolate one evaluator; scrub the epoch slider and watch the towers grow.
Stepping back, everything the algorithm does follows from two rules we've already seen:
1. Fund projects by tranche —
start with what evaluators estimate as the highest
utility per dollar, and continue spending dollars with
less utility, but always the highest utility available
at that point (the sweep from §2).
2. Proportional contributions
— when multiple evaluators help fund the same dollar,
they should each direct the same proportion of their
total spending to that dollar (§3).
The surprise is that these two rules pin the allocation down completely: any procedure that follows them — however it's implemented — must output the same result as the S-Process. The algorithm above is just one way of finding it.
To see why, notice that the rules eliminate every choice except one number per evaluator. By rule 1, an evaluator's behavior is completely described by how far down they sweep their MVF: they endorse every dollar above the line and nothing below it. By rule 2, once we know everyone's sweep depth there is no choice left about who pays for what — each dollar's cost is split, in proportion to budgets, among exactly the evaluators whose sweeps reach it.
That leaves only the depths themselves, and those are forced by the requirement that each evaluator spends exactly their budget. Sweeping deeper only ever increases what an evaluator is charged — they pick up shares of new dollars while their shares of old ones are unchanged. So, given what everyone else does, there is exactly one depth at which an evaluator's charge comes out to exactly their budget — and exactly one profile of depths that works for everyone at once. That profile is the fixed point the algorithm converges to from below: you can watch it in the playground, where endorsement levels only ever ratchet upward across epochs while the remaining-budget curve falls to zero.
Imagine we have these two tranche tables, again for evaluators A and B:
| Tranche | P | Q | R |
|---|---|---|---|
| 1 | 500 | — | — |
| 2 | 500 | — | 500 |
| Tranche | P | Q | R |
|---|---|---|---|
| 1 | — | 500 | — |
| 2 | — | 500 | 500 |
We run into the problem that we haven't defined how to average recommendations. (It may seem obvious in this case because both tranche tables distribute the same amount in both their first and second rows, but we need to say how to average in general.)
The way the S-Process approaches averaging is via the conversion of tranche tables to marginal value functions — the curves from §2 — visualized below. As before, read each graph from top to bottom: a horizontal line sweeps down, funding the proposals with the highest marginal utility first.
To calculate the average MVF, shown below, we sample from both MVFs at each significant point ($0, $500k, and $1m), averaging the result. Because A assigns Q no utility and B assigns P none, both are dragged down — while R, which both endorse, stays in place.
Finally, we convert back to tranche representation:
| Averaged tranche | P | Q | R |
|---|---|---|---|
| 1 | — | — | 500 |
| 2 | 1000 | 1000 | — |
As you can see, R gets all $500 before P or Q gets any money! In general, averaging is good for proposals which a lot of evaluators like at least a little, which can cost proposals which fewer evaluators like a lot!
We think it's worth funding both proposals that one evaluator considers very valuable, and proposals which many evaluators think are somewhat valuable. We use a mean evaluator which takes the average of all the human evaluators' evaluations, but we then use the S-Process to send money through all of the evaluators. This way proposals with less enthusiastic broad support and proposals with strong polarized support can both receive some funding.
I think this is a good suggestion for many projects! One big issue that the S-Process avoids is when one evaluator is in a position of power, they may be able to railroad the other evaluators and have too much influence on the final allocation.
Another issue with just talking it out is that you may never come to a complete consensus. The S-Process provides a principled way to resolve such conflicts.
Another reason is that your evaluators might not all be humans. One thing you might do is to create fake "evaluators" which represent different ways of thinking about what to fund. Two examples from the 2025 Survival and Flourishing Fund (SFF) funding round:
1. One evaluator wrote a program to
group together different types of projects, each of
which they find valuable in different ways, and run an
instance of the S-Process on each of these groups. You
can also do this with a deeper hierarchy, running the
S-Process at each level. The end result was a tranche
table he could then feed into the S-Process app.
2. In the 2025 round, we wanted to
automatically give a bonus to proposals which have a
matching pledge (for every $1 SFF gives to them, they'll
receive some amount of money from other donors). We
created a set of
matching evaluators by taking
the tranche tables of regular evaluators and adjusting
them to account for the extra value some dollars provide
due to matching. We then ran an S-Process, where both
regular evaluators and matching evaluators both receive
some budget.
Finally, the S-Process is a deterministic algorithm (with a correct answer), so it's a nice reproducible way of recording why each proposal received what it did. You record each evaluator's tranche tables and can always re-run the algorithm to verify that every proposal received what they should have. Compare to deciding by consensus, where you may not have written down all of the reasoning which contributed to the final decision.
I primarily care how much I'm sending to each proposal (i.e. my contribution), so is there any reason to care about endorsement levels?
In fact, I recommend focusing on endorsement levels for two reasons:
1. Because they correspond to what is
actually happening in the algorithm: the simulated
evaluator going down your tranche list (or MVF graph if
you prefer) is endorsing funding.
2. Endorsement levels are in your
control, but contributions are not. The tranche list is
your way of saying, for any budget, how you would spend
it (in terms of endorsement levels). But contributions
depend on both the endorsement levels and also all of
the other evaluators.