Roth · Guide contents
Expected Parrot · Roth

Matching that listens
to both sides.

Students have preferences over internships. Employers have preferences over students. Roth collects both, then uses deferred acceptance to turn those preferences into a stable set of assignments.

Use direct rankings from people, or let an LLM rank candidates from their preference descriptions. An optional A-versus-B survey checks how well the model understands what each person wants.

Need to form groups as well? The team-and-project mode jointly chooses student teams and their projects using ranked preferences and integer programming.

For classroom essays or internal proposals, peer-review assignment gives each submission enough reviewers while enforcing workloads and conflicts.

Human surveys through EDSL HumanizeOrganizer-controlled delegationReproducible matching
Students matched with internship openings Three assignments from the saved example: Casey 3 to Data analysis at Fictional Lab 1, Harper 8 to Design at Fictional Lab 4, and Indigo 9 to Software development at Fictional Lab 2. STUDENTS INTERNSHIP OPENINGS Casey 3Harper 8Indigo 9Software developmentData analysisDesign Fictional Lab 2Fictional Lab 1Fictional Lab 4
  • Casey 3→ Data analysis · Fictional Lab 1
  • Harper 8→ Design · Fictional Lab 4
  • Indigo 9→ Software development · Fictional Lab 2
Three of the ten assignments in the bundled example. All participants and preference lists in this example are fictional.

01 · The ideaOne market. Two sets of preferences.

Roth is a Python package and command-line tool for organizing a two-sided matching process—from participant lists to assignments you can inspect and reproduce.

The organizer supplies two lists, the profiles each side will see, and the market's rules. Roth helps collect preferences, records which candidates are acceptable, and computes one-to-one matches. Each internship opening has one place; each student can receive one internship.

  1. Define the marketAdd students, openings, profiles, and eligibility rules.
  2. Collect preferencesAsk people to rank, or score candidates on their behalf.
  3. Freeze and matchClose the active cohort and run deferred acceptance.
  4. Inspect the outcomeRead assignments, preference statistics, and coverage.
Direct preferences

People rank their options.

Students review internship profiles. Employer representatives review students. Personalized Humanize surveys collect rankings and explicit rejections from both sides.

See the human workflow →
Delegated preferences

People describe what matters.

An LLM evaluates candidates using each participant's instructions. The organizer decides whether those rankings can be used directly or require confirmation.

See the delegated workflow →

The two sides can use different collection methods. They still meet at the same matching engine, with a saved record of where each preference came from.

Start a coding agent with the right question

roth agent next

This read-only entry point helps the calling agent identify the scenario before choosing a method. Two distinct sides with one partner each use deferred acceptance. Forming student teams and assigning each team its own project uses joint integer optimization. Many-to-one capacities use the same deferred-acceptance workflow with individual rankings. Reviewer/submission assignment uses coverage and workload optimization. General stable many-to-many matching, roommate matching, and repeated projects require other formulations.

roth --project study agent next --scenario one-to-one
roth --project mentorship agent next --scenario many-to-one
roth --project classroom agent next --scenario teams

In a fresh directory, the response gives questions about rosters, preferences, and organizer rules. With existing files or saved state, it explains the next applicable step and returns exact command arguments. The agent resolves only missing questions, follows the relevant commands within your authorization, and runs the returned data.rerun command after each stage.

The guide distinguishes existing ranking files, human surveys, delegated scoring, required confirmations, and completed reports. Team results are checked against their input hash and independently recomputed scores; changed inputs get a new output directory. Read the agent guidance contract →

02 · The worked exampleA summer internship program

Imagine a university placing students into openings across ten fictional labs. Some students value close mentoring; others care more about the work itself, compensation, or remote arrangements. Employers consider skills, project experience, interests, and availability.

12students
10single-slot openings
10matches in the saved run
What you provideStudent sideInternship side
A public profileSkills, coursework, projects, and availabilityWork, dates, location, compensation, and mentoring
Private preferencesWhat the student wants to learn and which tradeoffs they will makeWhat the employer values in a candidate for this opening
Who respondsThe studentAn employer representative for the opening

A profile describes what someone offers. Preference instructions describe what they seek. Roth keeps those separate, along with contact information and private rankings.

Where do these rankings come from? The example generator shuffles candidate IDs with a fixed random seed (17) and marks some options unacceptable. These are synthetic inputs, independent of the profile descriptions above. No person or LLM produced them. Importing these same lists reproduces the assignments below.

The actual input: two ordered lists

Each participant supplies a list from best to worst, plus explicit unacceptable options. Here are two of the 22 records used in this run. Lab numbers identify distinct single-slot openings.

s001 · Synthetic input

Alex 1 ranks internships

  1. Lab 8 · Policy research
  2. Lab 4 · Design
  3. Lab 1 · Data analysis
  4. Lab 6 · Data analysis
  5. Lab 2 · Software development
  6. Lab 10 · Climate research
  7. Lab 3 · Policy research ← realized match
  8. Lab 5 · Climate research

Would rather remain unmatched than accept: Software development — Fictional Lab 7, Design — Fictional Lab 9.

i003 · Synthetic input

Lab 3 ranks students

  1. Casey 3
  2. Alex 1 ← realized match
  3. Emery 5
  4. Devon 4
  5. Finley 6
  6. Lane 12
  7. Gray 7
  8. Jules 10
  9. Blair 2
  10. Harper 8

Would rather remain unmatched than accept: Kai 11, Indigo 9.

Alex ranks Lab 3 seventh; Lab 3 ranks Alex second. Those two positions become 7 / 2 in the matrix. The lists are the inputs; the highlighted assignment is the computed outcome.

See the exact JSON for these two participants

This excerpt contains two complete records from the full 22-record preference file. IDs refer to participants in market.json.

[
  {
    "participant_id": "s001",
    "ranking": ["i008", "i004", "i001", "i006", "i002", "i010", "i003", "i005"],
    "unacceptable": ["i007", "i009"],
    "evaluated": ["i008", "i004", "i001", "i006", "i002", "i010", "i003", "i005", "i007", "i009"],
    "complete": true,
    "source": "synthetic",
    "confirmed": false
  },
  {
    "participant_id": "i003",
    "ranking": ["s003", "s001", "s005", "s004", "s006", "s012", "s007", "s010", "s002", "s008"],
    "unacceptable": ["s011", "s009"],
    "evaluated": ["s003", "s001", "s005", "s004", "s006", "s012", "s007", "s010", "s002", "s008", "s011", "s009"],
    "complete": true,
    "source": "synthetic",
    "confirmed": false
  }
]

ranking contains acceptable options in order. unacceptable lists explicit rejections. evaluated records which candidates were reviewed; complete marks a finished submission, which can have an empty ranking. The source is labeled synthetic.

All rankings, with realized matches

Read a row to see a student’s preferences across openings. Read a column to see how an employer ranks each student. Each cell is student rank / employer rank; 1 is best on either side.

7 / 2 · MATCH Realized assignment× Unacceptable to that side? Unresolved (none in this example)
All 120 possible pairs from the bundled synthetic preferences. Students propose. Only mutually acceptable pairs can match. Scroll horizontally on a narrow screen; student names stay visible.
Student ↓
Opening →
Lab 1Data analysis Lab 2Software development Lab 3Policy research Lab 4Design Lab 5Climate research Lab 6Data analysis Lab 7Software development Lab 8Policy research Lab 9Design Lab 10Climate research Outcome
Alex 1 3 / 7 5 / 9 7 / 2MATCH 2 / 10 8 / 2 4 / 9 × / 6 1 / 8 × / 6 6 / 9 Lab 3
Blair 2 3 / × 1 / 4 7 / 9 × / 4 6 / 1 2 / × × / 1 5 / 1MATCH 8 / 8 4 / × Lab 8
Casey 3 2 / 1MATCH 4 / × × / 1 × / 6 6 / 9 7 / 2 5 / 10 1 / 7 3 / 3 8 / 5 Lab 1
Devon 4 7 / 2 × / 6 3 / 4 5 / 1 × / 8 2 / 8 8 / 7 1 / 9 6 / 9 4 / 2MATCH Lab 10
Emery 5 8 / × 2 / 10 6 / 3 7 / 5 5 / 3MATCH × / 7 1 / 4 4 / 5 × / × 3 / 6 Lab 5
Finley 6 × / 3 4 / 5 2 / 5 5 / × 7 / × 8 / 6 1 / 3 × / × 3 / 2 6 / 4 Unmatched
Gray 7 7 / 9 1 / 2 6 / 7 × / 8 3 / 5 8 / 5 5 / 2MATCH 4 / 2 × / 7 2 / × Lab 7
Harper 8 4 / 8 6 / 8 7 / 10 1 / 2MATCH × / 6 8 / 3 5 / × 2 / × 3 / × × / 1 Lab 4
Indigo 9 × / 5 2 / 1MATCH 6 / × 4 / 9 1 / 7 × / × 7 / × 5 / 3 8 / 5 3 / 8 Lab 2
Jules 10 × / 6 1 / × 7 / 8 8 / × 3 / × 2 / 1MATCH 6 / 5 × / 4 5 / 10 4 / 3 Lab 6
Kai 11 2 / 10 7 / 3 5 / × 1 / 7 3 / 10 4 / 4 × / 9 × / 10 6 / 1MATCH 8 / 7 Lab 9
Lane 12 × / 4 × / 7 × / 6 × / 3 × / 4 × / 10 × / 8 × / 6 × / 4 × / 10 Unmatched

Why doesn’t Alex get Lab 8, their first choice? Lab 8 ranks Alex eighth and Blair first. The stable outcome assigns Blair to Lab 8 and Alex to Lab 3. A high ranking from one side alone does not secure a match.

Follow Alex’s proposals through this run

Alex approaches Labs 8, 4, 1, 6, 2, 10, and 3 in that order. Labs 8 and 1 initially hold Alex, then replace Alex with applicants they prefer. Labs 4, 6, 2, and 10 reject Alex when approached. Lab 3 holds Alex through the end, producing the 7 / 2 match.

Two students remain unmatched. Finley 6 exhausts their acceptable options during matching. Lane 12 explicitly rejects all ten openings—the × entries across Lane’s row are submitted choices, not missing answers.

This matrix is computed from the downloadable preference file using student-proposing deferred acceptance. The commands below reproduce it without model calls or survey invitations.

03 · The methodWhat makes a match stable?

A blocking pair is a student and an internship that would both prefer to be matched with one another rather than keep their current assignments. A stable matching has no such pair, relative to the preferences and candidates considered.

With students proposing, deferred acceptance works like this:

  1. Students apply in preference order. Each unmatched student approaches their most-preferred opening that has not yet rejected them.
  2. Openings hold their preferred acceptable applicant. An employer can replace a tentative hold with an applicant it ranks higher. Other applicants are rejected.
  3. Rejected students try their next option. The process continues until nobody has another proposal to make. Tentative holds then become final assignments.

Someone can remain unmatched because they ran out of acceptable partners. An opening can also remain empty. Roth never forces a match that either side rejected.

The proposing side matters. In the standard strict one-to-one model, proposers receive their best outcome among stable matchings. The organizer selects that side before fielding; Roth also computes the reverse orientation by default so the difference is visible.

For the economic background, see Alvin Roth's Nobel lecture on market design. Roth supports strict one-to-one and many-to-one rankings with responsive preferences; see the capacity example.

04 · Get startedRun the example locally

From a checkout of this package, install Roth with Python 3.11 or newer. The core demo runs locally and needs no EDSL account.

# From the Roth source directory
python -m pip install -e .

1. Create the market and inspect the input files

roth example create internship-study
roth --project internship-study status

This initializes 22 participants and writes two files. The status still reports completed: 0: the preference file exists, but its rows have not yet been imported.

File in internship-study/What it contains
market.jsonThe 12 students and 10 openings: IDs, profiles, preference descriptions, and organizer rules. View the example market.
preferences.json22 explicit ranking records, one per participant. These are the inputs shown in the matrix above. Download all 22 records.

2. Import the rankings

roth --project internship-study preferences import \
  internship-study/preferences.json
roth --project internship-study status
roth --project internship-study preferences show

The import reads the JSON array, checks participant and candidate IDs, checks for duplicate or contradictory choices, and records each participant's ordered list. It preserves the submitted order. The import reports imported: 22 and unchanged: 0; status now shows completed: 22 and an empty missing list. preferences show prints the active records for inspection.

This step imports explicit rankings from the file. Natural-language descriptions in market.json are only used to infer rankings when you separately run the delegated scoring workflow. With people, the survey response importer produces these preference records instead.

3. Freeze those inputs and compute the assignments

roth --project internship-study preferences freeze --name main
roth --project internship-study match --snapshot main --name main
roth --project internship-study report --run main \
  --output internship-study/report

Freeze records the exact cohort and preference lists used for a run. The matching command runs student-proposing deferred acceptance on that snapshot, producing the ten highlighted assignments in the matrix. Later answers or revisions produce a new snapshot, so you can reproduce the earlier assignments.

Shortcut: run all of these steps together
roth demo internship-demo

This creates a separate project, imports the fictional rankings, freezes them, computes matches, and exports results and survey previews. In the development workspace, the installed executable is .venv/bin/roth.

Bring your own participants

Import a complete market definition, or supply one file per side. Participant IDs must be unique. CSV and JSON side files can include profiles, natural-language preferences, and separate contact information.

roth --project my-study init --left students.csv --right internships.csv
# Or import the full definition, including organizer policies:
roth --project another-study init market.json

EDSL AgentLists are also accepted. The data contract reference describes the fields, policies, and response formats.

05 · Human preferencesAsk both sides to rank

For human participation, install the fielding extra and generate personalized surveys. Each student sees internship profiles; each employer representative sees students for their opening.

python -m pip install -e '.[fielding]'
roth --project internship-study field build --name rankings \
  --output internship-study/rankings

The participant ranks the displayed options alongside Remain unmatched. Candidates placed below that outside option are unacceptable, unless the participant separately marks them as impossible to assess.

Participant responseWhat Roth records
“I would accept this option.”An acceptable candidate in the participant's ranking
“I would rather remain unmatched.”An explicit rejection
“I do not have enough information.”An unresolved candidate, not a rejection
No completed surveyA nonrespondent, not an empty preference list

From preview to email invitation

Review the generated preview.html, then use the commands in handoff.json to create the surveys through EDSL Humanize. Register the returned survey identifiers in Roth. Registration provides the next commands for email invitations, delivery status, and response retrieval.

The organizer supplies real email addresses for recruitment. Roth prepares the survey and recipient mapping; external ep commands publish it and send the invitations. The fictional example contains no deliverable email addresses.

Register a survey and import its answers
# Replace HUMAN_SURVEY_UUID with the identifier returned by Humanize.
roth --project internship-study field register --field rankings \
  --package rankings_s001_1 --uuid HUMAN_SURVEY_UUID

ep humanize responses HUMAN_SURVEY_UUID --output student-results.ep
roth --project internship-study field import student-results.ep \
  --name rankings --edsl
roth --project internship-study field status --name rankings

The importer checks participant identity, question wording, option order, and required answers against the saved survey package. Use --replace for an explicit revised submission; earlier answers remain in the project history.

If replacing the example's already-imported fictional rankings, use a new human-fielding project or explicitly replace those fixtures during import.

Close the cohort deliberately

Final matching requires completed preferences for everyone in the active cohort. At the deadline, the organizer can explicitly exclude nonrespondents from a new snapshot. Roth records that reduced cohort so the result cannot be confused with a run covering every invitee.

Native EDSL package and response round trips have been tested locally. Hosted survey presentation and email delivery still need a live pilot before recruitment.

06 · Delegated preferencesDescribe the tradeoffs. Let the model rank.

Reviewing every possible partner becomes burdensome as a market grows. In delegated mode, participants explain their preferences in natural language and the model evaluates candidate profiles on their behalf.

“I want hands-on data analysis experience and strong mentoring. Remote work would help, but I would consider an on-site role if the learning opportunity were better. Pay matters less to me than the work.”

An employer provides its own instructions for an opening. Roth retrieves promising candidates, scores them against the relevant instructions, and records an explanation and acceptability judgment for each evaluation.

Organizer settingHow preferences become final
DirectPeople supply their rankings.
DelegatedThe organizer permits inferred rankings to be used directly.
Confirmation requiredParticipants must confirm the inferred ranking before it can be used.

The organizer can choose a different policy for each side. Explicit human rankings are preserved when model scores are applied.

Separate evaluation from matching

The model produces preferences first. Deferred acceptance then runs on a fixed ordering. This prevents a candidate's position from changing because the model gave a different answer halfway through matching.

Prepare and apply a scoring run

The canned example enables delegation and includes preference descriptions. YOUR_MODEL is a placeholder for the model selected by the organizer.

roth example create delegated-study
roth --project delegated-study score plan --name baseline \
  --model YOUR_MODEL --k 4 --budget 200 --output delegated-study/baseline

# Inspect the plan and cost; execute the generated EDSL handoff.
roth --project delegated-study score import delegated-study/results.ep \
  --name baseline --edsl
roth --project delegated-study score apply --name baseline

Run the optional benchmark before applying final scores if you want to incorporate its answers. The complete delegation walkthrough includes that sequence, score retries, confirmation, and an offline path using clearly labeled synthetic answers.

07 · Optional preference checkWould the model choose what you would?

A plausible explanation does not establish that the model understood someone's preferences. Roth can generate a short A-versus-B survey and compare the participant's choices with predictions saved in advance.

An illustrative student question

Which internship would you prefer?

Option A

More mentoring

  • Data analysis · remote
  • Daily guidance from a mentor
  • $22 per hour
Option B

Higher compensation

  • Data analysis · remote
  • Weekly guidance from a mentor
  • $28 per hour
Strongly
prefer A
Somewhat
prefer A
IndifferentSomewhat
prefer B
Strongly
prefer B

The survey also asks whether each option is acceptable at all, allows “Insufficient information,” and provides space to explain the tradeoff.

Illustrative profiles to explain the question format. Actual benchmark questions use candidates from the participant's scored pool. This diagram is not a live survey or a model result.

Questions combine representative pairs with revealing comparisons, such as options the model scores similarly. The displayed A/B order is randomized, and participants do not see the model's prediction while answering.

Calibration questions

The model can use these answers and explanations to refine its interpretation of the participant's preferences.

Held-out questions

Predictions are frozen before these answers are imported. Their agreement measures how well the model predicted choices it had not seen.

The organizer can treat the benchmark as advisory or require a minimum level of agreement before using delegated preferences. Reports show answer counts, disagreements, ties, and acceptability errors for each participant, with targeted and representative questions kept separate.

Refining and evaluating are different steps. Answers used to improve the model cannot also serve as fresh evidence of its accuracy. Once held-out answers are revealed, another prediction round needs a new benchmark.

Explicit human choices also constrain the final inferred ranking. Preferring A to B does not make either acceptable: a participant can reject both. Conflicting comparisons are flagged for clarification.

08 · When there are too many optionsBudget attention as well as model calls

For people: screen, then rank across batches

The default direct-ranking budget is 15 candidates. For larger lists, generate manageable screening batches, collect acceptability judgments, then ask for a single ranking across the accepted candidates. Separate batch rankings alone would leave their relative order unresolved.

roth --project internship-study field build --kind screening \
  --name screening --batch-size 10 --output internship-study/screening
# Import the screening responses, then build the final ranking.
roth --project internship-study field build --name final-ranking \
  --output internship-study/final-ranking

If too many acceptable candidates remain, the organizer can raise the ranking budget explicitly or field a retrieved shortlist. Follow-up rounds can expand the candidates considered.

For models: retrieve, score, and expand

Roth's initial retrieval method matches words in preference descriptions to candidate profiles. It retrieves from both directions and combines the proposed pairs. When both sides delegate, each retained pair receives two evaluations: how the student values the opening, and how the employer values the student.

Matching instructions, profiles, model settings, and calibration evidence allow a previous score to be reused. Expansion adds candidates while retaining earlier work. Sampling omitted candidates provides an additional check on what retrieval may have missed.

Synthetic scale example · 200 students × 150 openings
Evaluate every pair in both directions60,000
Initial shortlists · k = 53,290
Expanded shortlists · k = 106,044 total
Counts are directional candidate evaluations, not API requests. Expansion reused all 3,290 earlier scores and added 2,754 evaluations. Both shortlist runs filled 150 openings. These are local synthetic results, not measurements of LLM quality or latency.

Shortlist stability has a boundary. These two runs were stable within their evaluated graphs. When checked against the full fictional preference lists, they still had 3,121 and 1,596 blocking pairs, respectively. Expanding a shortlist can help, but it does not certify that every desirable pair has been found.

Roth reports that boundary with each result: which participants were active, which candidates were considered, and whether the preferences were human, delegated, or synthetic.

09 · InterpretationLook beyond the number of matches

A useful outcome explains who matched, who did not, and how the assignments relate to each side's preferences. Here is a compact reading of the complete 12-student example:

MeasureStudentsInternship openings
Matched10 of 1210 of 10
Assigned their first choice1 of 125 of 10
Assigned a top-three choice4 of 1210 of 10
Mean assigned-partner rank, among matched participants3.91.6
Students propose in this run. Preference lists are fictional and cover all eligible candidates; there are no blocking pairs under those lists. Top-choice rates include unmatched participants in their denominators.

These statistics describe different things. Filling every opening does not mean every student received a highly ranked internship. Comparing the reverse proposing orientation helps reveal how the mechanism affects the allocation.

Understand preferences

Inspect concentrated first-choice demand, mutual top-three interest, ranking agreement on shared candidates, and how often each candidate was evaluated.

Understand coverage

Check response rates, unresolved candidates, excluded nonrespondents, and the scope of the blocking-pair verification.

Ranks are ordinal. A first-to-second-choice difference does not have a common value across people, and an LLM score is not automatically comparable across participants. Roth does not present these numbers as a measure of total welfare.

Keep the outcome reproducible

Each run retains its preference snapshot, proposing side, assignments, and proposal trace. Local history under .roth/ preserves earlier revisions. Exports include an organizer report, match and preference files, and individual summaries that reveal only the assigned partner's public profile.

10 · A different assignment problemForm teams and assign their projects together

Students care about both the project and the people they will work with. Roth can take both sets of rankings and solve the team formation and project assignment jointly.

The organizer sets a target team size, whether smaller or larger teams are allowed, and the weight on teammate preferences. Each student joins one team. Each used project hosts one team. The solver first minimizes deviation from the target size, then maximizes the total weighted Borda score.

This mode uses integer optimization. It returns a feasible assignment and states whether optimality was proved. It makes no stability or strategy-proofness guarantee. The one-to-one deferred-acceptance workflow above remains available separately.

Start with the actual ranking files

python -m pip install -e '.[teams]'
roth teams example classroom
roth teams validate classroom/market.json \
  --preferences classroom/preferences.json
roth teams solve classroom/market.json \
  --preferences classroom/preferences.json \
  --output classroom/report --time-limit 60

teams example writes inputs without solving. The market file defines 12 students, five projects, a target size of three, and allowed sizes of two through four. The preference file contains each student's project and teammate rankings, plus explicit exclusions. All rankings in this example are hand-built fictional inputs.

For five projects, first through fifth place earns 4, 3, 2, 1, and 0 Borda points. For eleven potential teammates, first place earns 10 points. Unlisted options earn zero, but remain distinguishable from exclusions. The category scores are normalized using the full option counts and target team size before applying the organizer's weight.

A concrete outcome, including its compromises

With equal project and teammate weights, the optimum forms four teams of three. Alex, Blair, and Casey work on the campus climate dashboard; Devon, Emery, and Finley study housing; Gray, Harper, and Indigo work on transport; Jules, Kai, and Lane tackle food waste. The library project is unused.

Casey receives an unranked project. Climate earns Casey zero project points, but their team includes both top-ranked teammates. That is an allowed outcome under this aggregate objective, and the report makes it visible. An explicit project exclusion would prohibit the assignment.

What changes when we change the weight?

Weight on teammatesFirst-choice projectAt least one ranked teammateUnranked project
0% · projects only10 / 125 / 120 / 12
25%7 / 1210 / 120 / 12
50% · equal weights4 / 1212 / 121 / 12

These are actual solved variants of the same synthetic inputs, each with four teams of three. The table describes the saved optima; tied solutions can have different individual assignments. Inspect the runs, or reproduce them with python scripts/team_sensitivity.py --output new-sensitivity.json.

This mode uses file inputs and frozen report directories, independently of the stable-matching project store. SciPy/HiGHS is an optional local solver dependency. Humanize assessment and ranking surveys are available through teams field. Skill constraints and repeated projects remain future extensions.

11 · Several partners, one rankingEmployees and mentors

Many mentors can work with more than one employee. Keep one mentor ID and one ranking, and give that mentor a capacity. Roth assigns each employee at most one mentor and each mentor up to their capacity. Either side may propose.

Example inputsRule
30 fictional employeesAt most one mentor each
10 fictional mentorsAt most three employees each
Two sets of explicit rankingsAll candidates acceptable in this fixture; shared topics ranked first

The preferences are supplied explicitly. Inspect the roster and capacities and each person's ranked list, then import them before matching:

roth example mentorship mentorship-demo
roth --project mentorship-demo preferences import mentorship-demo/preferences.json
roth --project mentorship-demo preferences freeze --name main
roth --project mentorship-demo match --snapshot main --name main
roth --project mentorship-demo report --run main --output mentorship-demo/report

The fixture fills all 30 slots. Open the worked report to see every assigned mentee, mentor capacity utilization, and the matrix of both sides' rankings with matches marked. The JSON output records vacancies separately from people with no assignment.

Rank individuals, including fallback choices. A mentor with three slots can rank all 30 candidates. They prefer any acceptable person to leaving a slot empty, and their preference between two people must not depend on who else they receive. Requirements such as “these two together” or “at least two or none” need another formulation.

Capacity defaults to one, accepts zero for a closed position, and can exceed one on at most one side. It is an upper bound; unmatched people and vacant slots are allowed. The algorithm retains the best acceptable proposals up to capacity and replaces a lower-ranked incumbent when a better proposal arrives. The verifier checks both capacity violations and blocking pairs.

Human surveys, model delegation, and confirmation use the same workflow. With 30 candidates per mentor, start human elicitation with screening before a cross-batch ranking. roth --project mentorship-demo agent next --collection human provides guidance. This example's synthetic rankings bypass human fielding explicitly.

For more detail, see the many-to-one guide and Python API. The standard vacancy and replacement rule is illustrated in NRMP's matching explanation.

12 · Reviews with coverageWho reviews whose work?

A class has 12 individually authored essays. Each student should review three essays, and each essay should receive three reviews. Students cannot review their own work or an essay by a member of their existing team. Roth enforces those rules and chooses assignments using reviewer preferences.

RuleWorked example
Reviewer workloadExactly three essays per student
Submission coverageExactly three distinct reviewers per essay
Hard exclusionsSelf-review, teammate review, an organizer conflict, and an unacceptable option
ObjectiveMaximize normalized Borda points from the submitted rankings

There are two explicit files: reviewers, authorship, teams, and rules, and completed preference records. This is Student 1's actual record in the fictional fixture:

{
  "reviewer_id": "s01",
  "ranking": [
    "p05",
    "p09",
    "p12",
    "p08",
    "p10",
    "p06",
    "p07",
    "p11"
  ],
  "unacceptable": [],
  "complete": true,
  "source": "synthetic"
}

The solver reads that preference file through --preferences. The example does not infer preferences or send surveys:

python -m pip install -e '.[reviews]'
roth reviews example classroom-reviews
roth reviews validate classroom-reviews/market.json --preferences classroom-reviews/preferences.json
roth reviews solve classroom-reviews/market.json --preferences classroom-reviews/preferences.json --output classroom-reviews/report

The installation command is for a checkout. The optional reviews extra uses SciPy/HiGHS, the same solver dependency as team assignment.

Open the worked report and assignment matrix: it contains 36 reviews, every requested count is met, and 29 assignments are in the reviewer's top three. Each matrix row shows a student's rankings; columns show essays; green checkmarks show realized assignments. Forbidden edges are marked ×.

Counts and conflicts are hard constraints. Unranked eligible options score zero and may be assigned, while explicit conflicts cannot be assigned. A missing preference record is incomplete input. If the rules cannot all be met, Roth reports infeasibility and leaves the decision about revisions to the organizer.

Organizers can set different workload bounds and review counts, use explicit 0–100 expertise scores, or deliberately request a feasible allocation without a preference objective. Wider workload bounds allow unequal loads. A time-limited feasible result is labeled separately from a proven optimum.

This mode uses file inputs, immutable report directories, and an independent assignment verifier. It makes no stability or strategy-proofness claim. Humanize assessment, ranking, and expertise surveys are available through reviews field; delegated review scoring remains future work. roth --project classroom-reviews agent next guides the calling agent through inputs, solving, and result review. See the full data contract and formulation.

Collect human team and review preferences

Start from the market roster and a private contact map. Roth builds personalized Humanize packages, tracks returned responses, and exports the completed preferences into the existing solver workflow. The agent can lead the process:

roth --project classroom agent next --scenario teams --collection human --contacts contacts.json
roth --project classroom-reviews agent next --scenario reviews --collection human --contacts contacts.json

First, respondents assess options in manageable batches: select for ranking, state no preference/insufficient information, or declare a hard exclusion. Then they rank the selected options across batches. Review expertise surveys instead use 0–100 ratings in increments of 10. Missing responses block export; revising assessments invalidates old rankings.

No preference is not an exclusion. These optimization modes may assign unranked or unscored eligible options at zero preference score. A hard exclusion forbids the assignment. The survey explains this distinction and the export preserves it.

The offline synthetic pilot exercised native EDSL survey/Results round trips for all 84 packages: 60 for team preferences and 24 for peer review. Both resulting optimizations reached proven optima. No real participants were recruited, no invitations were sent, and no model inference was run. A real cohort pilot remains pending.

Inspect the team assessment preview, review assessment preview, and complete collection workflow. Publication and delivery use explicit, reviewable ep humanize handoffs. Collection files contain private contacts and individual answers.

Compare organizer what-if scenarios

Use a saved matching, team, or review report as the baseline. Change capacities, team sizes, available projects, or review workloads and inspect who receives different assignments and whose preference outcomes rise or fall.

roth compare classroom/report --scenarios scenarios.json --output classroom/comparison

For the classroom team example, a scenario file can contain:

[
  {"name": "allow-four", "config": {"allow_larger": true, "max_size": 4}},
  {"name": "close-climate", "close_projects": ["climate"]},
  {"name": "project-priority", "config": {"social_weight": 0.25}}
]

Every scenario branches from the same original run. The static report shows a before/after assignment matrix, teammate changes, original ranks, individual score changes, workloads, and solver statuses. Frozen preferences and the baseline scoring scale make the comparison interpretable. Closing a project preserves its original rank; a larger review workload is labeled separately from a preference gain.

Allowing teams of four does not require them: the solver still prioritizes the organizer's target size. Equal-score optima may change assignments even when a rule change does not require it. Scores describe the allocation objective, not measured welfare.

Inspect the synthetic comparison report · Inputs, commands, and interpretation

13 · At your deskThe workflow reference

Start with roth agent next to identify the scenario and current stage. Use roth guide for the full workflow. The CLI returns structured output for an assistant; this guide explains the decisions behind those commands.

You want to…Start here
Create the mentorship exampleroth example mentorship mentorship-demo
Run the local exampleroth demo internship-demo
Identify the scenario and next steproth agent next
Inspect a project's progressroth --project study next
Build personalized surveysroth --project study field build --help
Plan delegated evaluationsroth --project study score plan --help
Check preference predictionsroth --project study benchmark build --help
Freeze the active preferencesroth --project study preferences freeze --name main
Compute assignmentsroth --project study match --snapshot main --name main
Verify a saved projectroth --project study validate
Assign peer reviewsroth reviews solve --help
Form teams and assign projectsroth teams solve --help

For exact input schemas and the full fielding sequence, continue with the data contracts and delegation and benchmark walkthrough.

This page describes Roth 0.6.0. Stable matching, joint team optimization, peer-review assignment, and the shared one-to-one/many-to-one survey workflow are implemented. Real recruitment and real-model preference quality require a pilot in the intended market.