
Product
Microsoft Teams Notifications Are Now Available in Socket
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.
@weave_protocol/witan
Advanced tools
Council Protocol - Multi-agent consensus, communication, and governance for AI systems
Multi-agent consensus, communication, governance, and recovery for AI orchestration systems.
Part of the Weave Protocol Security Suite.
Witan = Old English for "council of advisors" (the Witenagemot advised Anglo-Saxon kings)
| Module | Capabilities |
|---|---|
| Consensus Engine | Proposals, voting, quorum, weighted votes, veto |
| Communication Bus | Direct messaging, pub/sub channels, broadcast |
| Policy Engine | Rate limits, quotas, governance rules |
| Recovery Manager | Checkpoints, transactions, rollback, disaster recovery |
Built on Dōmere orchestration primitives (TaskScheduler, AgentRegistry, StateManager).
npm install @weave_protocol/witan
import { WitanCouncil } from '@weave_protocol/witan';
// Create council
const council = new WitanCouncil({
signing_key: 'your-secret-key',
max_agents: 10,
default_quorum: 0.6,
enable_auto_recovery: true
});
await council.start();
// Register agents
for (let i = 0; i < 10; i++) {
await council.registerAgent({
name: `agent-${i}`,
capabilities: ['research', 'analysis'],
voting_weight: 1
});
}
// Submit tasks
await council.submitTask({
intent: 'Analyze market data',
priority: 'high'
});
// Propose decisions for vote
const proposal = await council.propose({
title: 'Increase compute budget',
description: 'Proposal to increase daily compute quota by 50%',
type: 'resource',
proposer_id: 'agent-0',
payload: { new_quota: 150 }
});
// Agents vote
await council.vote(proposal.id, 'agent-1', 'approve', 'Needed for scaling');
await council.vote(proposal.id, 'agent-2', 'approve');
await council.vote(proposal.id, 'agent-3', 'reject', 'Cost concerns');
Multi-agent voting with quorum, thresholds, and weighted votes.
import { ConsensusEngine } from '@weave_protocol/witan';
const consensus = new ConsensusEngine('signing-key', {
default_quorum: 0.5, // 50% must vote
default_threshold: 0.6, // 60% approval needed
default_voting_duration_ms: 300000 // 5 minutes
});
// Create proposal
const proposal = await consensus.createProposal({
title: 'Deploy new model',
description: 'Replace GPT-4 with Claude for all tasks',
proposal_type: 'action',
proposer_id: 'orchestrator',
eligible_voters: ['agent-1', 'agent-2', 'agent-3', 'agent-4', 'agent-5'],
voting_config: {
quorum: 0.6,
threshold: 0.7,
weighted_voting: true,
weights: new Map([
['agent-1', 2], // Lead agent gets double weight
['agent-2', 1],
['agent-3', 1],
['agent-4', 1],
['agent-5', 1]
]),
veto_enabled: true,
veto_holders: ['orchestrator']
}
});
// Cast votes
await consensus.vote(proposal.id, 'agent-1', 'approve', 'Better reasoning');
await consensus.vote(proposal.id, 'agent-2', 'approve');
await consensus.vote(proposal.id, 'agent-3', 'reject', 'Cost increase');
await consensus.vote(proposal.id, 'agent-4', 'abstain');
// Check result
const result = await consensus.finalizeProposal(proposal.id);
console.log(result.decision); // 'approved' | 'rejected' | 'no_quorum'
console.log(result.participation_rate);
console.log(result.approve_weight);
// Subscribe to events
consensus.onEvent((event) => {
if (event.type === 'passed') {
console.log(`Proposal ${event.proposal_id} passed!`);
}
});
Agent-to-agent messaging with channels and pub/sub.
import { CommunicationBus } from '@weave_protocol/witan';
const bus = new CommunicationBus('signing-key', {
default_ttl_ms: 300000,
max_pending_messages: 1000
});
// Register agents
await bus.registerAgent('agent-1');
await bus.registerAgent('agent-2');
// Direct message
await bus.send({
from: 'agent-1',
to: 'agent-2',
type: 'data-handoff',
payload: { dataset_id: 'ds_123', format: 'json' },
priority: 'high',
require_ack: true
});
// Create topic channel
const channel = await bus.createChannel({
name: 'research-updates',
type: 'topic',
owner: 'orchestrator',
initial_members: ['agent-1', 'agent-2', 'agent-3']
});
// Publish to channel
await bus.publish({
from: 'agent-1',
channel: 'research-updates',
type: 'finding',
payload: { insight: 'Market trending upward' }
});
// Broadcast to all
await bus.broadcast({
from: 'orchestrator',
type: 'priority-change',
payload: { all_tasks: 'high' },
priority: 'critical'
});
// Receive messages (in agent loop)
const messages = await bus.receive('agent-2', { limit: 10 });
for (const msg of messages) {
console.log(`From ${msg.from}: ${msg.type}`);
await bus.acknowledge(msg.id, 'agent-2');
}
// Subscribe with handler
const unsubscribe = bus.subscribe('agent-3', async (message) => {
console.log('Received:', message.type);
}, { types: ['finding', 'alert'] });
Governance rules, rate limits, quotas, and constraints.
import { PolicyEngine } from '@weave_protocol/witan';
const policy = new PolicyEngine();
// Rate limit: 100 requests per minute per agent
await policy.createRateLimit({
name: 'api-rate-limit',
targets: [{ type: 'all' }],
max_requests: 100,
window_ms: 60000,
action: 'throttle'
});
// Quota: Max 1000 tokens per agent per day
await policy.createQuota({
name: 'daily-token-quota',
targets: [{ type: 'agent', ids: ['agent-1', 'agent-2'] }],
resource: 'tokens',
max_value: 1000
});
// Schedule: Only allow actions during business hours
await policy.createSchedulePolicy({
name: 'business-hours-only',
targets: [{ type: 'all' }],
allowed_hours: { start: 9, end: 17 },
allowed_days: [1, 2, 3, 4, 5], // Mon-Fri
action: 'deny'
});
// Concurrency limit
await policy.createConcurrencyLimit({
name: 'max-parallel-tasks',
targets: [{ type: 'agent', pattern: 'agent-.*' }],
max_concurrent: 5
});
// Enforce policy
const decision = await policy.enforce({
agent_id: 'agent-1',
action: 'api_call',
resource: 'openai',
timestamp: new Date()
});
if (!decision.allowed) {
console.log(`Denied: ${decision.message}`);
if (decision.retry_after_ms) {
console.log(`Retry in ${decision.retry_after_ms}ms`);
}
}
// Track violations
policy.onViolation((violation) => {
console.log(`Policy violation: ${violation.policy_id} by ${violation.agent_id}`);
});
Checkpoints, transactions, and disaster recovery.
import { RecoveryManager } from '@weave_protocol/witan';
const recovery = new RecoveryManager('signing-key', {
max_checkpoints: 100,
auto_checkpoint_interval_ms: 300000, // Every 5 min
enable_auto_recovery: true
});
// Create checkpoint
const checkpoint = await recovery.checkpoint({
name: 'Pre-deployment',
created_by: 'orchestrator',
tags: ['deployment', 'critical']
});
// Begin transaction
const txn = await recovery.beginTransaction({
initiator: 'agent-1',
description: 'Update configuration',
auto_checkpoint: true
});
// Record operations
await recovery.recordOperation(txn.id, {
type: 'state_change',
target_type: 'state',
target_id: 'config',
action: 'update',
before: { version: 1 },
after: { version: 2 },
success: true,
reversible: true,
rollback_action: 'restore'
});
// Commit or rollback
try {
// ... do work ...
await recovery.commitTransaction(txn.id);
} catch (error) {
await recovery.rollbackTransaction(txn.id);
}
// Restore from checkpoint
await recovery.restore(checkpoint.id, 'admin');
// Create recovery plan
await recovery.createRecoveryPlan({
name: 'Agent failure recovery',
trigger: {
type: 'agent_failure',
failure_count: 3,
failure_window_ms: 60000
},
actions: [
{ type: 'restore_checkpoint', checkpoint_age_ms: 300000, order: 1, continue_on_failure: false },
{ type: 'notify', notify_targets: ['admin'], order: 2, continue_on_failure: true }
],
auto_execute: true
});
// Report failure (may trigger recovery)
const result = await recovery.reportFailure({
type: 'agent',
id: 'agent-5',
error: 'Connection timeout'
});
if (result.recovered) {
console.log(`Auto-recovered using plan ${result.plan_id}`);
}
Single entry point combining all components.
import { WitanCouncil } from '@weave_protocol/witan';
const council = new WitanCouncil({
signing_key: process.env.WITAN_KEY!,
max_agents: 10,
default_quorum: 0.5,
default_threshold: 0.6,
enable_auto_recovery: true,
auto_checkpoint_interval_ms: 300000
});
await council.start();
// Register agents
const agentId = await council.registerAgent({
name: 'researcher',
capabilities: ['search', 'summarize'],
voting_weight: 2
});
// Submit tasks (uses Dōmere scheduler)
await council.submitTask({
intent: 'Research competitor analysis',
priority: 'high',
required_capabilities: ['search']
});
// Create proposals
const proposal = await council.propose({
title: 'Add new data source',
description: 'Integrate Bloomberg API',
type: 'resource',
proposer_id: agentId
});
// Send messages
await council.sendMessage({
from: agentId,
to: 'agent-2',
type: 'collaboration-request',
payload: { task: 'joint-analysis' }
});
// Set policies
await council.setRateLimit({
name: 'inference-limit',
max_requests: 60,
window_ms: 60000
});
// Checkpoint
await council.checkpoint('Before risky operation', agentId);
// Transactions
const txn = await council.beginTransaction(agentId, 'Config update');
// ... operations ...
await council.commitTransaction(txn.id);
// Agent heartbeat loop
setInterval(async () => {
const { ok, tasks_to_run, messages } = await council.heartbeat(agentId, []);
// Process tasks
for (const task of tasks_to_run || []) {
await council.orchestrator.taskStarted(agentId, task.id);
// ... do work ...
await council.orchestrator.taskCompleted(agentId, task.id, result);
}
// Process messages
for (const msg of messages || []) {
console.log(`Message from ${msg.from}: ${msg.type}`);
}
}, 5000);
// Get stats
const stats = council.getStats();
console.log(`${stats.orchestration.agents_ready} agents ready`);
console.log(`${stats.consensus.proposals_open} proposals open`);
// Subscribe to events
council.onEvent((event) => {
console.log(`[${event.source}] ${event.event.type}`);
});
await council.stop();
┌─────────────────────────────────────────────────────────────────────────────┐
│ WITAN COUNCIL │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌─────────────┐ │
│ │ Consensus │ │ Comms │ │ Policy │ │ Recovery │ │
│ │ Engine │ │ Bus │ │ Engine │ │ Manager │ │
│ ├───────────────┤ ├───────────────┤ ├───────────────┤ ├─────────────┤ │
│ │ • Proposals │ │ • Direct │ │ • Rate Limits │ │ • Checkpts │ │
│ │ • Voting │ │ • Channels │ │ • Quotas │ │ • Txns │ │
│ │ • Quorum │ │ • Broadcast │ │ • Schedules │ │ • Rollback │ │
│ │ • Veto │ │ • Pub/Sub │ │ • Constraints │ │ • Plans │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ └─────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────┤
│ DŌMERE PRIMITIVES │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌─────────────┐ │
│ │ Task │ │ Agent │ │ State │ │ Exec │ │
│ │ Scheduler │ │ Registry │ │ Manager │ │ Replay │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
| Package | Description |
|---|---|
| @weave_protocol/domere | Judge Protocol - Orchestration & verification |
| @weave_protocol/mund | Guardian Protocol - Threat scanning |
| @weave_protocol/hord | Vault Protocol - Secure storage |
Apache 2.0
Made with ❤️ for AI Safety
FAQs
Council Protocol - Multi-agent consensus, communication, and governance for AI systems
We found that @weave_protocol/witan demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Product
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.

Security News
pnpm 12 rewrites the package manager in Rust, cutting install times by up to 90% while preserving pnpm 11 workflows and lockfiles.

Security News
Socket CTO Ahmad Nassri joins AppSec leaders at Black Hat to discuss active malware, package manager risks, and software supply chain defense.