Skip to main content

Persona Surfaces Matrix

A single-page reference: which view in which package serves which canonical persona. Use this to orient before changing a feature on a journey — a persona's surface is the canvas you have to fit your change into.

Canonical personas (from v1.0 spec § 3.1)

IDNameOne-line role
AGardenerPerforms regenerative work; submits via PWA or agent
BOperatorCoordinates the garden; reviews work; mints hypercerts
CEvaluatorHat-holder who attests assessments; gated by HatsModule.isEvaluator
DFunderDeposits into vaults / cookie jars; receives Karma GAP linkage
ECommunity MemberLocal resident; signals priorities via conviction

Public browser routes (canonical)

There are exactly four public route families in packages/client/src/router.config.tsx (plus /landing as a legacy redirect). The Garden family includes its detail path. Installed PWA app routes are scoped separately under /home: /home, /home/login, /home/garden, /home/profile, and garden detail routes under /home/:id. The old /login, /garden, and /profile paths exist only as PWA-mode compatibility redirects.

  • /gardensviews/Public/Gardens.tsx
  • /gardens/:idviews/Public/GardenDetail.tsx
  • /impactviews/Public/Impact.tsx
  • /fundviews/Public/Fund.tsx
  • /actionsviews/Public/Actions.tsx

Use canonical Green Goods domain vocabulary throughout: Garden, Action, Work, Vault, Cookie Jar, Hypercert, Assessment, Attestation, Hat, Season.

Matrix

PersonaPrimary surfacePackage / view pathSecondary surfacesKey hooks / services
A: GardenerClient PWA /home + /home/garden submit wizardpackages/client/src/views/Home/index.tsx, packages/client/src/views/Garden/index.tsxPublic /gardens browse (read-only), Telegram agent (packages/agent/src/handlers/{start,join,submit}.ts), /home/profile (packages/client/src/views/Profile/)useAuth, useGardener, useGardens, useWorkMutation, useDraftAutoSave, useDraftResume, useOffline, job queue (packages/shared/src/modules/job-queue/)
B: OperatorAdmin Hub workspacepackages/admin/src/views/Hub/index.tsx (stages: work, assess, certify, history)Garden workspace (Garden/index.tsx, tabs: overview, impact, settings), Community workspace (Community/index.tsx, tabs: treasury, governance, payouts, members), Actions workspace (Actions/index.tsx), Profile, Telegram agent (handlers/{approve,reject,pending}.ts)useHubWorkbenchController, useGardens, useGardenOperations, useWorkApproval, useBatchWorkApproval, useCreateAssessmentWorkflow, useCreateHypercertWorkflow, useEffectiveToolbarPermissions
C: EvaluatorAdmin Garden workspace + Hub Assess/Certify, role-permissioned (no dedicated workspace)Same Garden / Hub views as Operator; visibility gated by garden.evaluators[] and useHasRole("evaluator")None — the surface is the same; the difference is the on-chain hat membership at attestation timeuseHasRole, useEffectiveToolbarPermissions (inEvaluators slot), useCreateAssessmentWorkflow (the same hook the operator uses; the resolver is the gate)
D: FunderPublic browser /fund page + Admin Garden Vault tabpackages/client/src/views/Public/Fund.tsx, packages/admin/src/views/Garden/Vault.tsxAdmin Hub Cookie Jar modals (Hub/components/CookieJarDepositModal.tsx, CookieJarManageModal.tsx, CookieJarPayoutPanel.tsx, CookieJarWithdrawModal.tsx), Admin Community Payouts (Community/index.tsx mode payouts), Public /impact (read-only)useAppKit, useGardens, useUser, useVaultDeposit, useVaultWithdraw, useVaultOperations, useFunderLeaderboard, useCookieJarDeposit, useCookieJarWithdraw
E: Community MemberPublic browser /gardens + /impact (read) + Admin Community Governance/Strategies (write, when role-permissioned)packages/client/src/views/Public/Gardens.tsx, Public/Impact.tsx, Public/GardenDetail.tsx; packages/admin/src/views/Community/index.tsx (mode governance), views/Garden/Strategies.tsx, views/Garden/SignalPool.tsxNone client-side for signal allocation (see gap below)usePublicGardens, usePublicGardenDetail, usePublicStats, usePublicSeason, useGardenCommunity, useConvictionStrategies, useAllocateHypercertSupport, useHypercertConviction, useMemberVotingPower

Surface design notes per persona

A: Gardener

  • Authentication: passkey (useAuth.createPasskey) is the primary path; wallet via AppKit is the fallback. The agent path provisions a custodial key in agent/services/db.ts for users without smartphones.
  • Offline-first is the defining constraint for this persona: the work submission flow has to function with intermittent connectivity. Job queue (packages/shared/src/modules/job-queue/) is the mechanic.
  • See Onboarding and Work Submission journeys.

B: Operator

  • The 4-stage Hub workspace (Work → Assess → Certify → History) is the canonical operator pipeline. Stage transitions correspond to journey steps; stage filtering is governed by useHubWorkbenchController.
  • Cross-garden context: useEligibleAdminGardens + useAdminGardenWorkspaceSelection constrain admin views to gardens the user holds an operator/owner hat on.
  • See Work Submission, Evaluation, Harvest journeys.

C: Evaluator

  • No dedicated workspace, no public profile, no separate route. The Evaluator surface is the existing Garden + Hub workspace, gated by hat membership.
  • The authority boundary is on-chain: AssessmentResolver.onAttest() calls HatsModule.isEvaluator(attester). The UI does not enforce a parallel separation between drafting and attesting; the resolver is the gate.
  • An evaluator who happens to also be an operator sees the same workspace as any operator; they additionally have on-chain authority to sign Assessment attestations.
  • See Evaluation journey for the full workflow.

D: Funder

  • Two parallel deposit channels: Octant Vault (yield-bearing ERC-4626, principal-preserving) and Cookie Jar (direct grant pool with on-chain access policy).
  • Public /fund is deposit-only by design (ADR D37). Withdraws live in the admin surface; the public page intentionally keeps the funder JTBD focused.
  • Hypercert listings are the funder's pull mechanism for impact purchase markets — funders can buy listed hypercerts via useCreateListing / marketplace flow.
  • See Funding journey.

E: Community Member

  • Read access is fully shipped via the four public routes (/gardens, /gardens/:id, /impact, /actions). A community member can browse a Garden, see its impact, and read its actions without authentication.
  • Conviction signaling is currently operator-facing: the conviction allocation hooks (useAllocateHypercertSupport, useHypercertConviction) and signal-pool primitives (useGardenPools, useRegisteredHypercerts) are wired into admin Community Governance / Strategies / SignalPool views, not into a public PWA surface.
  • Community members hold the role on garden.communities[] and useEffectiveToolbarPermissions recognizes the role for visibility, but the public browser site does not currently render a public-side "signal" allocation flow. This is the one persona-surface gap of note.

Gaps (vs v1.0 spec § 3.1)

PersonaGapWhere it sits
A: GardenerNone on the primary path. SMS path is documented but only Telegram is operationally live.packages/agent/src/handlers/ covers Telegram; SMS adapter is referenced in spec § 6.3 Flow 1 but not deployed.
B: OperatorNone material.
C: EvaluatorNone — Persona C is served by existing surfaces via role-permissioned visibility, not a dedicated workspace.
D: FunderOctant Vault auto-buy of listed hypercerts is aspirational; "automated Karma GAP report showing yield utilization" is partial — manual Garden.gapProjectUID linkage is shipped, automated reporting is not.Spec § 3.3 + § 3.1 Persona D Definition of Success.
E: Community MemberNo public-side conviction allocation surface. Hooks exist (useAllocateHypercertSupport, useHypercertConviction) but no view in packages/client/src/views/Public/ allows a community member to allocate signal from the public browser site. Operator-facing surfaces in packages/admin/src/views/Community/ and Garden/{Strategies,SignalPool}.tsx cover it for hat-holders only.Spec § 3.1 names "Public Signal Feed and Gardens Conviction Voting" as the Persona E key interface — partial.

Reading guide

  • When picking up a feature: identify the persona, find its primary surface in this matrix, follow the link to the journey doc that describes the choreography, then read the source-of-truth file paths in the journey's frontmatter.
  • When introducing a new affordance: place it on the persona's primary surface unless there is a reason it must live elsewhere. Use the secondary-surface column to find the existing place a closely-related affordance already lives — that's where new related code should go.
  • When changing roles: useEffectiveToolbarPermissions, useHasRole, and the on-chain hat checks in resolvers are the three layers. Don't bypass any of them.