Repository navigation
Code map
A guided tour of where things live. Read it alongside How the Hub works — this is the same architecture, viewed from the filesystem.
src/ the application — Next.js routes, Payload collections, endpoints,
member interface, domain modules
mcp-content/ the independent content MCP service — HTTP + stdio, its own process
scripts/ seed, CI, agent and operational entry points
tests/ vitest integration specs + playwright e2e
src/collections/ Payload collections — the schema of every table
src/endpoints/ REST handlers, one file per domain
src/lib/ the engine room — access, authority, notifications, views
src/modules/ larger domains that outgrew lib/: platform, negotiation
src/db/migrations/ versioned schema migrations — structure only, never data
src/member/ the member interface — pages, components, session, guards
src/shared/ modules shared with mcp-content — plain .js
src/app/ App Router routes — member UI in (site)/(member),
Payload API under (payload)
The files that matter most, in the order a newcomer should read them:
| File | What it is |
|---|---|
src/lib/authority.ts |
The role registry + deriveAuthority — the controlled vocabulary for authority_records, with policy citations per role |
src/lib/access.ts |
The access engine — turns authority rows into the AccessProfile every check uses |
src/lib/authorityService.ts |
The only write path for records — grant, end, revoke, with locking |
src/lib/authorityLock.ts |
Advisory-lock ordering that makes concurrent writes safe |
src/lib/collectionAccess.ts |
The collection-level guards Payload hooks call |
src/lib/decisionRuntime.ts |
Decision transitions, ballots, the Council electorate |
src/payload.config.ts |
Which collections and endpoints exist, DB adapter, plugins |
-
platform/— the body/Council surface: decisions platform bridge, overview, tasks, enquiries, members' records. -
negotiation/— UNFCCC track workspaces: documents, versions, extraction review, contribution projects, follow tracking.
One file per domain, ~200 endpoints total. The naming is regular enough to navigate blind: /api/decisions/* for the decision pipeline, /api/member/team/* for staff workflows, /api/governance/* for elections and selections, /api/negotiations/* for track work, /api/intelligence/* for the query adapters, /api/push/* and /api/notifications/* for delivery. API reference walks the conventions.
src/member/pages/ route components — workspaces, decisions, elections, profile
src/member/components/ shared views — Shell, AccessGate, MemberGate, ui kit
src/member/lib/ session, guards, the router bridge, data access (swr)
src/shared/ modules shared with mcp-content — opportunities,
protocol, platform constants
Every member URL is a real App Router route under src/app/(site)/(member) — thin page wrappers over these components. The layout applies the gate chain (AccessGate → AccountProvider → MemberGate → Shell), and lockedFor() in member/lib/guards is the single source for route guards.
src/shared/ deserves a note: mcp-content imports it under plain node, so its files must stay .js and Node-safe — no process.env, no Node-only APIs, no TypeScript syntax. Breaking that rule fails the MCP smoke test, not the web build.
server.mjs HTTP service — /mcp JSON-RPC, /healthz, bearer-token auth
lib/mcpServer.mjs one shared server factory used by both transports
lib/client.mjs the Hub HTTP API client the tools call
lib/memory.mjs proxies the shared memory bank's tools into the stdio server
scripts/agent/hub-mcp.mjs the unified stdio transport — content + memory (in root scripts/)
scripts/agent/sync-mcp.mjs renders local agent MCP configs from env — the only place that wiring is defined
The MCP is a client of the Hub, not a part of it — it holds HUB_TOKEN (or email/password) and calls the same endpoints members do. It is never given DATABASE_URL. Agent tools covers it.
-
"Why can/can't X do Y?" →
src/lib/access.ts→src/lib/authority.ts→ theirauthority_recordsrows. -
"How does the decision move?" →
src/lib/decisionRuntime.ts+src/endpoints/decisions.ts. -
"Where's the migration that built this table?" →
src/db/migrations/— named by timestamp, applied in order. -
"What can an agent touch?" →
mcp-content/lib/mcpServer.mjstool list, then the endpoint it calls.