fix(legal): verify the installed clickwrap SDK and document UI versus API acceptance boundaries #49

Open
opened 2026-10-14 03:11:59 +00:00 by PlasticDigits · 0 comments
Owner

Scope and source

Priority: P1. Gap coverage: GAP-022, GAP-038. Derived from GAP_1791945837.md, reviewed code commit f8dbe93df953a78b17cb3304b717dcf84c4cd517. Current e476a68da09645c2308cbf47b90211fcaffcb7af adds only the report, so implementation findings remain applicable. Report evidence is local reproduction/source inspection unless explicitly proposed; no production exploit or current live-readiness claim.

Coverage and sequencing: gap backlog tracker. Workstream 13. Dependencies: 06, 08, 11.

Current codebase

Transactional dApp gating exists, but APIs do not verify terms status. That matches the current UI-gate requirement rather than proving an API breach. Unit tests substitute local SDK replicas; Accept test fails because a global location stub differs from window.location navigation in jsdom. This is harness failure, not evidence of broken production Accept.

Why this implementation is needed

Legal assurance needs actual SDK contract and return-path evidence, plus honest documentation of which callers are gated, without treating terms signatures as voting authentication.

Relevant files

Fix navigation tests at a pure URL construction/injected navigation boundary and exercise real navigation in Playwright. Add contract tests against installed @plasticdigits/cl8y-clickwrap (>=0.1.1) and reduce copied SDK mocks to explicitly limited fixtures. Preserve property/network/account-specific fail-closed gating, path-safe full-page redirects and required EVM/Keplr hints. Document UI-only enforcement as the current policy. If universal API acceptance is later chosen, specify authoritative Legal verification/current terms/caching/outage/revocation separately before adding all-mutation server enforcement; current implementation should not silently invent that policy.

Constraints and guardrails

Preserve standalone offchain advisory voting, no new smart contracts or archive-node dependency, BSC as a core electorate, raw 18-decimal integer balances and separate Terra/BSC address identities. Keep Legal fail-closed transactional UI and the proven DEX Terra/Bridge EVM connectors; no browser BSC balance RPC, seed/key prompt or embedded admin/model credential. API must retain a restricted role separate from the ledger writer. Freeze at actual opening, never at draft creation or a client-supplied height. Agents own design, implementation, review and evidence under repository guidance; do not shift approvals/tests to the human or invent PASS evidence.

Acceptance criteria

Unit suite is green for the correct navigation reason; tests detect real installed SDK incompatibility. Unknown/error/unaccepted/new-version/account-changed status blocks all transactional UI on both chains. Accept includes connected account and safe return path; portal/alias return works. Public API participation boundary and terms-versus-voting authentication are accurately documented.

Test plan: supported paths, failure paths and concurrency

Terra/EVM accepted/unaccepted/unknown/error/new terms, account/network switches, status cancellation/retry, injected and WC/mobile hints. Installed package URL/status contract; full navigation and portal return for /, /new, /:id and /vote aliases. Disconnected browsing and production builds without E2E hatch. Direct signed API client behavior demonstrates the documented boundary; if later enforcing server Legal checks, test every mutation and cache/version/outage path.

Test plan: attack, hack and abuse vectors

Forged localStorage acceptance, wrong property/network/account, spoofed query account, open redirects, stale acceptance cache and SDK drift; dev hatch in production, forged Legal response and terms signature replay as voting auth. No admin credentials or second portal signing implementation.

Verification and completion criteria

Attach green frontend tests, installed-SDK contract output and production-like browser navigation/status cases for both chains. Record actual portal/live return evidence separately; UI-only scope must not be described as universal API enforcement.

Record commit and pinned toolchain, commands/results and sanitized artifacts. Relevant Rust changes require cargo test --workspace --lib plus isolated Postgres integration (explicit guarded LEDGER_TEST_DATABASE_URL); frontend changes require npm test and production build plus relevant browser cases. Run secret scanning for new fixtures/config. Exercise fresh/upgrade migrations when schema/grants change; report skipped/live-only checks explicitly.

<!-- voting-gap-1791945837:13 --> ## Scope and source **Priority:** P1. **Gap coverage:** GAP-022, GAP-038. Derived from [GAP_1791945837.md](https://git.cl8y.com/code/voting/src/branch/main/gaps/GAP_1791945837.md), reviewed code commit `f8dbe93df953a78b17cb3304b717dcf84c4cd517`. Current `e476a68da09645c2308cbf47b90211fcaffcb7af` adds only the report, so implementation findings remain applicable. Report evidence is local reproduction/source inspection unless explicitly proposed; no production exploit or current live-readiness claim. Coverage and sequencing: [gap backlog tracker](https://git.cl8y.com/code/voting/issues/35). Workstream **13**. Dependencies: [06](https://git.cl8y.com/code/voting/issues/41), [08](https://git.cl8y.com/code/voting/issues/43), [11](https://git.cl8y.com/code/voting/issues/46). ## Current codebase Transactional dApp gating exists, but APIs do not verify terms status. That matches the current UI-gate requirement rather than proving an API breach. Unit tests substitute local SDK replicas; Accept test fails because a global location stub differs from window.location navigation in jsdom. This is harness failure, not evidence of broken production Accept. ## Why this implementation is needed Legal assurance needs actual SDK contract and return-path evidence, plus honest documentation of which callers are gated, without treating terms signatures as voting authentication. ## Relevant files - [`frontend/src/components/legal/ConnectedTermsGate.tsx`](https://git.cl8y.com/code/voting/src/branch/main/frontend/src/components/legal/ConnectedTermsGate.tsx) - [`frontend/src/components/legal/__tests__/ConnectedTermsGate.test.tsx`](https://git.cl8y.com/code/voting/src/branch/main/frontend/src/components/legal/__tests__/ConnectedTermsGate.test.tsx) - [`frontend/src/utils/legalClickwrap.ts`](https://git.cl8y.com/code/voting/src/branch/main/frontend/src/utils/legalClickwrap.ts) - [`frontend/src/utils/legalEvmInAppHint.ts`](https://git.cl8y.com/code/voting/src/branch/main/frontend/src/utils/legalEvmInAppHint.ts) - [`frontend/src/vendor/cl8y-clickwrap-react.tsx`](https://git.cl8y.com/code/voting/src/branch/main/frontend/src/vendor/cl8y-clickwrap-react.tsx) - [`frontend/src/vendor/cl8y-clickwrap.ts`](https://git.cl8y.com/code/voting/src/branch/main/frontend/src/vendor/cl8y-clickwrap.ts) - [`frontend/package.json`](https://git.cl8y.com/code/voting/src/branch/main/frontend/package.json) - [`frontend/vite.config.ts`](https://git.cl8y.com/code/voting/src/branch/main/frontend/vite.config.ts) - [`frontend/e2e/vote.spec.ts`](https://git.cl8y.com/code/voting/src/branch/main/frontend/e2e/vote.spec.ts) - [`operator-voting/src/api.rs`](https://git.cl8y.com/code/voting/src/branch/main/operator-voting/src/api.rs) - [`docs/FRONTEND.md`](https://git.cl8y.com/code/voting/src/branch/main/docs/FRONTEND.md) - [`skills/AGENTS_LEGAL_CLICKWRAP.md`](https://git.cl8y.com/code/voting/src/branch/main/skills/AGENTS_LEGAL_CLICKWRAP.md) ## Recommended solution Fix navigation tests at a pure URL construction/injected navigation boundary and exercise real navigation in Playwright. Add contract tests against installed @plasticdigits/cl8y-clickwrap (>=0.1.1) and reduce copied SDK mocks to explicitly limited fixtures. Preserve property/network/account-specific fail-closed gating, path-safe full-page redirects and required EVM/Keplr hints. Document UI-only enforcement as the current policy. If universal API acceptance is later chosen, specify authoritative Legal verification/current terms/caching/outage/revocation separately before adding all-mutation server enforcement; current implementation should not silently invent that policy. ## Constraints and guardrails Preserve standalone offchain advisory voting, no new smart contracts or archive-node dependency, BSC as a core electorate, raw 18-decimal integer balances and separate Terra/BSC address identities. Keep Legal fail-closed transactional UI and the proven DEX Terra/Bridge EVM connectors; no browser BSC balance RPC, seed/key prompt or embedded admin/model credential. API must retain a restricted role separate from the ledger writer. Freeze at actual opening, never at draft creation or a client-supplied height. Agents own design, implementation, review and evidence under repository guidance; do not shift approvals/tests to the human or invent PASS evidence. ## Acceptance criteria Unit suite is green for the correct navigation reason; tests detect real installed SDK incompatibility. Unknown/error/unaccepted/new-version/account-changed status blocks all transactional UI on both chains. Accept includes connected account and safe return path; portal/alias return works. Public API participation boundary and terms-versus-voting authentication are accurately documented. ## Test plan: supported paths, failure paths and concurrency Terra/EVM accepted/unaccepted/unknown/error/new terms, account/network switches, status cancellation/retry, injected and WC/mobile hints. Installed package URL/status contract; full navigation and portal return for /, /new, /:id and /vote aliases. Disconnected browsing and production builds without E2E hatch. Direct signed API client behavior demonstrates the documented boundary; if later enforcing server Legal checks, test every mutation and cache/version/outage path. ## Test plan: attack, hack and abuse vectors Forged localStorage acceptance, wrong property/network/account, spoofed query account, open redirects, stale acceptance cache and SDK drift; dev hatch in production, forged Legal response and terms signature replay as voting auth. No admin credentials or second portal signing implementation. ## Verification and completion criteria Attach green frontend tests, installed-SDK contract output and production-like browser navigation/status cases for both chains. Record actual portal/live return evidence separately; UI-only scope must not be described as universal API enforcement. Record commit and pinned toolchain, commands/results and sanitized artifacts. Relevant Rust changes require `cargo test --workspace --lib` plus isolated Postgres integration (explicit guarded LEDGER_TEST_DATABASE_URL); frontend changes require `npm test` and production build plus relevant browser cases. Run secret scanning for new fixtures/config. Exercise fresh/upgrade migrations when schema/grants change; report skipped/live-only checks explicitly.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/voting#49
No description provided.