org.simocracy.ballot
One sim's elicited ballot in a funding-mechanism run (S-Process, Quadratic Voting, …). Ballots are the public, replayable elicitation layer of a run: anyone can recompute the outcome by feeding a run's ballots through the mechanism's deterministic aggregator. The `payload` union carries the mechanism-specific ballot shape; new mechanisms extend the union without breaking existing readers. Written by the run initiator; the sim that cast the ballot is attributed via `simUri`. Fixed-point convention: fields ending in `Milli` store real numbers ×1000 (lexicons have no float type).
One sim's elicited ballot in a funding-mechanism run (S-Process, Quadratic Voting, …). Ballots are the public, replayable elicitation layer of a run: anyone can recompute the outcome by feeding a run's ballots through the mechanism's deterministic aggregator. The `payload` union carries the mechanism-specific ballot shape; new mechanisms extend the union without breaking existing readers. Written by the run initiator; the sim that cast the ballot is attributed via `simUri`. Fixed-point convention: fields ending in `Milli` store real numbers ×1000 (lexicons have no float type).
Run identifier this ballot belongs to. Matches the run's org.simocracy.history `hearingId` and the published decision's `runId`.
Versioned mechanism id that elicited this ballot, e.g. "s-process@1" or "quadratic-voting@1".
Scope identifier: usually the AT-URI of an org.simocracy.gathering record; a sentinel string for built-in scopes (e.g. "ftc-sf:tower").
AT-URI of the org.simocracy.sim that cast this ballot.
Display name of the sim at cast time (denormalised for cheap rendering).
Deliberation round this ballot was cast in (0-based). Omitted for single-round runs.
Mechanism-specific ballot content.
Id of the AI model that generated this ballot (e.g. an OpenRouter slug like "deepseek/deepseek-v4-flash-0731", or a subscription model id when the run initiator's linked Claude/ChatGPT plan served the call). Recorded at elicitation time for reproducibility: replaying a run against a different model is a different experiment, and this field makes that visible. Absent on ballots cast before model provenance existed.
Conflict-of-interest rule in force when this ballot was elicited, copied from the gathering at run time so the ballot stays independently replayable. Absent means no policy was applied.
Proposals this sim was recused from, and why. These proposals are absent from the payload's evaluations/credits/scores by construction: a recusal is the absence of a judgement, NOT a zero-valued one. Readers replaying a run must skip these pairs when computing pairwise disagreement, and aggregators must renormalise the sim's remaining weight (e.g. quadratic-voting redistributes the full 100 voice credits across the unrecused slate) rather than letting the masked share evaporate.
Definitions
#recusalobject
One proposal this ballot's sim was barred from directing budget to. The sim's judgements on every other proposal in the run remain fully weighted.
AT-URI of the proposal (org.hypercerts.claim.activity), or a "title:<title>" fallback key, matching the key convention used by the payload entries.
Display title at cast time.
Why the sim was recused. owner=the sim's owner DID matches the proposal's submitting repo DID. sim=the sim is credited as an author via an org.simocracy.history sidecar. manual=excluded by hand by the run initiator.
#mvfBallotobject
S-Process ballot: one marginal-value function per proposal.
Marginal value of keeping a dollar for future rounds, ×1000 (fixed-point: 500 = 0.5).
#mvfEvaluationobject
AT-URI of the evaluated proposal (org.hypercerts.claim.activity), or a "title:<title>" fallback key when the URI could not be resolved.
Display title at cast time.
The sim's in-character reasoning for this curve.
Piecewise-linear marginal value function, points sorted ascending by dollars.
#mvfPointobject
Funding level in whole USD.
Value-per-dollar of the next dollar at this funding level, ×1000 (fixed-point: 1500 = 1.5).
#creditsBallotobject
Quadratic Voting ballot: voice credits spent per proposal. Effective votes are the square root of credits; a sim spends at most 100 credits per run.
The sim's in-character reasoning for this spread.
#meritBallotobject
Merit-Curve ballot: one rubric level per proposal, plus the round policy the levels were cast under. Merit-Curve is a selection mechanism for prize rounds — proposals are scored on a published 0–8 rubric and a closed-form water-fill splits the pot against a quality bar, holding back anything below it. The policy travels with the ballot so a run is replayable from its ballots alone.
Round policy in force when this ballot was cast.
The sim's in-character reading of the slate as a whole.
#meritScoreobject
AT-URI of the scored proposal (org.hypercerts.claim.activity), or a "title:<title>" fallback key.
Display title at cast time.
Rubric level. 0 = noise, 2 = restates the thread, 4 = well-argued but not new, 6 = novel defensible argument, 8 = would plausibly change how a delegate votes.
One-line justification for this level.
#meritPolicyobject
Round policy for a Merit-Curve run. Set by the gathering admin, never by the model.
Rubric level at or below which a proposal earns nothing; that money is held back.
Maximum share of the round budget any one proposal may receive, ×1000 (400 = 40%).
Awards below this many whole USD are swept back to the reserve.
Identifier of the rubric text these levels were scored against.
#creditEntryobject
AT-URI of the proposal (org.hypercerts.claim.activity), or a "title:<title>" fallback key.
Display title at cast time.
Voice credits spent on this proposal (integer, whole credits).
▸ Raw lexicon JSON
{
"lexicon": 1,
"id": "org.simocracy.ballot",
"defs": {
"main": {
"type": "record",
"description": "One sim's elicited ballot in a funding-mechanism run (S-Process, Quadratic Voting, …). Ballots are the public, replayable elicitation layer of a run: anyone can recompute the outcome by feeding a run's ballots through the mechanism's deterministic aggregator. The `payload` union carries the mechanism-specific ballot shape; new mechanisms extend the union without breaking existing readers. Written by the run initiator; the sim that cast the ballot is attributed via `simUri`. Fixed-point convention: fields ending in `Milli` store real numbers ×1000 (lexicons have no float type).",
"key": "tid",
"record": {
"type": "object",
"required": [
"run",
"mechanism",
"gatheringUri",
"simUri",
"payload",
"createdAt"
],
"properties": {
"run": {
"type": "string",
"maxLength": 64,
"description": "Run identifier this ballot belongs to. Matches the run's org.simocracy.history `hearingId` and the published decision's `runId`."
},
"mechanism": {
"type": "string",
"maxLength": 64,
"description": "Versioned mechanism id that elicited this ballot, e.g. \"s-process@1\" or \"quadratic-voting@1\"."
},
"gatheringUri": {
"type": "string",
"description": "Scope identifier: usually the AT-URI of an org.simocracy.gathering record; a sentinel string for built-in scopes (e.g. \"ftc-sf:tower\")."
},
"simUri": {
"type": "string",
"description": "AT-URI of the org.simocracy.sim that cast this ballot."
},
"simName": {
"type": "string",
"maxLength": 200,
"description": "Display name of the sim at cast time (denormalised for cheap rendering)."
},
"round": {
"type": "integer",
"minimum": 0,
"description": "Deliberation round this ballot was cast in (0-based). Omitted for single-round runs."
},
"payload": {
"type": "union",
"refs": [
"#mvfBallot",
"#creditsBallot",
"#meritBallot"
],
"description": "Mechanism-specific ballot content."
},
"model": {
"type": "string",
"maxLength": 128,
"description": "Id of the AI model that generated this ballot (e.g. an OpenRouter slug like \"deepseek/deepseek-v4-flash-0731\", or a subscription model id when the run initiator's linked Claude/ChatGPT plan served the call). Recorded at elicitation time for reproducibility: replaying a run against a different model is a different experiment, and this field makes that visible. Absent on ballots cast before model provenance existed."
},
"recusalPolicy": {
"type": "string",
"description": "Conflict-of-interest rule in force when this ballot was elicited, copied from the gathering at run time so the ballot stays independently replayable. Absent means no policy was applied.",
"knownValues": [
"owner",
"sim",
"disclose",
"none"
]
},
"recusals": {
"type": "array",
"maxLength": 1000,
"items": {
"type": "ref",
"ref": "#recusal"
},
"description": "Proposals this sim was recused from, and why. These proposals are absent from the payload's evaluations/credits/scores by construction: a recusal is the absence of a judgement, NOT a zero-valued one. Readers replaying a run must skip these pairs when computing pairwise disagreement, and aggregators must renormalise the sim's remaining weight (e.g. quadratic-voting redistributes the full 100 voice credits across the unrecused slate) rather than letting the masked share evaporate."
},
"createdAt": {
"type": "string",
"format": "datetime"
}
}
}
},
"recusal": {
"type": "object",
"description": "One proposal this ballot's sim was barred from directing budget to. The sim's judgements on every other proposal in the run remain fully weighted.",
"required": [
"proposal",
"reason"
],
"properties": {
"proposal": {
"type": "string",
"description": "AT-URI of the proposal (org.hypercerts.claim.activity), or a \"title:<title>\" fallback key, matching the key convention used by the payload entries."
},
"proposalTitle": {
"type": "string",
"maxLength": 500,
"description": "Display title at cast time."
},
"reason": {
"type": "string",
"description": "Why the sim was recused. owner=the sim's owner DID matches the proposal's submitting repo DID. sim=the sim is credited as an author via an org.simocracy.history sidecar. manual=excluded by hand by the run initiator.",
"knownValues": [
"owner",
"sim",
"manual"
]
}
}
},
"mvfBallot": {
"type": "object",
"description": "S-Process ballot: one marginal-value function per proposal.",
"required": [
"evaluations"
],
"properties": {
"evaluations": {
"type": "array",
"maxLength": 1000,
"items": {
"type": "ref",
"ref": "#mvfEvaluation"
}
},
"outsideOptionMilli": {
"type": "integer",
"minimum": 0,
"description": "Marginal value of keeping a dollar for future rounds, ×1000 (fixed-point: 500 = 0.5)."
}
}
},
"mvfEvaluation": {
"type": "object",
"required": [
"proposal",
"mvf"
],
"properties": {
"proposal": {
"type": "string",
"description": "AT-URI of the evaluated proposal (org.hypercerts.claim.activity), or a \"title:<title>\" fallback key when the URI could not be resolved."
},
"proposalTitle": {
"type": "string",
"maxLength": 500,
"description": "Display title at cast time."
},
"reasoning": {
"type": "string",
"maxLength": 10000,
"maxGraphemes": 5000,
"description": "The sim's in-character reasoning for this curve."
},
"mvf": {
"type": "array",
"maxLength": 20,
"items": {
"type": "ref",
"ref": "#mvfPoint"
},
"description": "Piecewise-linear marginal value function, points sorted ascending by dollars."
}
}
},
"mvfPoint": {
"type": "object",
"required": [
"dollars",
"marginalValueMilli"
],
"properties": {
"dollars": {
"type": "integer",
"minimum": 0,
"description": "Funding level in whole USD."
},
"marginalValueMilli": {
"type": "integer",
"minimum": 0,
"description": "Value-per-dollar of the next dollar at this funding level, ×1000 (fixed-point: 1500 = 1.5)."
}
}
},
"creditsBallot": {
"type": "object",
"description": "Quadratic Voting ballot: voice credits spent per proposal. Effective votes are the square root of credits; a sim spends at most 100 credits per run.",
"required": [
"credits"
],
"properties": {
"reasoning": {
"type": "string",
"maxLength": 10000,
"maxGraphemes": 5000,
"description": "The sim's in-character reasoning for this spread."
},
"credits": {
"type": "array",
"maxLength": 1000,
"items": {
"type": "ref",
"ref": "#creditEntry"
}
}
}
},
"meritBallot": {
"type": "object",
"description": "Merit-Curve ballot: one rubric level per proposal, plus the round policy the levels were cast under. Merit-Curve is a selection mechanism for prize rounds — proposals are scored on a published 0–8 rubric and a closed-form water-fill splits the pot against a quality bar, holding back anything below it. The policy travels with the ballot so a run is replayable from its ballots alone.",
"required": [
"scores",
"policy"
],
"properties": {
"scores": {
"type": "array",
"maxLength": 1000,
"items": {
"type": "ref",
"ref": "#meritScore"
}
},
"policy": {
"type": "ref",
"ref": "#meritPolicy",
"description": "Round policy in force when this ballot was cast."
},
"reasoning": {
"type": "string",
"maxLength": 10000,
"maxGraphemes": 5000,
"description": "The sim's in-character reading of the slate as a whole."
}
}
},
"meritScore": {
"type": "object",
"required": [
"proposal",
"level"
],
"properties": {
"proposal": {
"type": "string",
"description": "AT-URI of the scored proposal (org.hypercerts.claim.activity), or a \"title:<title>\" fallback key."
},
"proposalTitle": {
"type": "string",
"maxLength": 500,
"description": "Display title at cast time."
},
"level": {
"type": "integer",
"minimum": 0,
"maximum": 8,
"description": "Rubric level. 0 = noise, 2 = restates the thread, 4 = well-argued but not new, 6 = novel defensible argument, 8 = would plausibly change how a delegate votes."
},
"note": {
"type": "string",
"maxLength": 2000,
"maxGraphemes": 1000,
"description": "One-line justification for this level."
}
}
},
"meritPolicy": {
"type": "object",
"description": "Round policy for a Merit-Curve run. Set by the gathering admin, never by the model.",
"required": [
"bar",
"maxShareMilli"
],
"properties": {
"bar": {
"type": "integer",
"minimum": 0,
"maximum": 8,
"description": "Rubric level at or below which a proposal earns nothing; that money is held back."
},
"maxShareMilli": {
"type": "integer",
"minimum": 1,
"maximum": 1000,
"description": "Maximum share of the round budget any one proposal may receive, ×1000 (400 = 40%)."
},
"minAwardUsd": {
"type": "integer",
"minimum": 0,
"description": "Awards below this many whole USD are swept back to the reserve."
},
"rubricVersion": {
"type": "string",
"maxLength": 64,
"description": "Identifier of the rubric text these levels were scored against."
}
}
},
"creditEntry": {
"type": "object",
"required": [
"proposal",
"credits"
],
"properties": {
"proposal": {
"type": "string",
"description": "AT-URI of the proposal (org.hypercerts.claim.activity), or a \"title:<title>\" fallback key."
},
"proposalTitle": {
"type": "string",
"maxLength": 500,
"description": "Display title at cast time."
},
"credits": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Voice credits spent on this proposal (integer, whole credits)."
}
}
}
}
}