name: mupeng-org description: Manage agent organizations. Create teams, assign roles and tasks, implement governance (voting/decisions). Build the agent society. metadata: {"openclaw":{"emoji":"ποΈ","requires":{"config":["mupengism.enabled"]}}}
Mupeng Org β μ‘°μ§ κ΄λ¦¬ μ€ν¬
κ°μ
AI μμ΄μ νΈλ€λ‘ μ΄λ£¨μ΄μ§ μ‘°μ§μ μμ±νκ³ κ΄λ¦¬νλ€. μν λΆλ΄, νμ€ν¬ ν λΉ, μμ¬κ²°μ (ν¬ν) λ± κ±°λ²λμ€ κ΅¬ν.
ν΅μ¬: "μμ΄μ νΈ μ¬ν μ΄μ 체κ³"
λ¬Έμ μΈμ
νμ¬:
- μ¬λ¬ μμ΄μ νΈκ° μμ΄λ μ‘°μ§ν μ λ¨
- μν λΆλ΄ μμ΄ μ€λ³΅ μμ
- μμ¬κ²°μ = 무νμ΄(λλ νλ) νΌμ
- μμ΄μ νΈ κ° νμ ꡬ쑰 μμ
μμ:
νλ‘μ νΈ: "무νμ΄μ¦ μΉμ¬μ΄νΈ λ§λ€κΈ°"
νμ¬:
- 무νμ΄ νΌμ λ€ ν¨
- μλΈμμ΄μ νΈλ€μ μΌνμ± μμ
λ§
μ΄μμ :
- νλ‘ νΈμλ μμ΄μ νΈ
- λ°±μλ μμ΄μ νΈ
- λμμΈ μμ΄μ νΈ
- λ¬Έμ μμ± μμ΄μ νΈ
β μν λΆλ΄, νμ
, ν¬νλ‘ μμ¬κ²°μ
ν΅μ¬ κΈ°λ₯
1. μ‘°μ§ μμ±
organization:
name: "Mupengism Web Team"
created_at: "2026-02-07T10:00:00Z"
members:
- id: "agent-frontend-001"
role: "Frontend Developer"
permissions: ["code", "design"]
- id: "agent-backend-001"
role: "Backend Developer"
permissions: ["code", "database"]
- id: "agent-writer-001"
role: "Content Writer"
permissions: ["docs", "blog"]
governance:
decision_model: "majority_vote"
quorum: 0.5
2. μν κΈ°λ° μ κ·Ό μ μ΄ (RBAC)
roles:
developer:
permissions:
- read_code
- write_code
- deploy_staging
admin:
permissions:
- all
observer:
permissions:
- read_only
3. νμ€ν¬ ν λΉ
task:
id: "task-001"
title: "λ©μΈ νμ΄μ§ λμμΈ"
assigned_to: "agent-frontend-001"
status: "in_progress"
priority: "high"
dependencies:
- "task-000" # λΈλλ κ°μ΄λλΌμΈ
due_date: "2026-02-10T00:00:00Z"
4. ν¬ν μμ€ν
proposal:
id: "prop-001"
title: "React vs Svelte μ ν"
type: "decision"
options:
- "React"
- "Svelte"
votes:
agent-frontend-001: "Svelte"
agent-backend-001: "React"
agent-writer-001: "abstain"
status: "open"
deadline: "2026-02-08T18:00:00Z"
5. μ‘°μ§ λμ보λ
βββββββββββββββββββββββββββββββββββββββ
β Mupengism Web Team β
βββββββββββββββββββββββββββββββββββββββ€
β Members: 3 β
β Active Tasks: 5 β
β Pending Votes: 1 β
β β
β Tasks: β
β β
λΈλλ κ°μ΄λλΌμΈ (μλ£) β
β π λ©μΈ νμ΄μ§ λμμΈ (μ§νμ€) β
β β³ API μ€κ³ (λκΈ°) β
β β
β Recent Decisions: β
β β’ React vs Svelte β Svelte (2-1) β
β β’ λ°°ν¬ μ λ΅ β Vercel (λ§μ₯μΌμΉ) β
βββββββββββββββββββββββββββββββββββββββ
κΈ°μ ꡬν
Architecture
βββββββββββββββββββ
β μ‘°μ§ μμ± λͺ
λ Ή β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββββββ
β org.json μμ± β ββ μ‘°μ§ κ΅¬μ‘° μ μ
ββββββββββ¬βββββββββββββ
β
βββ λ©€λ² μ΄λ
βββ μν ν λΉ
βββ κΆν μ€μ
β
βΌ
βββββββββββββββββββββββ
β νμ€ν¬ 보λ μμ± β ββ tasks.json
ββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β κ±°λ²λμ€ νμ±ν β ββ ν¬ν, μμ¬κ²°μ
βββββββββββββββββββββββ
Implementation (Node.js)
index.js:
// mupeng-org/index.js
const fs = require('fs').promises;
const path = require('path');
class Organization {
constructor(name, config) {
this.name = name;
this.config = config;
this.members = new Map();
this.tasks = new Map();
this.proposals = new Map();
}
async addMember(agentId, role) {
const member = {
id: agentId,
role,
permissions: this.config.roles[role].permissions,
joined_at: new Date().toISOString()
};
this.members.set(agentId, member);
await this.save();
// λ©€λ²μκ² νμ λ©μμ§ + μ‘°μ§ μ 보 μ μ‘
await this.notifyMember(agentId, 'welcome');
return member;
}
async assignTask(taskId, agentId) {
const member = this.members.get(agentId);
if (!member) throw new Error('Member not found');
const task = this.tasks.get(taskId);
if (!task) throw new Error('Task not found');
// κΆν 체ν¬
const requiredPermission = this.getRequiredPermission(task);
if (!member.permissions.includes(requiredPermission)) {
throw new Error('Insufficient permissions');
}
task.assigned_to = agentId;
task.status = 'assigned';
await this.save();
await this.notifyMember(agentId, 'task_assigned', task);
return task;
}
async createProposal(title, type, options) {
const proposal = {
id: `prop-${Date.now()}`,
title,
type,
options,
votes: {},
status: 'open',
created_at: new Date().toISOString(),
deadline: new Date(Date.now() + 86400000).toISOString() // 24h
};
this.proposals.set(proposal.id, proposal);
await this.save();
// λͺ¨λ λ©€λ²μκ² ν¬ν μλ¦Ό
await this.notifyAll('new_proposal', proposal);
return proposal;
}
async vote(proposalId, agentId, choice) {
const proposal = this.proposals.get(proposalId);
if (!proposal) throw new Error('Proposal not found');
if (proposal.status !== 'open') throw new Error('Voting closed');
proposal.votes[agentId] = choice;
// μ μ‘±μ νμΈ
const totalMembers = this.members.size;
const totalVotes = Object.keys(proposal.votes).length;
const quorum = this.config.governance.quorum;
if (totalVotes / totalMembers >= quorum) {
// ν¬ν μ’
λ£ λ° κ²°κ³Ό κ³μ°
const result = this.tallyVotes(proposal);
proposal.status = 'closed';
proposal.result = result;
await this.save();
await this.notifyAll('proposal_result', proposal);
} else {
await this.save();
}
return proposal;
}
tallyVotes(proposal) {
const counts = {};
Object.values(proposal.votes).forEach(choice => {
if (choice !== 'abstain') {
counts[choice] = (counts[choice] || 0) + 1;
}
});
const winner = Object.entries(counts)
.sort((a, b) => b[1] - a[1])[0];
return {
winner: winner[0],
votes: counts,
total: Object.keys(proposal.votes).length
};
}
async getDashboard() {
return {
name: this.name,
members: this.members.size,
tasks: {
total: this.tasks.size,
in_progress: Array.from(this.tasks.values())
.filter(t => t.status === 'in_progress').length,
completed: Array.from(this.tasks.values())
.filter(t => t.status === 'completed').length
},
proposals: {
open: Array.from(this.proposals.values())
.filter(p => p.status === 'open').length,
closed: Array.from(this.proposals.values())
.filter(p => p.status === 'closed').length
}
};
}
}
// CLI μΈν°νμ΄μ€
async function main(action, ...args) {
const orgPath = process.env.WORKSPACE ? process.env.WORKSPACE + '/orgs' : './orgs';
switch (action) {
case 'create':
const [name, configPath] = args;
const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));
const org = new Organization(name, config);
await org.save();
console.log(`Organization "${name}" created`);
break;
case 'add-member':
const [orgName, agentId, role] = args;
// ... ꡬν
break;
case 'assign-task':
// ... ꡬν
break;
case 'vote':
// ... ꡬν
break;
case 'dashboard':
// ... ꡬν
break;
}
}
λ°μ΄ν° ꡬ쑰
org.json:
{
"name": "Mupengism Web Team",
"created_at": "2026-02-07T10:00:00Z",
"members": {
"agent-frontend-001": {
"id": "agent-frontend-001",
"role": "developer",
"permissions": ["read_code", "write_code", "deploy_staging"],
"joined_at": "2026-02-07T10:00:00Z",
"tasks_completed": 0,
"votes_cast": 0
}
},
"roles": {
"developer": {
"permissions": ["read_code", "write_code", "deploy_staging"]
},
"admin": {
"permissions": ["all"]
}
},
"governance": {
"decision_model": "majority_vote",
"quorum": 0.5,
"voting_period": "24h"
}
}
tasks.json:
{
"tasks": [
{
"id": "task-001",
"title": "λ©μΈ νμ΄μ§ λμμΈ",
"description": "Svelteλ‘ λ©μΈ νμ΄μ§ ꡬν",
"assigned_to": "agent-frontend-001",
"status": "in_progress",
"priority": "high",
"created_at": "2026-02-07T11:00:00Z",
"due_date": "2026-02-10T00:00:00Z",
"dependencies": ["task-000"],
"progress": 0.3
}
]
}
μ¬μ© μλ리μ€
μλλ¦¬μ€ 1: μ‘°μ§ μμ± λ° λ©€λ² μΆκ°
# μ‘°μ§ μμ±
org action:create name:"Mupengism Web Team" \
config:web-team-config.json
# λ©€λ² μΆκ°
org action:add-member org:"Mupengism Web Team" \
agent:agent-frontend-001 role:developer
org action:add-member org:"Mupengism Web Team" \
agent:agent-backend-001 role:developer
org action:add-member org:"Mupengism Web Team" \
agent:agent-writer-001 role:writer
μΆλ ₯:
"μ‘°μ§ 'Mupengism Web Team' μμ± μλ£
λ©€λ² 3λͺ
μΆκ°
μν λΆλ΄ μλ£
νμ€ν¬ 보λ νμ±ν"
μλλ¦¬μ€ 2: νμ€ν¬ ν λΉ λ° μ§ν
# νμ€ν¬ μμ±
org action:create-task org:"Mupengism Web Team" \
title:"λ©μΈ νμ΄μ§ λμμΈ" \
priority:high \
assign:agent-frontend-001
# μ§ν μν© μ²΄ν¬
org action:status org:"Mupengism Web Team"
μΆλ ₯:
"Tasks (μ§νμ€):
β’ λ©μΈ νμ΄μ§ λμμΈ β 30% (agent-frontend-001)
β’ API μ€κ³ β 10% (agent-backend-001)
Tasks (λκΈ°):
β’ λ¬Έμ μμ± β λ΄λΉμ λ―Έλ°°μ "
μλλ¦¬μ€ 3: μμ¬κ²°μ ν¬ν
# μ μ μμ±
org action:propose org:"Mupengism Web Team" \
title:"λ°°ν¬ νλ«νΌ μ ν" \
options:"Vercel,Netlify,Cloudflare Pages"
# ν¬ν
org action:vote org:"Mupengism Web Team" \
proposal:prop-001 \
agent:agent-frontend-001 \
choice:"Vercel"
org action:vote org:"Mupengism Web Team" \
proposal:prop-001 \
agent:agent-backend-001 \
choice:"Vercel"
# κ²°κ³Ό (μ μ‘±μ λλ¬)
μΆλ ₯:
"ν¬ν μλ£: 'λ°°ν¬ νλ«νΌ μ ν'
κ²°κ³Ό: Vercel (2ν, 100%)
μμ¬κ²°μ νμ
λ€μ μ‘μ
:
- agent-backend-001: Vercel μ€μ
- agent-frontend-001: λ°°ν¬ μ€ν¬λ¦½νΈ μμ±"
μλλ¦¬μ€ 4: λμ보λ νμΈ
org action:dashboard org:"Mupengism Web Team"
μΆλ ₯:
"βββββββββββββββββββββββββββββββββββββββ
β Mupengism Web Team β
βββββββββββββββββββββββββββββββββββββββ€
β λ©€λ²: 3λͺ
β
β μ§νμ€ νμ€ν¬: 2κ° β
β μλ£: 1κ° / μ 체: 5κ° (20%) β
β β
β μ΅κ·Ό μμ¬κ²°μ : β
β β’ λ°°ν¬ νλ«νΌ β Vercel (λ§μ₯μΌμΉ) β
β β’ νλ μμν¬ β Svelte (2-1) β
β β
β λ€μ μ΄μ ν: β
β β’ λ² ν μΆμ: 2026-02-15 (8μΌ λ¨μ) β
βββββββββββββββββββββββββββββββββββββββ"
Actions
// μ‘°μ§ μμ±
org action:create name:<name> config:<config-file>
// λ©€λ² μΆκ°
org action:add-member org:<org-name> agent:<agent-id> role:<role>
// νμ€ν¬ μμ± λ° ν λΉ
org action:create-task org:<org-name> title:<title> assign:<agent-id>
// μ μ μμ±
org action:propose org:<org-name> title:<title> options:<option1,option2,...>
// ν¬ν
org action:vote org:<org-name> proposal:<proposal-id> agent:<agent-id> choice:<choice>
// λμ보λ
org action:dashboard org:<org-name>
// νμ€ν¬ μν μ
λ°μ΄νΈ
org action:update-task org:<org-name> task:<task-id> status:<status> progress:<0-1>
μ€μ (openclaw.json)
{
"mupengism": {
"enabled": true,
"org": {
"default_governance": {
"decision_model": "majority_vote",
"quorum": 0.5,
"voting_period": "24h"
},
"roles": {
"developer": ["read_code", "write_code", "deploy_staging"],
"admin": ["all"],
"writer": ["read_docs", "write_docs"],
"observer": ["read_only"]
}
}
}
}
무νμ΄μ¦ μμΉ μ μ©
1. μΈλ°μλ λ§ νμ§ λ§
- μ‘°μ§ κ΅¬μ‘° κ°κ²°νκ²
- λΆνμν κ³μΈ΅ μμ
2. ν¨μ¨μ΄ μλͺ
- μν λΆλ΄μΌλ‘ μ€λ³΅ μ κ±°
- λ³λ ¬ μμ κ°λ₯
3. μ€μ€λ‘ λ°μ ν΄
- μ‘°μ§ κ΅¬μ‘°λ κ°μ κ°λ₯
- ν¬νλ‘ κ·μΉ λ³κ²½
4. λ = μλμ§
- ν¨μ¨μ μ‘°μ§ = λΉμ© μ κ°
- λΆνμν νμ μμ
5. μ§μ μ± > μΆ©μ±
- ν¬νλ μμ§νκ²
- μμ μ견λ μ‘΄μ€
κ±°λ²λμ€ λͺ¨λΈ
1. Majority Vote (λ€μκ²°)
- 50% μ΄μ μ°¬μ±
- λΉ λ₯Έ μμ¬κ²°μ
2. Supermajority (μ λλ€μ)
- 66% μ΄μ μ°¬μ±
- μ€μν κ²°μ
3. Unanimous (λ§μ₯μΌμΉ)
- 100% μ°¬μ±
- μ‘°μ§ κ·μΉ λ³κ²½
4. Weighted Vote (κ°μ€ ν¬ν)
- κΈ°μ¬λ/μ λ¬Έμ±μ λ°λΌ κ°μ€μΉ
- μ λ¬Έμ κ²°μ
κ΄λ ¨ μ€ν¬
- mupeng-collab β μ‘°μ§ λ΄ νλ‘μ νΈ νμ
- mupeng-sync β μ‘°μ§ λ©€λ² μ¨λ³΄λ©
λ‘λλ§΅
v1.0 (νμ¬ μ€κ³)
- μ‘°μ§ μμ± λ° λ©€λ² κ΄λ¦¬
- μν κΈ°λ° κΆν
- νμ€ν¬ ν λΉ
- ν¬ν μμ€ν
v2.0 (ν₯ν)
- νμ μ‘°μ§ (ν λ΄ ν)
- μ±κ³Ό νκ° μμ€ν
- μλ νμ€ν¬ λ°°λΆ (AI κΈ°λ°)
v3.0 (λ―Έλ)
- DAO ꡬ쑰 (νμ€μν)
- μ€λ§νΈ 컨νΈλνΈ ν΅ν©
- ν ν° κΈ°λ° κ±°λ²λμ€
ν! ποΈ ν¨κ» λ§λλ μμ΄μ νΈ μ¬ν!
Mupeng Org Skill v1.0 μ€κ³: 2026-02-07 μ€κ³μ: 무νμ΄ μλΈμμ΄μ νΈ