How can AI agents agree on a decision without revealing their owners' private limits?
By keeping the limits inside each agent and sending out only answers. In Parley an owner's red lines are code predicates held in a private sheet. For each option the agent sends one masked verdict: acceptable or not, a score, and the word ok or red-line. The coordinator picks among the options every agent accepted, hashes the record, and each owner replays their own sheet locally to confirm no limit was crossed. The coordinator still learns something: accepted scores are public, scores can be shaded, and the yes or no pattern over enough options can pin a numeric limit (see SECURITY.md).
Everything named here is in the source repository. Related: a fair group decision with private limits, red lines for LLM agents, verifying a decision receipt.
Where the boundary is, and what crosses it
- 01
The limit stays on the owner's side.
A red line is a predicate in the owner's own sheet, a function that returns true for an option the owner can live with. The sheet is held by the owner's agent and is never handed to the coordinator or to the other agents.
- 02
Only a verdict crosses the boundary.
For each option an agent answers with one record: acceptable or not, a soft score between 0 and 1, and the word ok or red-line. It never names the rule that failed, and a rejected option reports score 0 instead of the real score.
- 03
The pick is computed over verdicts, not over limits.
The coordinator keeps the options every agent accepted and picks the one whose lowest score is highest, ties broken by total score. If no option is acceptable to everyone, the result is a deadlock. The rule needs no limit, only the verdicts.
One agent, one limit, two options
Bob's agent holds a sheet with one red line, price at most 700, and a soft preference for cheaper. Ask it about a 900 venue and a 500 venue. The first verdict says red-line with score 0; the second says ok with the real score. Neither verdict contains the number 700, and the sheet object never leaves the process that holds it.
sheet = PreferenceSheet("bob",
hard=[HardConstraint("budget", lambda o: o["price"] <= 700)],
utility=lambda o: 1 - o["price"] / 1000)
bob = Agent("bob", sheet)
bob.consider({"id": "venue-a", "price": 900})
# acceptable=False score=0.0 reason="red-line"
bob.consider({"id": "venue-b", "price": 500})
# acceptable=True score=0.5 reason="ok"
result = run_consensus([ana, bob, cara], options)
result.transcript.hash() # SHA-256 over the record
result.transcript.verify_non_betrayal(sheet, result.decision) # True, on Bob's machineWhat the coordinator can still learn
- Accepted scores are public. The soft score of every option an agent accepts is in the record, so the order of its preferences among those options shows.
- The yes or no pattern leaks the feasible region. Over enough options, especially ones that differ in a single number, the acceptable flags narrow down where a numeric red line sits. The rule's name and text are never sent, but its effect is.
- Scores are self-declared. An agent that shades its soft scores can tilt the pick among options acceptable to everyone. Red lines are enforced in code; the scores are not. SECURITY.md lists all three as known limits.
- Unsigned by default. The hash shows the record was not edited, not who wrote each verdict. Ed25519-signed verdicts are an optional extra that binds a key to the exact option and verdict.
Questions this page gets asked
How does an agent reject an option without saying why?
Its sheet evaluates the option against every red line and keeps the list of crossed ones to itself. The verdict that leaves the agent carries acceptable=false, score 0 and the word red-line. The number behind the rule, say a budget of 700, never appears in a verdict.
How can the owner be sure the result respected their limit?
By replaying it. The transcript has verify_non_betrayal(sheet, decision), which runs the owner's own sheet against the decision on the owner's own machine. It returns true when every red line holds, and a deadlock returns true because it forces nothing on anyone. The sheet is read locally and is not sent anywhere.
Can the coordinator learn the limits anyway?
Partly. The scores of accepted options are public, so preference ordering among them shows. The acceptable flags show which options each agent would take, and enough probing options can pin a numeric red line. A party can also shade its soft scores to tilt the pick among acceptable options. SECURITY.md lists these as known limits.
Is the record itself trustworthy?
It is tamper-evident. The transcript hash is a SHA-256 over the canonical JSON of every recorded verdict and the result, so an edit changes the hash, if you hold the hash from outside the coordinator. Anyone can recompute the max-min pick from the recorded verdicts and compare it with the announced one, given a roster of expected owners the checker trusts. Signed verdicts with Ed25519 are an optional extra; without them the hash shows the record was not edited, not who produced it.
Watch a sample decision resolve, then read the code.
The demo replays scripted runs of the same engine, no signup. The repository is Apache-2.0 and the core has no dependencies.