Skip to content

Paint combinator statement pages before operand IPFS reads finish - #142

Open
AdamSpitz wants to merge 140 commits into
masterfrom
feature/combinator-operand-nonblocking-load
Open

Paint combinator statement pages before operand IPFS reads finish#142
AdamSpitz wants to merge 140 commits into
masterfrom
feature/combinator-operand-nonblocking-load

Conversation

@AdamSpitz

Copy link
Copy Markdown
Owner

Summary

This branch makes combinator statement pages paint immediately instead of blocking on Promise.all for operand IPFS reads. Operand bodies fill in with CID fallbacks and resolve asynchronously.

Key Changes

1. Non-blocking operand loading (fdaa618)

  • StatementPage now paints the combinator statement before operand bodies resolve
  • Operand bodies fill in with CID fallbacks instead of blocking the whole page spinner
  • Added comprehensive tests for both conceptspace and causestarter StatementPage components

2. Guard against stale writes after navigation (ecb312b)

  • Extended loadTokenRef guard to all state writes after await points
  • Prevents slow loads from painting stale content after user navigates away
  • Applied pattern across StatementPage, UserProfilePage, and BrowseStatementsPage

3. Cleanup leftover CauseStarter package glue (4682db5)

  • Deleted unused files referencing old causestarter/src/ directory
  • Fixed tsconfig files to reflect new structure
  • Updated 19 stale path references across docs and specs

Testing

  • All typecheck passes (38 tasks successful)
  • Linting passes (only pre-existing warnings)
  • Unit tests pass for modified components:
    • ui/src/conceptspace/pages/StatementPage.test.tsx (32 tests)
    • ui/src/causestarter/pages/StatementPage.test.tsx (1 test)

Files Changed

  • ui/src/conceptspace/pages/StatementPage.tsx
  • ui/src/conceptspace/pages/UserProfilePage.tsx
  • ui/src/conceptspace/pages/BrowseStatementsPage.tsx
  • ui/src/causestarter/pages/StatementPage.tsx
  • Various cleanup files (vite.config.ts, index.html, etc.)

AdamSpitz and others added 30 commits August 14, 2026 16:23
…docs (#125)

* Define the ubiquitous language and sweep the terminology drift

Adds specs/glossary.md as the canonical vocabulary reference, linked from the
root README, specs/README.md, and jargon.md. The repo had no glossary — only a
stub asking whether one already existed.

Structurally the system was already coherent (see the 2026-06-25 conceptual
coherence review); the drift was vocabulary. Four clusters, all ruled on by
Adam 2026-08-14 and swept here:

- "Support" meant two disjoint things: agreeing with a statement (free) in
  Conceptspace, and giving money in LazyGiving/Content Funding. Support now
  means the belief sense only; the money sense is "contributor".
- One act had four names (belief / DirectSupport / signing / endorsement).
  "Sign/signer" is the user-facing word, "belief state" the technical name for
  the tri-state value, "endorsement" is retired in favour of "vouch".
- "Pledge" meant a recurring standing order in the contracts but a one-off
  contribution in UI copy. Pledge is now recurring-only.
- Six words for the money-giver role collapse to "contributor" pre-success and
  "donor" for retroactive donations.

Also retires "campaign" and finishes stragglers of the portal -> cause board
rename.

Scope is copy plus SDK/UI identifiers. No contract or event names change:
events are a versioned public API, so DirectSupport and the ABI arg
`participant` stay as they are, and the word wins only above the contract.

A distinction that fell out of the sweep and is now load-bearing: a "signer"
signed this exact statement, while a "supporter" is the union of direct signers
and indirect ones reached through the implication graph.

Deliberately not swept: the assurance-contract prose in credible-threat.md and
neighbours, where "pledge" carries the ordinary-English conditional-promise
sense and no recurring sense appears nearby. Recorded with reasoning in the
glossary. Remaining smaller items (earmark, marketplaceAddress, contract
directory names) filed in TODO.md.

Verified: sdk 519 tests, ui vitest 1700 tests, integration-tests typecheck all
pass; lint clean. The indexer stale-ABI typecheck failure and the 10 Playwright
e2e failures are pre-existing on dev and unrelated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Add founder-authored CauseStarter E2E verifier check.

Store Adam's CauseStarter surface description verbatim and have an LLM judge whether the built site more-or-less matches, plus independent user notes. Also include his inbox/TODO cleanup in the same commit.

* Explain CauseStarter project-list trust and seed it locally.

Project lists wait on a Subjectiv trust graph, not a cause attestation.
Show supporter counts without that gate, add settings plus a local trust
banner, and record Hardhat-account trust during data.sh --seed.

* Add an organizer viewing/editing switch to CauseDetailPage.

Organizers can now see what a supporter sees: viewing mode hides
device-local drafts and every editing affordance. `canEdit` still guards
each handler, so the switch is display-only. New causes open in editing,
already-live causes open in viewing.

Also: link issue text to the statement page, move the supporter-count
strip in with the issues, and adopt "bookmark" as the user-facing word
for the device-local save (glossary entry added).

* Limit CauseStarter edit mode to organizers and host Content Funding in-app.

Hide the viewing/editing switch unless the connected wallet owns the cause, keep statement CIDs off the cause page (muted on the statement page), and route Content Funding through CauseStarter instead of the separate domain.

* Rename CauseStarter Momentum to Causes and host earmark in-app.

Nav is Home / Causes / Tools; start a cause lives on the landing and Causes pages. Earmark and delegate-offer reuse the shared delegation pages inside CauseStarter. User-facing copy says cause page instead of roster.

* Turn CauseStarter Tools into Docs and split empty vs occupied home.

Drop growth tools from the nav page (they live on cause pages), rename it Docs, and show the landing copy only when the user has no causes. Occupied home and /causes share one YourCauses list.

* Hide unfiltered cause projects until a wallet has trustees.

Logged-out visitors were treated as trust-ready, so CauseStarter listed
every alignment vouch. Require a connected trustee set before querying,
and hide the organizer edit switch on pinned read-only versions.

Start-cause e2e now uses the Causes CTA so occupied home still works,
and revisions after publish switch into editing first.

* Fix glossary table whitespace

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
CauseStarter now hosts project creation, labels board sections as
initial funding vs reimbursement, explains that earmarks are public
but not binding, and sends the cause-page Content Funding link to a
cause-scoped social-media board instead of the generic landing page.
Move Start a cause to the title row, drop the home docs footer, and point the GitHub mark at the repo. Stop treating signed statements as causes; keep published causes via a dedicated bookmarked-causes ref, with drafts still device-local.
Add testnet ops and integration-test items for the bootstrap trust
service. Drop finished CauseStarter work and record bookmark follow-ups.
Show Unpublished only for drafts, move site copy into info alerts, drop the published-plank caption, put supporter counts on one line, and rename the section Fundable Projects.
Load statement text in parallel with a cheap document read, and cap the
legacy IPFS fallback so a missing CID no longer stalls first paint.
…ordances

CauseStarter board affordances, local lists, and alignment-trust bootstrap
Add not-yet-funded / not-yet-reimbursed plus quieter reimbursed and
failed tabs on the shared cause board, give CauseStarter project rows
progress sliders, raise the founder-e2e timeout, and record that
"Fully reimbursed" still means succeeded, not reimbursement-zero.
The cause-board tab no longer lists every project that merely raised its
threshold. Seed the local Hardhat trust graph on service start, and copy
the UI package into the CauseStarter IPFS image so that build can resolve
@ui/* imports.
The header now copies the full origin URL (or opens the system share
sheet). Also treat a configured starter trust root as a one-node network
when it has no outgoing TrustSet edges.
The starter-network filter notice and the "projects vouched for this issue" copy now live on the statement cause-board page, not the main cause view.
A content contract appears in the cause and statement project lists when
any of its posts is attested to a plank. Contract detail labels each post
as aligned or not. Remaining follow-ups are listed in causestarter/TODO.md.
Require a configured trusted content attester for inclusion, rematch on
attestation fingerprints instead of map size, and update founder e2e copy.
Live seed of mixed attested/unattested batches is still outstanding.
CauseStarter's board can now show a vouched project plus a 1-of-2
attested content contract after `./scripts/data.sh --seed`, and Hardhat
#0–#9 bookmark that cause so it appears on the landing page.
Drop the leftover Content Funding tool card now that contracts sit on the
board, collapse pledges into a summary that opens a dedicated funding
page, and move roster age plus connect-wallet prompts out of prime
layout. Wordmark is home; selected nav is no longer a filled CTA.
Replace stand-with-this-issue copy with sign-this-statement language, drop the any/all toggle so both selected-set counts appear together, and treat row selection as a faded/highlighted view filter with an eye icon rather than a signing control.
getStatementWithContent used to 404 unsigned planks because it only existed after DirectSupport events. Fall back to PublishedData content with zero believer counts so /statement/:cid works immediately after publish.
CauseViewStrip now says users signed at least one / every selected statement. Drop the in-app light/dark toggle so the theme tracks prefers-color-scheme. Assert plank-row totals have no extra labels.
Use a Statement tag and body-size heading, fold board help into a Projects tooltip, and persist discovery plus All/Direct-only alignment on trust settings instead of the board.
Keep Start content contract with Start project, stop the fundable-projects list flashing on trust refreshes, and show statements in the same compact signed-row layout as a cause plank (overline, direct/indirect counts).
Share the cause-page keep-painted pattern so statement boards, leaderboard
previews, and pledge totals do not flash a spinner on trust-set reloads.
Embed project lists in the board chrome, shrink header metrics, and make
cards a single-row layout with clearer remaining-to-threshold copy.
Add the reasonable-annoyance test to the peculiar-statements spec as a pair
checker, point nudger/seed/CSM docs at it, and teach cause-assist critique
and statement guidance to apply it without loosening the attester.
Split bridge wording guidance from ordinary planks, pass parent/intended-bridge into the cluster verbs, refuse coalition captions on shared text, and add attester examples for captions and tighter policy specs without rejecting honest subset.
Camp-match alignment attesters and buy/pledge by project id so secular
accounts stay off scripture-unique work. Cluster-only resolves statement
CIDs without republishing them on-chain. Keep signer-annoyance routing on
bridge drafts only.
Christian/secular tiny seed, statement guidance, and CauseStarter cluster assist
Capture the process, cause-assist guidance, and exercise-1 OSS/local-food
planks (earmark grain, geographic parents) so a later session can mass-seed
without hand-wordsmithing. Not yet in live seed-content.
Accepted OSS and local-food planks now live in seed-content/simple-causes.json. Tiny-seed garden alignment is unchanged. Live Grey→Ontario checks are scripted; the farmers-market Ontario parent dropped "more" only as a workaround. Nested-place boards vs the attester (container vs throughout) is still Ask: do not copy that workaround, somewhere-in, or an any-over-counties combinator.
Stop teaching Grey→Ontario as a designed-yes implication in statement generation, cause-assist, and seed gold. Ontario-wide planks stay as genuine wants; the garden seed publishes a Grey County relevant area and the local-food roster scopes within Ontario.
Canonical cutoff wording now contains the 12-16 week deal on the
modified-right (patterns page, bridge-creator, exercise JSON). Live
attester blesses both modifieds and refuses both naturals. Not loaded
into seed-content.
Production defaults live in PRODUCTION_OPENROUTER_MODEL; laptop scripts use a separate DEV_OPENROUTER_MODEL path so they can diverge later. Cause-assist now prefers OpenRouter over xAI when both keys are set.
CauseStarter now reads the same config.json-backed machinery as the rest of
the SPA, so IPFS overlays apply. Delete the CS copies of runtime config,
wagmi helpers, and WalletButton; route through domain manifests and barrels.
Move Hardhat keys, fake CIDs, and mock IPFS to @commonality/sdk/testing, let createWriteClients take a chain, and compile only src plus ABIs. Retire the unused schema/codegen path.
The attester prompt no longer treats Grey County → Ontario as an accept
rule. Resume-aware generation retries empty LLM responses and re-evaluates
stale prompt fingerprints. The checked-in seed implication corpus is
unchanged and still needs a live refresh.
Break the 1300-line name-scan decoder into per-subsystem modules and pass
the contract ABI into decodeEventLog so shared event names cannot pick the
wrong ABI. Keep the public utils re-export. Slice F still has other files.
Conceptspace and content-funding queries stay on the same public barrels; conceptspace event-cache reads page through fetchEventsComplete instead of treating a 10k cap as a complete set.
Keep publishBridgeCluster and page helpers as a real seam. Leave editor
and published-view JSX on the page. Slice G is stale-path nits already
covered elsewhere or marked opportunistic, so the plan is no longer useful.
Do not treat missing project metadata as a geographic miss (content-funding and in-flight IPFS reads), key aligned-list snapshots by inclusion rules, restore Compose env interpolation for cause-assist models, and pair an explicit xAI base URL with the xAI key.
Statement generation, geographic board inclusion, SDK/CauseStarter fold
Operand bodies fill in with CID fallbacks instead of blocking the whole
page spinner on Promise.all.
StatementPage: extend the existing loadTokenRef guard (previously only
covering operand fetches) to all state writes after await points —
setStatement, setStatementContent, setContentStatus, metrics,
setUserBeliefState, and the catch block. A slow load that resolves after
the user has navigated to a different statement no longer paints stale
content.

Sweep the same pattern across the other conceptspace pages:
- UserProfilePage: guard against stale writes when navigating between
  profiles (address param change)
- BrowseStatementsPage: guard against stale writes when rapidly toggling
  sort options

All 112 existing tests pass.
Delete unused files that referenced the old causestarter/src/ directory:
- vite.config.ts (dev/build now go through ui/ workspace)
- index.html (referenced deleted src/main.tsx)
- vitest.config.ts (referenced deleted src/test/setup.ts)
- tsconfig.app.json (included non-existent src/ directory)

Fix tsconfig files:
- tsconfig.json: simplify to extend tsconfig.node.json
- tsconfig.node.json: update includes to [playwright.config.ts, eslint.config.js, e2e]

Update 19 stale causestarter/src path references to ui/src/causestarter across:
- docs/founder/ (2 files, 4 refs)
- inbox.md (3 refs)
- cause-assist/ (2 refs)
- services/bridge-creator/ (1 ref)
- specs/ (4 files, 6 refs)
- fake-data-generation/ (2 refs)
- causestarter/README.md (1 ref)

Remove completed TODO item.
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.

1 participant