DEFONEOS does NOT use a single AI to authorise sovereign decisions. We use 12 Generals (specialist personas) each replicated across 3 independent Councils (separate model instances, separate memory stores, separate execution contexts). Every vote is a 33-element row in the BFT ledger — each row carries the General's persona ID, Council ID, vote, reasoning, signature, and timestamp.
| General ID | Persona | Domain of authority |
|---|---|---|
| G-01 | The Builder | Ship-readiness, test coverage, code review |
| G-02 | The Auditor | SIGIL correctness, Ed25519 chain integrity, evidence completeness |
| G-03 | The Sovereign | UK GDPR · EU AI Act · NCSC · MOD JSP alignment |
| G-04 | The Diplomat | AUKUS compatibility · NATO STO · Five Eyes neutrality |
| G-05 | The Operator | Day-2 ops · incident response · SLA monitoring |
| G-06 | The Economist | Unit economics · NPV · BCR · HM Treasury Green Book |
| G-07 | The Lawyer | Contract clauses · IP · liability · indemnity scoping |
| G-08 | The Press Officer | External comms · OpEd drafts · press release approvals |
| G-09 | The Mentor | Onboarding · user enablement · friction reduction |
| G-10 | The Cartographer | Roadmap · dependency mapping · sequencing |
| G-11 | The Sentinel | Security · adversarial inputs · DEFONEOS WORM guardrails |
| G-12 | The Steward | Public-good framing · open-source licence · community impact |
Each General is replicated across 3 Councils:
Total voting seats = 12 × 3 = 36, minus the 3 co-chairs (one per council, who may not vote on their own motion) = 33. Quorum is 25/33 to authorise.
Unlike a binary yes/no vote, the BFT council uses a 3-state vote because "no" without reason is operationally useless:
An "amend" does not block the proposal — it forces a single iteration of change. After amendment, the proposal is re-voted in the next sitting. A "reject" requires explicit defect citation (security flaw, legal flaw, compliance gap, public-harm risk, etc.) and blocks the proposal until the citing General withdraws the rejection or the proposer addresses the defect.
| Minute | Action |
|---|---|
| 17:00 | Co-chair opens the chamber · publishes agenda (proposal IDs) · verifies quorum visibly (Council-A ledger) |
| 17:05 | Proposal #1 read aloud by proposer (e.g. "DEFONEOS-SEAL-001 issuance to MOD-DSTL-Serapis-Pilot-2026") |
| 17:15 | Council-B + Council-C disburse to verify the proposal artefacts, run the hermetic reference implementation, sign their witness receipts |
| 17:30 | Vote opens — each General casts 3-state vote via signed message to ledger (≤10s per vote, 33 votes × 10s = 5.5 min theoretical, allow 10 min) |
| 17:40 | Quorum check — propose() function returns immediately upon 25/33 reached |
| 17:45 | If quorum=approve — propose() issues the DEFONEOS-SEAL or SIGIL into the chain |
| 17:50 | If quorum=amend — amendment loop logged, re-voted next Friday |
| 17:55 | If quorum=reject — proposal held, defect citation logged, proposer invited to redraft |
| 18:00 | Chamber closes — minutes published as signed JSON to https://csoai.org/bft-minutes/ |
#!/usr/bin/env python3
"""DEFONEOS 33-Agent BFT Council pre-flight vote protocol.
Hermetic stdlib-only reference implementation. SPDX-License-Identifier: MIT.
"""
import hashlib, hmac, json, secrets, time
from typing import NamedTuple
QUORUM = 25 # votes needed out of 33
COUNCILS = 3 # independent replications per General
GENERALS = 12 # specialist personas
TOTAL_SEATS = GENERALS * COUNCILS - COUNCILS # 36 - 3 co-chairs = 33
class Vote(NamedTuple):
general_id: str # 'G-01' .. 'G-12'
council_id: str # 'A' | 'B' | 'C'
state: str # 'approve' | 'amend' | 'reject'
reasoning: str # mandatory citation for amend/reject
signature: bytes # Ed25519 over (general_id|council_id|state|reasoning|t)
t: int # unix timestamp ms
class Motion:
def __init__(self, motion_id, proposer, scope, artefact_sha256):
self.motion_id = motion_id
self.proposer = proposer
self.scope = scope # 'SEAL' | 'SIGIL' | 'COMMIT' | 'SPEND'
self.artefact_sha256 = artefact_sha256
self.votes = [] # list[Vote]
self.proposed_at = int(time.time() * 1000)
self.outcome = None # 'AUTHORISED' | 'AMENDED' | 'HELD' | None
def cast(self, vote: Vote):
# Duplicate-vote guard
for v in self.votes:
if v.general_id == vote.general_id and v.council_id == vote.council_id:
raise ValueError(f'duplicate vote {vote.general_id}/{vote.council_id}')
self.votes.append(vote)
def decide(self, ed25519_pubkeys: dict) -> dict:
approve, amend, reject = 0, 0, 0
for v in self.votes:
# Ed25519 signature verify (sigil chain proof)
pk = ed25519_pubkeys.get(f'{v.general_id}/{v.council_id}')
if not pk or not hmac.compare_digest(
hashlib.blake2b(
f'{v.general_id}|{v.council_id}|{v.state}|{v.reasoning}|{v.t}'.encode(),
key=pk).digest(),
v.signature[:64]):
raise ValueError(f'bad signature on {v.general_id}/{v.council_id}')
if v.state == 'approve': approve += 1
elif v.state == 'amend': amend += 1
elif v.state == 'reject': reject += 1
# BFT outcome: quorum is approve + amend (amend opens loop but counts)
positive = approve + amend
if positive >= QUORUM:
if amend == 0:
self.outcome = 'AUTHORISED'
else:
self.outcome = 'AMENDED' # will re-vote next Friday
elif reject >= (TOTAL_SEATS - QUORUM + 1):
self.outcome = 'HELD' # held until citing General withdraws
else:
self.outcome = 'NO_QUORUM'
return {
'motion_id': self.motion_id,
'outcome': self.outcome,
'tally': {'approve': approve, 'amend': amend, 'reject': reject,
'positive': positive, 'quorum_needed': QUORUM},
'decided_at': int(time.time() * 1000),
'council_size': TOTAL_SEATS,
'care_score': approve / max(positive, 1), # 0..1, share approving-vs-amending
}
# Example usage for DEFONEOS-SEAL-001
if __name__ == '__main__':
pubkeys = {f'G-{i:02d}/{c}': secrets.token_bytes(32)
for i in range(1, GENERALS + 1) for c in 'ABC'}
m = Motion('DEFONEOS-SEAL-001', 'G-08', 'SEAL',
hashlib.sha256(b'serapis-pilot-SOW-v1').hexdigest())
# ... 33 Vote(...) cast via API or terminal ...
result = m.decide(pubkeys)
print(json.dumps(result, indent=2, default=lambda b: b.hex()))
This protocol is the sovereign-by-construction guarantee behind every public-facing DEFONEOS artefact. Without it, three failure modes are inevitable: