You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #77 now has a contract-backed GovernanceWidget foundation, but its membership lifecycle still presents a misleading “restake to rejoin” action. In the current GoodDaoHouses contract, an active member may call unstake(), which returns their G$ and removes their member record; that wallet then becomes a new/non-member and may join again.
A revoked member is deliberately out of scope: the contract has no reactivation route, so this task must not invent one.
Finalize the active-member unstake and no-member onboarding flow, complete the remaining runtime boundaries and contract-edge validation, and make the resulting Storybook/Playwright evidence trustworthy for human review.
Replace the existing restake/rejoin action with an active-member unstake() action.
Use the actual GoodDaoHouses unstake() call, wait for a successful receipt, and show wallet-confirmation, submitted, confirmed, rejected, and reverted states.
Respect the contract lock: unstaking is allowed only after member.updatedAt + termDuration. Show an accurate disabled/explanatory state before that time; never report success before the receipt.
After confirmation and refreshed reads, route the wallet to the existing no-member onboarding flow.
A wallet whose member record has status: None can use normal onboarding: Citizenship is available; Alignment remains available only when getHoaEligibility(account).isEligible is true.
Keep pending Alignment as a pending state. For Revoked, remove the misleading rejoin/restake CTA and show a concise non-actionable status. Do not implement reactivation, committee actions, or an “unrevoke” workaround.
Runtime correctness and maintainability
Refactor useGovernanceAdapter into a small composition hook. Separate membership/onboarding and unstake actions, voting state/actions, and funding refresh into meaningful widget-local modules/hooks. Do not create forwarding-only files or move contract calls into UI components.
Match vote-window rules before enabling a ballot: the voter and provisional HoA recipients must have joined before the vote start. Use the contract snapshot when it exists; otherwise filter the active HoA provisional list so the widget never submits a recipient the contract will reject.
Keep the cumulative funding total inclusive of stopped streams, but only present it as actively streaming when at least one stream has a non-zero current flow rate.
Tests, evidence, and comments
Add real-adapter integration tests using mocked viem RPC and Superfluid subgraph responses. Static injected adapter state is useful for visual QA but is not sufficient proof of runtime wiring.
Cover: no-member onboarding, eligible/ineligible HoA selection, successful and reverted/rejected registration and unstake receipts, lock-period handling, both-house voting eligibility, Citizen GoodID-root duplicate checks, join-time recipient filtering, 10,000-bps validation, and funding active/stopped/empty/failed states.
Keep Storybook runtime states for disconnected, loading, onboarding, pending, active, no eligible HoA, upcoming/open/already-voted/executed vote, funding unavailable, unsupported chain, unstake lock/confirmation/failure, revoked, and friendly error states.
Update current Playwright screenshots under tests/widgets/governance-widget/test-results/ when the UI changes; test output should represent the latest states.
Update comments in files touched by this work when they become inaccurate. Prefer clear component/function names and JSX structure over comments such as “CTA button” or “field rows.” Keep short comments only where they preserve a non-obvious protocol decision, for example: Citizen voting uses a GoodID root; a vote snapshot excludes members joined after the voting window starts; or stopped streams still contribute to the cumulative received total.
Scope boundaries
In scope
The GovernanceWidget lifecycle and runtime code, stories, tests, and generated widget test evidence.
Existing GoodDaoHouses read/write interface only, including unstake().
Focused comment corrections in files changed for this bounty.
Out of scope
Any GoodProtocol contract change, deployment, registry administration, committee UI, or member reactivation/unrevoke mechanism.
if something is found to be missing from the contract it should be raised as comment in the pull-request.
Changing shared packages/ui, packages/core, or packages/embed APIs.
New dashboard metrics, project-allocation funding breakdowns, or a detailed voting-page redesign.
packages/governance-widget/src/sdks/contracts.ts — verified #299 ABI, record mapping, receipt and address helpers.
packages/governance-widget/src/sdks/contractReads.ts — membership, schedule, vote, and FlowSplitter reads.
packages/governance-widget/src/sdks/transactions.ts — add/use the unstake() transaction path and receipt handling.
packages/governance-widget/src/sdks/funding.ts — cumulative funding aggregation and active-flow metadata.
packages/governance-widget/src/GovernanceWidget.tsx — truthful active, pending, revoked, and no-member surfaces; no contract calls here.
examples/storybook/src/stories/governance-widget/GovernanceRuntime.stories.tsx — deterministic visual states.
tests/widgets/governance-widget/adapter-logic.spec.ts and runtime.spec.ts — extend real-adapter and UI-flow coverage.
governance-widget-first-pass-verdict.md — concise review context and previously verified commands.
Definition of Done + how to test
Definition of Done
An eligible active member can unstake only when the contract lock permits it; confirmed unstaking returns widget state to no-member onboarding.
No-member onboarding, HoA registry gating, pending Alignment, and revoked states are accurate and do not offer an unsupported reactivation path.
Registration, unstaking, and voting wait for receipts and clearly represent submitted, rejected, reverted, and confirmed outcomes.
Runtime vote recipients and voter eligibility match the GoodDaoHouses vote-start/snapshot rules; submitted allocations are valid addresses totaling exactly 10,000 bps.
Funding displays the cumulative received total correctly and distinguishes stopped historical streams from active streaming.
useGovernanceAdapter is a composition boundary, with no new monolith or trivial helper-file fragmentation.
Mocked-RPC/subgraph tests prove the runtime adapter flows listed above; Storybook and Playwright evidence cover the expected visible states.
Comments changed by this work explain non-obvious protocol constraints or decisions, not obvious UI structure; comments unrelated to the changed code are preserved.
pnpm lint currently has unrelated root failures. Do not fix other packages for this bounty; record the exact failures in the PR handoff. Run Storybook locally and manually verify the changed active, no-member, pending, revoked, voting, funding, and transaction states at mobile and desktop widths.
Summary
PR #77 now has a contract-backed GovernanceWidget foundation, but its membership lifecycle still presents a misleading “restake to rejoin” action. In the current GoodDaoHouses contract, an active member may call
unstake(), which returns their G$ and removes their member record; that wallet then becomes a new/non-member and may join again.A revoked member is deliberately out of scope: the contract has no reactivation route, so this task must not invent one.
Finalize the active-member unstake and no-member onboarding flow, complete the remaining runtime boundaries and contract-edge validation, and make the resulting Storybook/Playwright evidence trustworthy for human review.
After all functionality is done, the UI structure should be aligned with figma design reference (only structuring pages of the widget, header-bar etc):
https://www.figma.com/design/xsk5EiF6CvStA9mtdbA9OR/GoodWidget-Library?node-id=2311-3&t=n8jj6CUBsjyvJ2Je-1
Contributor task
Make sure to start your work as branch-out from:
copilot/plan-wire-governancewidget-to-gooddaohousesAGENTS.md,docs/demo-environment.md, andgovernance-widget-first-pass-verdict.mdbefore changing code.Related contract pull-request for contract shape and reference can be found: Implement GoodDaoHouses MVP smart contract build GoodProtocol#299
Scope checks
Membership lifecycle
unstake()action.unstake()call, wait for a successful receipt, and show wallet-confirmation, submitted, confirmed, rejected, and reverted states.member.updatedAt + termDuration. Show an accurate disabled/explanatory state before that time; never report success before the receipt.status: Nonecan use normal onboarding: Citizenship is available; Alignment remains available only whengetHoaEligibility(account).isEligibleis true.Revoked, remove the misleading rejoin/restake CTA and show a concise non-actionable status. Do not implement reactivation, committee actions, or an “unrevoke” workaround.Runtime correctness and maintainability
useGovernanceAdapterinto a small composition hook. Separate membership/onboarding and unstake actions, voting state/actions, and funding refresh into meaningful widget-local modules/hooks. Do not create forwarding-only files or move contract calls into UI components.Tests, evidence, and comments
tests/widgets/governance-widget/test-results/when the UI changes; test output should represent the latest states.Scope boundaries
In scope
unstake().Out of scope
if something is found to be missing from the contract it should be raised as comment in the pull-request.
packages/ui,packages/core, orpackages/embedAPIs.Starting points
packages/governance-widget/src/adapter.ts— split orchestration; replace restake flow; preserve widget-local boundaries.packages/governance-widget/src/sdks/contracts.ts— verified #299 ABI, record mapping, receipt and address helpers.packages/governance-widget/src/sdks/contractReads.ts— membership, schedule, vote, and FlowSplitter reads.packages/governance-widget/src/sdks/transactions.ts— add/use theunstake()transaction path and receipt handling.packages/governance-widget/src/sdks/funding.ts— cumulative funding aggregation and active-flow metadata.packages/governance-widget/src/GovernanceWidget.tsx— truthful active, pending, revoked, and no-member surfaces; no contract calls here.examples/storybook/src/stories/governance-widget/GovernanceRuntime.stories.tsx— deterministic visual states.tests/widgets/governance-widget/adapter-logic.spec.tsandruntime.spec.ts— extend real-adapter and UI-flow coverage.governance-widget-first-pass-verdict.md— concise review context and previously verified commands.Definition of Done + how to test
Definition of Done
useGovernanceAdapteris a composition boundary, with no new monolith or trivial helper-file fragmentation.How to test
pnpm lintcurrently has unrelated root failures. Do not fix other packages for this bounty; record the exact failures in the PR handoff. Run Storybook locally and manually verify the changed active, no-member, pending, revoked, voting, funding, and transaction states at mobile and desktop widths.