Skip to content

feat(governance): finalize membership lifecycle and runtime QA (#80)#99

Open
edehvictor wants to merge 1 commit into
GoodDollar:copilot/plan-wire-governancewidget-to-gooddaohousesfrom
edehvictor:fix/governance-lifecycle-80
Open

feat(governance): finalize membership lifecycle and runtime QA (#80)#99
edehvictor wants to merge 1 commit into
GoodDollar:copilot/plan-wire-governancewidget-to-gooddaohousesfrom
edehvictor:fix/governance-lifecycle-80

Conversation

@edehvictor

@edehvictor edehvictor commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Closes #80

Related: #75, #76, #77, GoodProtocol #299

Summary

Finalizes the contract-backed GovernanceWidget membership lifecycle and runtime boundaries introduced in #77. Active members now receive a truthful, receipt-aware unstake() flow; no-member, pending Alignment, and revoked states follow the GoodDaoHouses contract; voting/funding edge cases are enforced before submission; and the adapter is split into maintainable widget-local hooks.

The page hierarchy, header, onboarding stepper, membership cards, and transaction surfaces were aligned with the supplied governance UI references while keeping the existing GoodWidget design system and avoiding the out-of-scope detailed voting/dashboard redesign.

Changes

  • Replaced the misleading restake/rejoin path with lock-aware unstake() handling, successful-receipt refresh, and contextual wallet-confirmation, submitted, rejected, reverted, failed, and confirmed states.
  • Preserved normal onboarding for None/unstaked members, GoodID verification for Citizenship, HoA registry gating for Alignment, the pending Alignment state, and a non-actionable revoked state.
  • Reduced useGovernanceAdapter to composition over dedicated membership, voting, and funding hooks without moving contract calls into UI components.
  • Enforced vote-start membership rules, provisional HoA recipient filtering, Citizen GoodID-root voter keys, unique valid addresses, and exactly 10,000 basis points.
  • Kept stopped streams in the cumulative received total while distinguishing whether any stream is currently active.
  • Hardened account switching against stale membership/voting state, separated runtime read failures from contextual action failures, and made contract timestamp conversion safe for bigint values outside JavaScript's integer range.
  • Added deterministic Storybook fixtures, mocked viem RPC/Superfluid integration coverage, lifecycle regression tests, and updated screenshot evidence.

Acceptance criteria

Membership lifecycle

  • Active members use the actual GoodDaoHouses unstake() call and wait for a successful receipt.
  • Unstaking is enabled only after member.updatedAt + termDuration; the locked state explains when it becomes available.
  • Confirmed unstaking refreshes reads and returns the wallet to no-member onboarding.
  • Rejected, reverted, failed, wallet-confirmation, submitted, and confirmed transaction states are represented truthfully.
  • None/unstaked members can join Citizenship; Alignment remains gated by getHoaEligibility(account).isEligible.
  • Pending Alignment remains pending, while revoked membership is concise and non-actionable.
  • No reactivation, committee action, contract change, or unrevoke workaround was added.

Runtime correctness and maintainability

  • Membership/onboarding, voting, and funding concerns live in meaningful widget-local hooks; useGovernanceAdapter remains a small composition boundary.
  • Contract/SDK calls remain inside packages/governance-widget; presentational cards and onboarding components stay contract-agnostic.
  • Voters and provisional HoA recipients must have joined before the vote start; an existing contract snapshot remains authoritative.
  • Ballots contain unique valid addresses and allocations totaling exactly 10,000 bps.
  • Citizen duplicate-vote checks use the GoodID root; eligible active members of either house can vote.
  • Cumulative funding includes stopped streams, while active-stream presentation requires a non-zero current flow rate.
  • Wallet/account changes cannot display state loaded for the previous account.
  • On-chain timestamps that cannot be safely represented in milliseconds fall back to unavailable states instead of imprecise dates.

Tests, evidence, and comments

  • Real-adapter integration tests use mocked viem RPC and Superfluid responses.
  • Runtime coverage includes no-member onboarding, HoA gating, registration/unstake receipt outcomes, lock boundaries, voting eligibility, GoodID-root checks, recipient filtering, ballot validation, and funding active/stopped/empty/failed states.
  • Storybook covers disconnected, loading, onboarding, pending, active, no eligible HoA, upcoming/open/already-voted/executed votes, funding unavailable, unsupported chain, unstake lifecycle, revoked, and friendly-error states.
  • Current screenshots under tests/widgets/governance-widget/test-results/ were regenerated for the latest UI states.
  • Comments in touched files are limited to non-obvious protocol decisions.

Verification

Check Result
Governance package lint (eslint packages/governance-widget/src plus changed governance specs) Passed
Governance package ESM/CJS/declaration build (tsup) Passed
Governance adapter logic and runtime Playwright suite 42 passed
Governance dashboard and onboarding Playwright suite 21 passed
Total governance Playwright coverage 63 passed
git diff --check / staged diff check Passed

pnpm lint continues to report the unrelated, pre-existing root failures required to be disclosed by #80:

  • packages/core/src/detect.ts: unused HostEnvironment.
  • packages/embed/src/createMiniAppElement.tsx: unused _ parameter.

The final filtered Turbo invocation was blocked by the local non-interactive pnpm wrapper attempting to purge node_modules (ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY). The already-installed toolchain was therefore used directly; the governance package, including generated declarations, built successfully.

Evidence

Scope confirmation

  • No GoodProtocol contract or deployment changes.
  • No shared packages/ui, packages/core, or packages/embed API changes.
  • No new dashboard metrics, fabricated allocation breakdowns, committee UI, or detailed voting-page redesign.

@edehvictor
edehvictor requested review from a team and L03TJ3 July 16, 2026 18:53
@edehvictor edehvictor changed the title Fix/governance lifecycle 80 feat(governance): finalize membership lifecycle and runtime QA (#80) Jul 16, 2026
@edehvictor
edehvictor changed the base branch from main to copilot/plan-wire-governancewidget-to-gooddaohouses July 16, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GoodBounty]: Finalize GovernanceWidget functionality membership lifecycle, runtime QA, and UI/UX structure

1 participant