Platform Features
Foundation includes several major platform capabilities beyond the core identity and voting system.
0. The Three Pillars
Foundation ships three governance pillars on top of one shared identity and on-chain layer. Each pillar is a separate Anchor program on Solana devnet, but they present a consistent UX: a unified card grid, primary Vote / Support actions, green Voted / Supported badges once a member has acted, and inline confirmation (the result renders in place on the card — there is no modal popup).
Your Voice — Pillar 1 (governance)
Members propose and vote on community proposals.
- Collection:
proposals - Lifecycle:
round0(gather support) →active(voting open) →closed/passed/rejected. (Round-0 proposals can also bediscardedby an admin.) - Actions:
castProposalSupport(Support, during round0) andcastProposalVote(Vote, while active). - On-chain program:
pillar1-governanceat8HfCAdu1UQAEmSN7LwXEwrpUTZycidM5BdeHsT9YbeK8.
Your Share — Pillar 2 (community fund allocation / participatory budgeting)
Members decide how a community pool is allocated.
- Collections:
allocations(withallocation_votesandallocation_signatures). - Lifecycle:
round0→active→closed. - Actions:
createAllocation,castAllocationSupport(Support),castAllocationVote(Vote), and adminadminUpdateAllocationStatus. - Crowd-sourced funding options (new):
submitAllocationOptionlets applicants submit candidate funding options (grant proposals) into around0/draftallocation. The option set stays open while in round0; once an admin activates the allocation, options freeze and members vote among the submitted candidates — a crowd-sourced ballot. Capped at the on-chain limit of 10 options, one submission per caller, deduped by label. - On-chain twin: mints on activation (
round0 → active), since the option set must be final at mint time. Round0 stays open for submissions until then. - On-chain program:
pillar2-shareatHGfJ1JR8FM5tpE4GBjc48mVXeVXGYiLyVMVe2QeVSyWJ.
Your Market — Pillar 3 (collective purchasing)
Members pool demand for a product and pick a supplier together.
- Collection:
product_requests(supplier bids are embedded as abids[]array; member votes live inproduct_votes). - Lifecycle:
gathering→bidding→voting→ordered→delivered. - Supplier bids (new):
submitProductBidlets suppliers submit competing bids. The first bid — only once the community demand threshold is met — opens thebiddingphase. Members then vote among suppliers viacastProductVote(supplier selection). Capped at 10 bids per product, one bid per caller, deduped by supplier name. - On-chain program:
pillar3-marketat75nVM4vN8EvnxwxZyvVbPgtTGjLkQtS2V5ti8ohNYcCB.
Cross-cutting: populations
Voters carry a populations array used for eligibility scoping across all pillars:
- UN-M49 nationality via
setMyNationality - H3 geospatial location via
setMyLocation - On-chain program:
identity-registryatEgWb3fdVLp7Qon3p1UEAA3iwrbCGu4ro56MY7hrBFaoV.
1. Admin Testing Panel
An interactive developer tool for exercising all 25 Cloud Function callables plus Firestore inspection.
Capabilities
- Callable browser: Browse callables grouped by domain (Governance, PoH, AI, Messaging, Auth, Legal). Each shows expected payload shape, auth requirements, and return type.
- Request builder: Invoke any callable with a custom JSON payload, view formatted response with timing.
- Firestore stats: Live counts of each collection, document sampling, schema-validator integration via
@plantagoai/db. - Seed runners: Demo data seeders and reset flows for dev/test populations.
Access
Admin Panel → Testing tab (requires ring ≤ 1).
Tech Stack
- React components with recharts for visualization
- Firebase
httpsCallableclient, App Check attached automatically - Request timing and status tracking
2. Governance State Machine (XState v5)
Replaces hardcoded proposal lifecycle logic with per-proposal XState v5 state machines. Communities can customize governance flows.
State Flow
Round 0 (gathering support)
→ SUPPORT events increment supportCount
→ SUPPORT_THRESHOLD_MET triggers transition to Active
Active (voting open)
→ VOTING_ENDED triggers transition based on results
→ ADMIN_DISCARD transitions to Discarded
Terminal states: Passed, Rejected, Discarded, Closed
Architecture
- proposalMachine.ts: Core XState v5 machine definition with states, events, guards, and actions
- machineFactory.ts: Factory function
createGovernanceMachine(config)builds community-customizable machines - machinePersistence.ts: Firestore persistence using
getPersistedSnapshot()/createActor({ snapshot }) - useProposalMachine.ts: React hook providing
{ state, send, canSupport, canVote, timeRemaining }
Community Configuration
Each community can define:
- Number and type of rounds
- Support thresholds per round
- Voting durations
- Custom guard conditions
Default configuration produces the standard Round 0 → Active → Result flow.
3. AI Constitutional Review
Communities define constitutional principles. Proposals are evaluated by Claude AI against those principles before submission.
Design Principles
- Advisory, not censorship: AI flags concerns but never blocks submission
- Transparency: AI reasoning is visible to all community members
- Community-defined: Each community writes its own constitution
- Appeals via democracy: Flagged proposals can still gain support and pass
Constitution Structure
- Preamble: Community mission statement
- Principles: Each has a title, description, category, and weight
- Categories:
rights,governance,ethics,procedural - Weights:
core,important,advisory
- Categories:
- 12 default principles provided as a starting template
AI Evaluation
- Powered by Claude (claude-sonnet-4-20250514) via Firebase Cloud Functions
- Returns: overall score (0-100), status (compliant/concern/violation), list of violations with severity and suggested edits
- Results cached by proposal text hash
- Evaluation displayed in proposal submission flow and proposal detail view
- Warning badges shown on proposal cards for flagged proposals
Admin
Navigate to /admin/constitution to manage community principles.
Tech Stack
- Anthropic Claude API (
@anthropic-ai/sdk) - Firebase Cloud Functions v2 (
onCall) - Firestore for constitution storage
- React components for evaluation display
4. Soulbound Attestations
Non-transferable on-chain proofs of participation — minted to a wallet's Solana account and permanently linked to it. Cannot be transferred or burned by the holder; revocation requires the original issuing keypair.
Attestation Types
| Type | Value | Context Hash | Issued When |
|---|---|---|---|
VERIFIED_HUMAN |
0 | 32 zero bytes | Passport/humanity verification completes |
VOTED |
1 | Twin PDA pubkey | A vote is mirrored on-chain |
SUPPORTED_PROPOSAL |
2 | Twin PDA pubkey | A support signature is mirrored on-chain |
VOTED and SUPPORTED_PROPOSAL are issued across all three pillars — a Your Voice proposal vote, a Your Share allocation vote, and a Your Market supplier vote all enqueue the same attestation types (the context hash is the relevant pillar's on-chain twin PDA). Issuance is non-fatal: a failed attestation enqueue never blocks the underlying vote/support write.
Architecture
- On-chain program: Anchor program at
GQrFse7NiB6QdqtagGayNYwrr8zn4W4uWhji57VkKGky(Solana devnet) - PDA seeds:
[b"attestation", holder_pubkey, attestation_type, context_hash]— uniquely identifies each attestation - Cloud Functions:
issueAttestation,queryAttestations,revokeAttestationcallables;enqueueIssueAttestationtask queue handler - Auto-issue: every qualifying on-chain event (vote confirmed, support mirrored) enqueues an attestation automatically via
on-chain-queue.js - Firestore mirror:
attestationssub-collection under each voter document; synced after on-chain confirmation
Soulbound Property
PDAs are created with no lamport transfer capability and the holder cannot sign for the account — only the program (via PDA authority) can modify state. Revocation is restricted to the original issuing keypair.
5. GaaS PoH API (Governance-as-a-Service)
Third-party governance platforms can verify a wallet's humanity attestations via a simple REST API — the first live revenue surface for Foundation's Proof-of-Humanity infrastructure.
Endpoint
GET https://us-east1-solanavote-devnet.cloudfunctions.net/pohAttestationsEndpoint?wallet=<base58>
X-PoH-API-Key: your_key_here
Response
{
"wallet": "4ZiTV3a...",
"attestations": [...],
"count": 1,
"hasVerifiedHuman": true
}
hasVerifiedHuman: true is the single signal external systems need for humanity gating.
Auth & Key Management
- API keys stored as SHA-256 hashes in
poh_api_keysFirestore collection withactive: true - Keys provisioned manually; plain-text shown only once at provisioning time
X-PoH-API-Keyheader required on every request
Integration Pattern
const res = await fetch(
`https://us-east1-solanavote-devnet.cloudfunctions.net/pohAttestationsEndpoint?wallet=${wallet}`,
{ headers: { "X-PoH-API-Key": apiKey } }
);
const { hasVerifiedHuman } = await res.json();
if (!hasVerifiedHuman) return res.status(403).json({ error: "Humanity verification required" });
See docs/poh-api-guide.md for full reference.
6. Outreach Deal-Rooms + Preview Workspaces
Prospective partners get a personalized, unguessable kit microsite at /r/:token (the "deal-room") with per-contact engagement attribution — every view, video milestone, and download is recorded against the contact.
From the deal-room, an email-OTP gate opens a preview workspace: a lazily created, fully seeded tenant where the contact lands as a signed-in preview member (custom-token hand-off via URL fragment #wt=, never sent on the wire). Everything works — proposals, support, voting, allocations, supplier bids — with no setup.
Preview Identity experience
Preview members see a dedicated Identity tab instead of the enrollment flow:
- Preview-access card — explains that full Proof-of-Personhood is deferred: members verify with Foundation Mobile when the workspace goes live.
- Soulbound attestations panel — voting and support badges accrue live as the preview member participates (the Verified Human badge stays locked until real PoH).
- PoH Verifier (preview-labelled) — the same verifier surface a third-party platform calls, demonstrating the GaaS API against the member's own wallet.
Key surfaces
functions/outreach.js— targets/contacts/links model, OTP flow, lazy tenant creation + server-side seeding (seedTenantData), custom-token minting with tenant-scoped preview claims.- Admin Outreach tab — manage targets, contacts, and deal-room links; engagement analytics.
kit-site— the standalone deal-room app (deploys manually tofoundation-global-kit, not in CI).