Abstimmung: mehrere Agenten pruefen unabhaengig und stimmen blind ab (#702)

A unit can put operations to a blind vote instead of its lead. Not opinions
are counted but independent checks enforced.

- UnitConfig.votes: operations, voters, approveAt, rejectAt, quorum, hours,
  perDay - set only by a human (OrgAdministration.SetVotes).
- Core/Staging/Votes: routes a covered staged call before the lead; one task
  per voter with the frozen call and nothing else; cast_vote needs reasoning
  and evidence. Counted as soon as the result is settled; in between and
  without the quorum a human decides. The proposer does not vote, voters that
  read foreign content get no ballot, changes to agents never go to a vote.
- Escalation tool: list_ballots, cast_vote.
- Approvals view shows each vote with every ballot and the voters' costs;
  organisation view sets the rule and lists the votes held.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-10-01 12:04:33 +02:00
co-authored by Claude Opus 5.5
parent d834e5ac38
commit a5dd503d9b
23 changed files with 1238 additions and 11 deletions
@@ -138,6 +138,20 @@
"org.measure.security": "Sicherheitsverdacht",
"org.measureStatus.accepted": "angenommen",
"org.measureStatus.dismissed": "abgelehnt",
"org.votes": "Abstimmungen",
"org.votesHint": "Operationen, die mehrere Agenten vor der Ausführung unabhängig prüfen und blind abstimmen — statt der Leitung. Stimmberechtigte wählen, die auf verschiedene Daten sehen (Konten, Lager, Sortiment): Es geht um unabhängige Prüfungen, nicht um eine Mehrheit. Wer beantragt, stimmt nicht mit; wer fremde Inhalte liest, bekommt keinen Stimmzettel; eine fehlende Stimme ist kein Ja. Zwischen Annahme und Ablehnung und ohne Quorum entscheidest du. Jede Stimme kostet einen Lauf.",
"org.votesVoters": "Stimmberechtigte (ein Agent je Zeile)",
"org.votesApproveAt": "Angenommen ab Ja-Stimmen",
"org.votesRejectAt": "Abgelehnt bei höchstens Ja-Stimmen",
"org.votesQuorum": "Mindestens abgegebene Stimmen (0: wie für Annahme)",
"org.votesHours": "Stunden für die Abstimmung",
"org.votesHeld": "Abgehaltene Abstimmungen",
"org.voteWhen": "Wann",
"org.voteOperation": "Aufruf",
"org.voteTally": "Stimmen",
"org.voteTallyText": "{yes} ja · {no} nein · {missing} fehlen",
"org.voteOutcome": "Ergebnis",
"org.voteCost": "Kosten der Abstimmenden",
"org.ceilingInherited": "Von oben begrenzt auf: {tools}",
"org.settings": "Sammelwerte",
"org.settingsHint": "Werden nach einer Vorschau in die Agenten geschrieben. Die Einheit merkt sich den Wert nur als Vorgabe für neue Mitglieder — zur Laufzeit übertrumpft nichts einen Agenten.",
@@ -659,6 +673,14 @@
"staging.rejected": "Aufruf wurde abgelehnt.",
"staging.rejectFailed": "Ablehnen fehlgeschlagen: {error}",
"staging.withLead": "Die Leitung {lead} darf dies bis {until} entscheiden, im Rahmen dessen, was ihre Einheit erlaubt. Du kannst vorher entscheiden; danach liegt es allein bei dir.",
"staging.voteRunning": "Abstimmung #{id} läuft bis {until}: {yes} ja, {no} nein, {missing} ausstehend. Du kannst vorher entscheiden.",
"staging.voteDone": "Abstimmung #{id}: {outcome} — {yes} ja, {no} nein, {missing} fehlen.",
"staging.voteRule": "Angenommen ab {approve} Ja, abgelehnt bei höchstens {reject}, mindestens {quorum} Stimmen",
"staging.voteCost": "Läufe der Abstimmenden: ${cost}",
"staging.voteYes": "ja",
"staging.voteNo": "nein",
"staging.voteMissing": "fehlt",
"staging.voteEvidence": "Beleg: {evidence}",
"staging.leadsTitle": "Freigaben durch Leitungen",
"staging.leadsHint": "Was Leitungen in den letzten 30 Tagen an deiner Stelle freigegeben haben. Eine Leitung, die alles freigibt, verursacht nur Kosten — sieh dir ihre Entscheidungen an.",
"staging.leadName": "Leitung",