File size: 4,537 Bytes
dfb775d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# Governance β€” classroom / boardroom / dojo

A clean-room reimplementation (from the behaviour of
[`github.com/openmindx/openmind`](https://github.com/openmindx/openmind) β€” Boardroom
multi-model consensus + Dojo head-to-head evaluation) of the decision layer that governs
training. Lives in `mindxtrain/governance/`; pure stdlib + pydantic, base-install importable.

## The model

- **Classroom** (`governance/classroom.py`) β€” where an actor (model) trains. An actor
  **graduates** when its persona imprint took: `graduate(imprint_report, min_delta=…)`
  returns a `Graduation` (the motion the boardroom convenes on). Ties the governance layer
  to `mindxtrain.eval.imprint`.
- **Boardroom** (`governance/boardroom.py`) β€” a panel of **any number** of role-based
  members (advocate, critic, analyst, devil's advocate, expert, generalist). `convene(motion,
  ballot)` tallies votes β†’ `approved` / `rejected` / `disputed`. The boardroom **governs the
  classroom**: it decides about training given a graduation. Preset boards: `classic_triad`,
  `devils_court`, `full_board`, `peer_review`.
- **Dojo** (`governance/dojo.py`) β€” the boardroom's **dispute-settlement** extension. When a
  boardroom is `disputed` (a tie or no quorum), a dojo settles it. **A dojo panel is always an
  odd prime (β‰₯ 3)** β€” an odd number of decisive judges cannot tie, so the dispute always
  resolves. `Dojo.sized(n)` rounds a requested size to the nearest valid prime; `settle(motion,
  ballot)` returns a final `DojoVerdict`. 2 is prime but even (can tie), so it is excluded.

## Flow

```
classroom: train actor β†’ measure imprint β†’ graduate(report) ─► Graduation.motion
                                                                      β”‚
boardroom: convene(motion, ballot) ─► approved / rejected / disputed β”‚
                                                  β”‚ disputed         β”‚
dojo (prime panel): settle_dispute(decision, dojo, ballot) ─► DojoVerdict (no tie)
```

Members vote via an explicit `{id: vote}` map or a callable `(member, motion) -> vote`, so
the whole layer is testable with no LLM and can later be backed by real models
(boardroom-of-LLMs, dojo head-to-head) β€” clean-room, never vendoring openmind's TypeScript.

## Why prime

A boardroom can be any size because deliberation tolerates abstention and "no decision"
(escalate). A dojo must *settle* β€” so its panel is an odd prime: `approvals + rejections`
is odd, the majority is strict, and the verdict is final. See `governance/primes.py`
(`is_prime`, `next_prime`, `nearest_prime`) and `dojo.prime_dojo_size`.

## Model-backed deliberation

`governance/panel.py` backs members + judges with **real models** (any OpenAI-compatible
backend β€” the same ollama / vLLM the operator serves). `deliberate(member, motion)` prompts a
member from its role stance and parses a `VERDICT: APPROVE|REJECT|ABSTAIN`; `model_ballot()` /
`model_judge_ballot()` return ballots you pass straight to `Boardroom.convene` /
`Dojo.settle`. Lazy + best-effort: a model that errors or returns no parseable verdict abstains
(boardroom) or is recorded as reject (dojo). The base URL resolves from
`MINDXTRAIN_OPENAI_BASE_URL` / `MINDXTRAIN_VLLM_BASE_URL` / `MINDXTRAIN_OLLAMA_BASE_URL`.

## Coach surface

The **Boardroom** card (after the receipt card) convenes a board on a promotion motion and,
if disputed, settles it in a prime dojo:

- `GET /coach/api/boardroom/presets` β€” named boards β†’ roles.
- `POST /coach/api/boardroom/convene` β€” `{motion, members:[{id,role,model}], quorum, votes?,
  use_models?, base_url?}`. Tally supplied `votes`, or `use_models: true` to have each member's
  model deliberate. Model calls run in a worker thread (`asyncio.to_thread`) so the operator
  event loop never blocks on inference. Returns the decision + per-member deliberations.
- `POST /coach/api/dojo/settle` β€” `{motion, size, model?, votes?, use_models?, base_url?}`.
  Sizes the panel to the nearest odd prime and settles.

## Tests

- `tests/test_governance.py` β€” primes, any-N boardroom (majority / tie / no-quorum), prime-only
  dojo (rejects non-prime panels, settles without tie), end-to-end classroom β†’ disputed β†’ dojo.
- `tests/test_governance_panel.py` β€” verdict parsing, role stances, model-backed ballots driving
  a boardroom + dojo over a mocked chat backend, graceful backend-error handling.
- `tests/test_coach_governance_api.py` β€” convene (votes + model mode), dojo settle (prime sizing),
  422 paths, and the Coach card/JS presence.