Governance & validation
Sovereign Mesh Explore a distributed coordination scenario and its application/server boundary.
Code & guide What to expect This directory includes code and documentation. Its guide defines dependencies, execution modes and what the results demonstrate.
Guides & runbooks 1
Registered commands 0 Environment setup ↗ Guided tour Inspect the sources Try it locally Architecture Complete library
A CLOSER LOOK
How does a multi-hub interface cross the API and chain boundary? For application architects: inspect hub configuration, commit construction and the mesh server before assembling a provider-connected deployment.
01 02 Follow commit construction Trace how the client prepares its validation commitment. Confirm the expected encoding and network before using it with real contracts.
demo/sovereign-mesh/app/src/lib/commit.ts ↗ Inspect this source ↓ 03 Inspect the server boundary Read the API implementation, contract dependencies and environment requirements. The app and server have separate packages and setup steps.
demo/sovereign-mesh/server/index.ts ↗ Inspect this source ↓
REAL REPOSITORY MATERIAL
Inspect. Understand. Reproduce. Reading the exact source at revision 5b4cebb3. This browser inspection does not execute the demo.
demo/sovereign-mesh/config/mesh.ui.config.json
Select a walkthrough step to explore its source.
Show more fields ↓ Full source text {
"network": "mainnet",
"etherscanBase": "https://etherscan.io",
"defaultSubgraphUrl": "https://api.thegraph.com/subgraphs/name/agi/jobs-v2",
"orchestratorBase": "http://localhost:8084",
"hubs": [
"public-research",
"industrial-ops",
"civic-governance"
]
}
SHA-256 d2db779715963b5846493a11f7b5808822b0340a639775596f066128dfaeeef0
The first source is shown in full. All walkthrough source links and the complete document library remain available without JavaScript.
{"revision":"5b4cebb309a83a7a6749d8911d8bf96a1921e042","sources":[{"file":"demo/sovereign-mesh/config/mesh.ui.config.json","content":"{\n \"network\": \"mainnet\",\n \"etherscanBase\": \"https://etherscan.io\",\n \"defaultSubgraphUrl\": \"https://api.thegraph.com/subgraphs/name/agi/jobs-v2\",\n \"orchestratorBase\": \"http://localhost:8084\",\n \"hubs\": [\n \"public-research\",\n \"industrial-ops\",\n \"civic-governance\"\n ]\n}\n","format":"json","sha256":"d2db779715963b5846493a11f7b5808822b0340a639775596f066128dfaeeef0","bytes":281,"download":"/AGIJobsv0/examples/d2db779715963b58-mesh.ui.config.json","source":"https://github.com/MontrealAI/AGIJobsv0/blob/5b4cebb309a83a7a6749d8911d8bf96a1921e042/demo/sovereign-mesh/config/mesh.ui.config.json"},{"file":"demo/sovereign-mesh/app/src/lib/commit.ts","content":"import { ethers } from \"ethers\";\n\nexport const computeCommit = (approve: boolean, salt?: string) => {\n const s = salt && salt.startsWith(\"0x\") ? salt : ethers.hexlify(ethers.randomBytes(32));\n const commitHash = ethers.keccak256(\n ethers.solidityPacked([\"bool\", \"bytes32\"], [!!approve, s])\n );\n return { commitHash, salt: s };\n};\n","format":"text","sha256":"2fc62677d2390497423a6039b34d10ca3a441d1cfcdaeb74e680d49a63265063","bytes":337,"download":"/AGIJobsv0/examples/2fc62677d2390497-commit.ts","source":"https://github.com/MontrealAI/AGIJobsv0/blob/5b4cebb309a83a7a6749d8911d8bf96a1921e042/demo/sovereign-mesh/app/src/lib/commit.ts"},{"file":"demo/sovereign-mesh/server/index.ts","content":"import express from \"express\";\nimport { readFileSync } from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { ethers } from \"ethers\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\nconst root = path.join(__dirname, \"..\");\n\nfunction loadJson<T = unknown>(rel: string): T {\n const file = path.join(root, rel);\n return JSON.parse(readFileSync(file, \"utf8\")) as T;\n}\n\nconst meshCfg = loadJson(\"config/mesh.ui.config.json\");\nconst hubs = loadJson<Record<string, any>>(\"config/hubs.mainnet.json\");\nconst playbooks = loadJson<any[]>(\"config/playbooks.json\");\nconst actors = loadJson<any[]>(\"config/actors.json\");\n\nconst jobAbi = [\n \"function createJob(uint256 reward, uint64 deadline, bytes32 specHash, string uri) returns (uint256)\"\n];\nconst stakeAbi = [\"function depositStake(uint8 role, uint256 amount)\"];\nconst validationAbi = [\n \"function commitValidation(uint256 jobId, bytes32 hash, string subdomain, bytes32[] proof)\",\n \"function revealValidation(uint256 jobId, bool approve, bytes32 salt)\",\n \"function finalize(uint256 jobId)\"\n];\nconst disputeAbi = [\"function raiseDispute(uint256 jobId, string evidence)\"];\nconst identityAbi = [\n \"function addAdditionalAgent(address)\",\n \"function addAdditionalValidator(address)\"\n];\n\nconst iface = (abi: string[]) => new ethers.Interface(abi);\nconst encode = (abi: string[], fn: string, args: any[]) => iface(abi).encodeFunctionData(fn, args);\n\nfunction getHub(id: string) {\n const hub = hubs[id];\n if (!hub) {\n throw new Error(`Unknown hub: ${id}`);\n }\n return hub;\n}\n\nconst app = express();\napp.use(express.json());\n\napp.get(\"/mesh/config\", (_req, res) => res.json(meshCfg));\napp.get(\"/mesh/hubs\", (_req, res) => res.json({ hubs }));\napp.get(\"/mesh/playbooks\", (_req, res) => res.json(playbooks));\napp.get(\"/mesh/actors\", (_req, res) => res.json(actors));\n\napp.post(\"/mesh/:hub/tx/create\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { rewardWei, uri } = req.body ?? {};\n if (!rewardWei) {\n return res.status(400).json({ error: \"rewardWei is required\" });\n }\n if (!uri) {\n return res.status(400).json({ error: \"uri is required\" });\n }\n const nowSec = Math.floor(Date.now() / 1000);\n const defaultDeadline = nowSec + 7 * 24 * 3600;\n const specHash = ethers.keccak256(ethers.toUtf8Bytes(uri));\n const tx = {\n to: hub.addresses.JobRegistry,\n data: encode(jobAbi, \"createJob\", [rewardWei, defaultDeadline, specHash, uri]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/:hub/tx/stake\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { role, amountWei } = req.body ?? {};\n if (role === undefined || amountWei === undefined) {\n return res.status(400).json({ error: \"role and amountWei are required\" });\n }\n const tx = {\n to: hub.addresses.StakeManager,\n data: encode(stakeAbi, \"depositStake\", [role, amountWei]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/:hub/tx/commit\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { jobId, commitHash, subdomain, proof } = req.body ?? {};\n if (jobId === undefined || !commitHash) {\n return res.status(400).json({ error: \"jobId and commitHash are required\" });\n }\n const tx = {\n to: hub.addresses.ValidationModule,\n data: encode(validationAbi, \"commitValidation\", [\n jobId,\n commitHash,\n subdomain ?? \"validator\",\n proof ?? []\n ]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/:hub/tx/reveal\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { jobId, approve, salt } = req.body ?? {};\n if (jobId === undefined || salt === undefined) {\n return res.status(400).json({ error: \"jobId and salt are required\" });\n }\n const tx = {\n to: hub.addresses.ValidationModule,\n data: encode(validationAbi, \"revealValidation\", [jobId, !!approve, salt]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/:hub/tx/finalize\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { jobId } = req.body ?? {};\n if (jobId === undefined) {\n return res.status(400).json({ error: \"jobId is required\" });\n }\n const tx = {\n to: hub.addresses.ValidationModule,\n data: encode(validationAbi, \"finalize\", [jobId]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/:hub/tx/dispute\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { jobId, evidence } = req.body ?? {};\n if (jobId === undefined) {\n return res.status(400).json({ error: \"jobId is required\" });\n }\n const tx = {\n to: hub.addresses.JobRegistry,\n data: encode(disputeAbi, \"raiseDispute\", [jobId, evidence ?? \"\"]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/:hub/tx/allowlist\", (req, res) => {\n const hub = getHub(req.params.hub);\n const { role, addr } = req.body ?? {};\n if (role === undefined || !addr) {\n return res.status(400).json({ error: \"role and addr are required\" });\n }\n const fn = Number(role) === 0 ? \"addAdditionalAgent\" : \"addAdditionalValidator\";\n const tx = {\n to: hub.addresses.IdentityRegistry,\n data: encode(identityAbi, fn, [addr]),\n value: 0\n };\n return res.json({ tx });\n});\n\napp.post(\"/mesh/plan/instantiate\", (req, res) => {\n const { playbookId } = req.body ?? {};\n if (!playbookId) {\n return res.status(400).json({ error: \"playbookId is required\" });\n }\n const pb = playbooks.find((p) => p.id === playbookId);\n if (!pb) {\n return res.status(404).json({ error: \"Unknown playbook\" });\n }\n const now = Math.floor(Date.now() / 1000);\n const txs = pb.steps.map((step: any) => {\n const [, hubId] = String(step.hub).split(\"@\");\n if (!hubId) {\n throw new Error(`Invalid hub step: ${step.hub}`);\n }\n const hub = getHub(hubId);\n const deadline = now + 7 * 24 * 3600;\n const uri = step.uri ?? \"\";\n const specHash = ethers.keccak256(ethers.toUtf8Bytes(uri));\n return {\n hub: hubId,\n to: hub.addresses.JobRegistry,\n data: encode(jobAbi, \"createJob\", [step.rewardWei, deadline, specHash, uri]),\n value: 0\n };\n });\n return res.json({ txs });\n});\n\nconst PORT = process.env.SOVEREIGN_MESH_PORT ? Number(process.env.SOVEREIGN_MESH_PORT) : 8084;\napp.listen(PORT, () => {\n console.log(`[Sovereign Mesh] server listening on port ${PORT}`);\n});\n","format":"text","sha256":"ddc2414746480d8e447008dbb8257f84678f09d96a9cd3b8b32ed1c131125cc8","bytes":6334,"download":"/AGIJobsv0/examples/ddc2414746480d8e-index.ts","source":"https://github.com/MontrealAI/AGIJobsv0/blob/5b4cebb309a83a7a6749d8911d8bf96a1921e042/demo/sovereign-mesh/server/index.ts"}]}
FROM READING TO A REPRODUCIBLE RUN
Try the selected path. Node.js workspace Run from the repository root after nvm install, nvm use and npm ci. Use the versions pinned in .nvmrc and package.json. Commands below describe the selected path; optional app/server packages can have their own locked dependencies.
Complete environment setup ↗ SELECTED EXECUTION PATH Copy
npm --prefix demo/sovereign-mesh/server ci
npm --prefix demo/sovereign-mesh/server run build
npm --prefix demo/sovereign-mesh/app ci
npm --prefix demo/sovereign-mesh/app run buildWhat you should observe Both packages install their locked dependencies and compile. A successful build does not launch or commission a mesh; follow the component configuration and deployment scripts before starting services.
The source inspector above reads bundled repository material. Local commands run separately on your computer. Recorded examples may contain historical timestamps, placeholders and simulated metrics.
MAKE IT YOUR OWN
One useful experiment. Trace one UI action through the API to the expected contract operation. List the concrete addresses and provider evidence required to execute it.
THE SYSTEM, MADE VISIBLE
Architecture & relationships Architecture diagram · source preserved below
View original Mermaid source flowchart LR
Operators((Mission Owners)) --> demo_sovereign_mesh[[Demo → Sovereign Mesh]]
demo_sovereign_mesh --> Core[[AGI Jobs v0 (v2) Core Intelligence]]
Core --> Observability[[Unified CI / CD & Observability]]
Core --> Governance[[Owner Control Plane]]
WHEN SOMETHING DOESN’T MATCH
Troubleshooting A command or service fails Start at the first error, confirm the working directory and pinned toolchain, then follow the linked component guide. Optional packages and provider services have separate prerequisites.
A report looks successful but lacks evidence Check its source revision, configuration, timestamps and underlying events. Historical fixtures and generated plans do not prove a fresh execution.
TRACE THE CHECKS
Verification & next steps 1 tracked test source files are available in this directory. Inspect the tests and their environment before choosing a suite; file counts do not establish test results.
Browse the test sources For live commissioning, consult the production readiness record .
EVERY VARIANT, PRESERVED
Complete document library REPRODUCE & INSPECT
Registered commands Run commands from the repository root after following this demo's guide. Network and owner actions require their documented setup.
No root-level launch command is associated with this source path. Follow the guide or source directory for its own entry point.
Full command catalog and troubleshooting ↗