Implement LLM-driven governance architecture with structured memory
This commit completes the transition to a pure LLM-driven agentic governance system with no hard-coded governance logic. Core Architecture Changes: - Add structured memory system (memory.py) for tracking governance processes - Add LLM tools (tools.py) for deterministic operations (math, dates, random) - Add audit trail system (audit.py) for human-readable decision explanations - Add LLM-driven agent (agent_refactored.py) that interprets constitution Documentation: - Add ARCHITECTURE.md describing process-centric design - Add ARCHITECTURE_EXAMPLE.md with complete workflow walkthrough - Update README.md to reflect current LLM-driven architecture - Simplify constitution.md to benevolent dictator model for testing Templates: - Add 8 governance templates (petition, consensus, do-ocracy, jury, etc.) - Add 8 dispute resolution templates - All templates work with generic process-based architecture Key Design Principles: - "Process" is central abstraction (not "proposal") - No hard-coded process types or thresholds - LLM interprets constitution to understand governance rules - Tools ensure correctness for calculations - Complete auditability with reasoning and citations Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
643
ARCHITECTURE_EXAMPLE.md
Normal file
643
ARCHITECTURE_EXAMPLE.md
Normal file
@@ -0,0 +1,643 @@
|
||||
# Governance Architecture: Complete Example
|
||||
|
||||
This document shows how the agentic governance system works through a complete process lifecycle, using a **proposal** as the example.
|
||||
|
||||
**Note**: The system uses "process" as the generic concept for any governance activity. Proposals are just one type of process. The same architecture handles disputes, elections, discussions, do-ocracy actions, jury selection, and any other process type defined in your constitution.
|
||||
|
||||
## Example Process: Standard Proposal
|
||||
|
||||
User `@alice` initiates a proposal process. Let's see how the system handles it WITHOUT hard-coded logic.
|
||||
|
||||
### Step 1: User Submits Proposal
|
||||
|
||||
```
|
||||
@alice: "@govbot I propose we change the moderation policy to require 2 moderators for bans"
|
||||
```
|
||||
|
||||
### Step 2: Agent Parses Intent (LLM)
|
||||
|
||||
```python
|
||||
agent._parse_intent_with_llm(request, actor="@alice")
|
||||
```
|
||||
|
||||
**LLM Response**:
|
||||
```json
|
||||
{
|
||||
"intent_type": "create_proposal",
|
||||
"query": "What are the rules for creating a proposal about moderation policy?",
|
||||
"parameters": {
|
||||
"proposal_text": "change the moderation policy to require 2 moderators for bans",
|
||||
"topic": "moderation_policy"
|
||||
},
|
||||
"confidence": "high"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Query Constitution
|
||||
|
||||
```python
|
||||
constitution.query(
|
||||
question="What are the rules for creating a proposal about moderation policy?",
|
||||
context="Actor: @alice, Request: [proposal text]"
|
||||
)
|
||||
```
|
||||
|
||||
**Constitutional Reasoner Returns**:
|
||||
```json
|
||||
{
|
||||
"answer": "Standard proposals address routine governance matters including policy changes. They require a 6-day discussion period and pass when more people vote agree than disagree.",
|
||||
"sections": [
|
||||
{
|
||||
"title": "Article 3, Section 3.1: Proposal Types",
|
||||
"content": "Standard Proposals address routine governance matters:\n- Discussion period: 6 days minimum\n- Passage threshold: More Agree than Disagree votes"
|
||||
}
|
||||
],
|
||||
"confidence": "high"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Query Memory for Context
|
||||
|
||||
```python
|
||||
memory.get_active_processes()
|
||||
```
|
||||
|
||||
**Memory Returns**:
|
||||
```python
|
||||
[
|
||||
ProcessMemory(
|
||||
id="process_123",
|
||||
type="standard_proposal",
|
||||
status=ACTIVE,
|
||||
created_by="@bob",
|
||||
deadline=datetime(2026, 2, 10),
|
||||
# ... other active proposals
|
||||
),
|
||||
# ... more processes
|
||||
]
|
||||
```
|
||||
|
||||
**Memory Context Summary**:
|
||||
```json
|
||||
{
|
||||
"active_processes": [
|
||||
"Process process_123: standard_proposal by @bob, deadline 2026-02-10",
|
||||
"Process process_124: urgent_proposal by @carol, deadline 2026-02-09"
|
||||
],
|
||||
"overdue_processes": []
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: LLM Makes Decision
|
||||
|
||||
```python
|
||||
agent._make_decision_with_llm(intent, constitution, memory, actor, context)
|
||||
```
|
||||
|
||||
**LLM Prompt** (simplified):
|
||||
```
|
||||
You are a governance bot interpreting a community constitution.
|
||||
|
||||
INTENT:
|
||||
User wants to create a proposal about moderation policy.
|
||||
|
||||
CONSTITUTIONAL GUIDANCE:
|
||||
Standard proposals need 6-day discussion period and pass when more agree than disagree.
|
||||
|
||||
CURRENT MEMORY STATE:
|
||||
2 active proposals currently running.
|
||||
|
||||
What should be done?
|
||||
```
|
||||
|
||||
**LLM Decision**:
|
||||
```json
|
||||
{
|
||||
"action": "create_process",
|
||||
"reasoning": "This is a standard proposal about moderation policy. According to Article 3, Section 3.1, standard proposals require a 6-day discussion period and pass when more members vote agree than disagree. I should create a new process with these parameters.",
|
||||
"constitution_citations": [
|
||||
"Article 3, Section 3.1: Proposal Types"
|
||||
],
|
||||
"parameters": {
|
||||
"process_type": "standard_proposal",
|
||||
"deadline_days": 6,
|
||||
"threshold_expression": "agree > disagree",
|
||||
"initial_state": {
|
||||
"proposal_text": "change the moderation policy to require 2 moderators for bans",
|
||||
"proposer": "@alice",
|
||||
"topic": "moderation_policy",
|
||||
"votes": {}
|
||||
}
|
||||
},
|
||||
"calculations": [
|
||||
{
|
||||
"tool": "datetime_add",
|
||||
"days": 6,
|
||||
"result": "2026-02-14T18:30:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Execute Decision
|
||||
|
||||
```python
|
||||
agent._execute_decision(decision, actor="@alice", context)
|
||||
```
|
||||
|
||||
**Memory Operations**:
|
||||
|
||||
1. **Create Process**:
|
||||
```python
|
||||
process = memory.create_process(
|
||||
process_id="process_125",
|
||||
process_type="standard_proposal",
|
||||
created_by="@alice",
|
||||
constitution_basis=["Article 3, Section 3.1: Proposal Types"],
|
||||
deadline=datetime(2026, 2, 14, 18, 30),
|
||||
initial_state={
|
||||
"proposal_text": "change the moderation policy to require 2 moderators for bans",
|
||||
"votes": {}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
2. **Log Event**:
|
||||
```python
|
||||
memory.add_event(
|
||||
process_id="process_125",
|
||||
actor="@alice",
|
||||
event_type="process_created",
|
||||
data={"proposal_text": "..."},
|
||||
context="Proposal created by @alice"
|
||||
)
|
||||
```
|
||||
|
||||
3. **Log Decision**:
|
||||
```python
|
||||
memory.add_decision(
|
||||
process_id="process_125",
|
||||
decision_type="process_creation",
|
||||
reasoning="This is a standard proposal about moderation policy...",
|
||||
constitution_citations=["Article 3, Section 3.1"],
|
||||
result="created"
|
||||
)
|
||||
```
|
||||
|
||||
### Step 7: Generate Response
|
||||
|
||||
**Bot Response**:
|
||||
```
|
||||
@alice Your proposal has been created as Process #125.
|
||||
|
||||
Type: Standard Proposal
|
||||
Discussion Period: 6 days
|
||||
Deadline: February 14, 2026 at 18:30 UTC
|
||||
Voting Threshold: More Agree than Disagree votes
|
||||
|
||||
Constitutional Basis: Article 3, Section 3.1 - Standard Proposals
|
||||
|
||||
The discussion period is now open. Community members may discuss and
|
||||
vote on this proposal until the deadline.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scenario: Voting
|
||||
|
||||
User `@bob` votes on the proposal.
|
||||
|
||||
### Step 1: User Votes
|
||||
|
||||
```
|
||||
@bob: "@govbot I vote agree on proposal 125"
|
||||
```
|
||||
|
||||
### Step 2-4: Intent Parsing + Constitution + Memory
|
||||
|
||||
**Intent**: `cast_vote` on `process_125`
|
||||
|
||||
**Constitution**: "Members vote by replying to proposal thread. Votes can be changed before deadline."
|
||||
|
||||
**Memory**: Gets process_125, checks if active, checks if @bob already voted
|
||||
|
||||
### Step 5: LLM Decision
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "record_vote",
|
||||
"reasoning": "@bob is voting 'agree' on an active proposal. The constitution allows members to vote before the deadline. This vote should be recorded.",
|
||||
"constitution_citations": ["Article 4, Section 4.2: Voting Process"],
|
||||
"parameters": {
|
||||
"process_id": "process_125",
|
||||
"vote_type": "agree"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Execute
|
||||
|
||||
**Memory Operations**:
|
||||
|
||||
1. **Update Process State**:
|
||||
```python
|
||||
votes = process.state["votes"]
|
||||
votes["@bob"] = {"vote": "agree", "timestamp": "2026-02-09T10:15:00Z"}
|
||||
memory.update_process("process_125", state_updates={"votes": votes})
|
||||
```
|
||||
|
||||
2. **Log Event**:
|
||||
```python
|
||||
memory.add_event(
|
||||
process_id="process_125",
|
||||
actor="@bob",
|
||||
event_type="vote_cast",
|
||||
data={"vote": "agree"},
|
||||
context="@bob voted agree"
|
||||
)
|
||||
```
|
||||
|
||||
**Bot Response**:
|
||||
```
|
||||
@bob Your vote has been recorded: Agree
|
||||
|
||||
Current tally for Proposal #125:
|
||||
- Agree: 1
|
||||
- Disagree: 0
|
||||
- Abstain: 0
|
||||
|
||||
Deadline: February 14, 2026 at 18:30 UTC
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scenario: Deadline Reached
|
||||
|
||||
Bot checks deadlines and evaluates proposal.
|
||||
|
||||
### Step 1: Scheduled Check
|
||||
|
||||
```python
|
||||
agent.check_deadlines()
|
||||
```
|
||||
|
||||
**Memory Query**:
|
||||
```python
|
||||
overdue = memory.get_overdue_processes()
|
||||
# Returns: [process_125]
|
||||
```
|
||||
|
||||
### Step 2: Evaluate Process
|
||||
|
||||
```python
|
||||
agent._evaluate_process_deadline(process_125)
|
||||
```
|
||||
|
||||
**Get Votes**:
|
||||
```python
|
||||
votes = process.state["votes"]
|
||||
# {"@bob": {"vote": "agree"}, "@carol": {"vote": "agree"}, "@dave": {"vote": "disagree"}}
|
||||
|
||||
vote_tally = tools.tally([{"vote": v["vote"]} for v in votes.values()], "vote")
|
||||
# Result: {"agree": 2, "disagree": 1}
|
||||
```
|
||||
|
||||
### Step 3: Query Constitution for Threshold
|
||||
|
||||
```python
|
||||
constitution.query(
|
||||
question="For a standard_proposal, what voting threshold is required for passage?",
|
||||
context="Votes: agree=2, disagree=1"
|
||||
)
|
||||
```
|
||||
|
||||
**Constitution Returns**:
|
||||
```json
|
||||
{
|
||||
"answer": "Standard proposals pass when there are more Agree votes than Disagree votes.",
|
||||
"sections": ["Article 3, Section 3.1"],
|
||||
"confidence": "high"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: LLM Evaluates Threshold
|
||||
|
||||
**LLM Prompt**:
|
||||
```
|
||||
Process process_125 has reached its deadline.
|
||||
|
||||
Votes cast:
|
||||
- Agree: 2
|
||||
- Disagree: 1
|
||||
- Abstain: 0
|
||||
|
||||
Constitution says: "More Agree than Disagree votes"
|
||||
|
||||
Does this proposal pass?
|
||||
|
||||
Use the calculate tool to evaluate: agree > disagree
|
||||
```
|
||||
|
||||
**LLM Decision**:
|
||||
```json
|
||||
{
|
||||
"action": "complete_process",
|
||||
"reasoning": "The proposal has reached its deadline. According to the constitution, standard proposals pass when more members vote agree than disagree. The vote tally shows 2 agree and 1 disagree. Using the calculate tool: 2 > 1 = True. Therefore, the proposal passes.",
|
||||
"constitution_citations": ["Article 3, Section 3.1: Passage threshold"],
|
||||
"parameters": {
|
||||
"process_id": "process_125",
|
||||
"outcome": "passed"
|
||||
},
|
||||
"calculations": [
|
||||
{
|
||||
"tool": "calculate",
|
||||
"expression": "agree > disagree",
|
||||
"variables": {"agree": 2, "disagree": 1},
|
||||
"result": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Execute Completion
|
||||
|
||||
**Memory Operations**:
|
||||
|
||||
1. **Update Status**:
|
||||
```python
|
||||
memory.update_process("process_125", status=ProcessStatus.COMPLETED)
|
||||
```
|
||||
|
||||
2. **Log Decision**:
|
||||
```python
|
||||
memory.add_decision(
|
||||
process_id="process_125",
|
||||
decision_type="process_completion",
|
||||
reasoning="The proposal has reached its deadline...",
|
||||
constitution_citations=["Article 3, Section 3.1"],
|
||||
result="passed",
|
||||
calculation_used="agree > disagree",
|
||||
calculation_variables={"agree": 2, "disagree": 1},
|
||||
calculation_result=True
|
||||
)
|
||||
```
|
||||
|
||||
3. **Log Event**:
|
||||
```python
|
||||
memory.add_event(
|
||||
process_id="process_125",
|
||||
actor="bot",
|
||||
event_type="process_completed",
|
||||
data={"outcome": "passed"},
|
||||
context="Process completed: proposal passed"
|
||||
)
|
||||
```
|
||||
|
||||
### Step 6: Generate Audit Trail
|
||||
|
||||
```python
|
||||
audit = AuditTrail.format_decision(process.decisions[-1], process)
|
||||
```
|
||||
|
||||
**Audit Trail** (excerpt):
|
||||
```markdown
|
||||
# GOVERNANCE DECISION AUDIT TRAIL
|
||||
|
||||
**Decision ID**: process_125_2
|
||||
**Timestamp**: 2026-02-14 18:30:15 UTC
|
||||
**Decision Type**: process_completion
|
||||
**Result**: passed
|
||||
|
||||
## Constitutional Basis
|
||||
|
||||
- Article 3, Section 3.1: Passage threshold
|
||||
|
||||
## Reasoning
|
||||
|
||||
The proposal has reached its deadline. According to the constitution,
|
||||
standard proposals pass when more members vote agree than disagree.
|
||||
The vote tally shows 2 agree and 1 disagree. Using the calculate tool:
|
||||
2 > 1 = True. Therefore, the proposal passes.
|
||||
|
||||
## Calculation Details
|
||||
|
||||
**Expression**: `agree > disagree`
|
||||
**Variables**:
|
||||
- `agree` = 2
|
||||
- `disagree` = 1
|
||||
**Result**: `True`
|
||||
```
|
||||
|
||||
### Step 7: Announce Result
|
||||
|
||||
**Bot Post**:
|
||||
```
|
||||
📊 Proposal #125 has PASSED
|
||||
|
||||
Proposal: "Change the moderation policy to require 2 moderators for bans"
|
||||
Proposed by: @alice
|
||||
|
||||
Final Vote Tally:
|
||||
✅ Agree: 2 (66.7%)
|
||||
❌ Disagree: 1 (33.3%)
|
||||
⚪ Abstain: 0
|
||||
|
||||
Constitutional Threshold: More Agree than Disagree
|
||||
Result: 2 > 1 ✓
|
||||
|
||||
This proposal has passed and will now be implemented.
|
||||
|
||||
Full audit trail: [link]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Differences from Old System
|
||||
|
||||
### Old System (Hard-Coded)
|
||||
```python
|
||||
# Hard-coded threshold check
|
||||
def check_threshold(counts, "simple_majority"):
|
||||
return counts['agree'] > counts['disagree']
|
||||
|
||||
# Hard-coded in agent
|
||||
if threshold_type == "simple_majority":
|
||||
passed = agree > disagree
|
||||
```
|
||||
|
||||
### New System (Agentic)
|
||||
```python
|
||||
# Constitution defines threshold in natural language
|
||||
"More Agree than Disagree votes"
|
||||
|
||||
# LLM interprets and uses tool
|
||||
decision = llm.decide(
|
||||
constitution="More Agree than Disagree votes",
|
||||
votes={"agree": 2, "disagree": 1}
|
||||
)
|
||||
# Returns: "Use calculate tool with expression 'agree > disagree'"
|
||||
|
||||
result = tools.calculate("agree > disagree", {"agree": 2, "disagree": 1})
|
||||
# Returns: True
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Auditability Example
|
||||
|
||||
Community member `@eve` wants to understand why proposal 125 passed.
|
||||
|
||||
### Query Memory
|
||||
|
||||
```python
|
||||
process = memory.get_process("process_125")
|
||||
audit = AuditTrail.generate_process_audit_file(process)
|
||||
```
|
||||
|
||||
### Audit File Contents
|
||||
|
||||
```markdown
|
||||
# Governance Process Audit: process_125
|
||||
|
||||
**Generated**: 2026-02-15 09:00:00 UTC
|
||||
|
||||
---
|
||||
|
||||
# Process Summary: process_125
|
||||
|
||||
**Type**: standard_proposal
|
||||
**Status**: completed
|
||||
**Created By**: @alice
|
||||
**Created At**: 2026-02-08 18:30:00 UTC
|
||||
**Deadline**: 2026-02-14 18:30:00 UTC
|
||||
|
||||
## Constitutional Basis
|
||||
|
||||
- Article 3, Section 3.1: Proposal Types
|
||||
|
||||
## Current State
|
||||
|
||||
- proposal_text: change the moderation policy...
|
||||
- proposer: @alice
|
||||
- topic: moderation_policy
|
||||
- votes: 3 items
|
||||
|
||||
## Event Timeline
|
||||
|
||||
**[2026-02-08 18:30]** process_created
|
||||
- Actor: @alice
|
||||
- Context: Proposal created by @alice
|
||||
|
||||
**[2026-02-09 10:15]** vote_cast
|
||||
- Actor: @bob
|
||||
- Context: @bob voted agree
|
||||
|
||||
**[2026-02-10 14:22]** vote_cast
|
||||
- Actor: @carol
|
||||
- Context: @carol voted agree
|
||||
|
||||
**[2026-02-11 09:45]** vote_cast
|
||||
- Actor: @dave
|
||||
- Context: @dave voted disagree
|
||||
|
||||
**[2026-02-14 18:30]** process_completed
|
||||
- Actor: bot
|
||||
- Context: Process completed: proposal passed
|
||||
|
||||
## Decisions
|
||||
|
||||
**1. [2026-02-08 18:30]** process_creation
|
||||
- Result: created
|
||||
- Reasoning: This is a standard proposal about moderation policy...
|
||||
|
||||
**2. [2026-02-14 18:30]** process_completion
|
||||
- Result: passed
|
||||
- Reasoning: The proposal has reached its deadline. According to...
|
||||
|
||||
---
|
||||
|
||||
# Detailed Decision Log
|
||||
|
||||
[Full decision details with calculations, reasoning, citations...]
|
||||
|
||||
---
|
||||
|
||||
## Audit Trail Integrity
|
||||
|
||||
This audit trail represents the complete record of this governance process.
|
||||
All decisions were made according to the community constitution...
|
||||
```
|
||||
|
||||
**Key Point**: Every step is logged with:
|
||||
- What happened
|
||||
- When it happened
|
||||
- Who did it
|
||||
- Why (bot reasoning)
|
||||
- What constitutional rule applied
|
||||
- What calculations were used
|
||||
|
||||
Humans can inspect and verify every decision.
|
||||
|
||||
---
|
||||
|
||||
## Handling Different Templates
|
||||
|
||||
The beauty of this system: the SAME code works for different governance models!
|
||||
|
||||
### Example: Consensus (from templates)
|
||||
|
||||
**Constitution excerpt**:
|
||||
```markdown
|
||||
### Section 4.4: Block
|
||||
|
||||
"I block this proposal because..."
|
||||
- Fundamental objection preventing consensus
|
||||
- Must include explanation and reasoning
|
||||
- Triggers deeper discussion
|
||||
```
|
||||
|
||||
**User Action**:
|
||||
```
|
||||
@frank: "@govbot I block proposal 126 because it violates our privacy principles"
|
||||
```
|
||||
|
||||
**Agent Flow**:
|
||||
1. LLM parses intent: "cast_vote with type=block"
|
||||
2. Queries constitution: "What happens when someone blocks?"
|
||||
3. Constitution: "Triggers deeper discussion, proposal cannot pass until block resolved"
|
||||
4. LLM decides: "Record block vote, update process status to 'blocked', notify proposer"
|
||||
5. Memory updated with block and reasoning
|
||||
6. Audit trail shows: "Block recorded. Constitutional requirement: must address concern"
|
||||
|
||||
**No code changes needed!** The agent interprets the constitution's block rules.
|
||||
|
||||
### Example: Jury/Sortition (from templates)
|
||||
|
||||
**Constitution excerpt**:
|
||||
```markdown
|
||||
Juries selected randomly:
|
||||
- 5-7 members from eligible pool
|
||||
- Random selection ensures fairness
|
||||
```
|
||||
|
||||
**Agent Flow**:
|
||||
1. LLM interprets: "Need to select 5-7 random members"
|
||||
2. Uses tool: `random_select(eligible_members, count=5)`
|
||||
3. Creates jury process in memory
|
||||
4. Logs selection with seed for reproducibility
|
||||
5. Audit shows: "Selected using random sortition per Article X"
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The system:
|
||||
|
||||
✅ **No hard-coded governance logic** - All rules come from constitution
|
||||
✅ **LLM interprets and decides** - Based on natural language rules
|
||||
✅ **Structured memory tracks state** - Queryable by LLM and humans
|
||||
✅ **Tools ensure correctness** - Math done by calculator, not LLM reasoning
|
||||
✅ **Complete audit trails** - Every decision explained and cited
|
||||
✅ **Works with any template** - Consensus, do-ocracy, jury, etc.
|
||||
|
||||
The key insight: **Separate interpretation from execution**. LLM interprets what to do, tools execute it correctly, memory tracks everything, audits explain it all.
|
||||
Reference in New Issue
Block a user