Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Ideascape is an exploration-mode concept-validation platform for learning which
- Route-level code splitting for non-home pages
- Supabase row-level security and pgTAP coverage for profiles, ideas, media, categories, and interest signals

There is intentionally no live fundraising, checkout, crypto wallet connection, custody, or payment collection. The future design explores security-reviewed smart-contract escrow, milestone-based releases, self-custodied signatures, refund paths, and compliant fiat on-ramps. No chain, asset, governance model, or contract implementation has been selected.
There is intentionally no live fundraising, checkout, custody, or payment collection. Funding research is deferred and is not part of the current landing page, catalog, or pilot-readiness mission.

## Demo catalog

Expand Down Expand Up @@ -66,7 +66,7 @@ Fresh databases contain these published concept previews:
20. [Model Commons Lab](https://ideascape-gamma.vercel.app/ideas/model-commons-lab)
21. [Flock Off Colorado Springs](https://ideascape-gamma.vercel.app/ideas/glass-box-sensor-network)

Each concept uses a stable UUID and slug, polished multi-paragraph copy, and a locally hosted SVG illustration so local resets and production verification remain reproducible. Every demo now uses the landing page's security-claim discipline: it names a concrete threat scenario, an authorization, privacy, safety, provenance, or fail-safe control boundary, and measurable proof required before the concept earns a larger test. The earliest five broad previews define bounded first tests, required permissions, privacy limits, measurable continuation evidence, and explicit stop conditions instead of assuming that backing or an operating program already exists. Those five concepts and Project Time Capsule also ask one focused, private-answer validation question so practical demand, permissions, and pilot capability can be evaluated as aggregate evidence rather than public member activity. Three previously generic previews are now sharp Colorado Springs campaigns: challenge the plate-reader dragnet through public records and lawful organizing, force a dangerous Academy Boulevard crossing into the engineering record, and turn Mountain Metro's own accessibility findings into five concrete stop fixes.
Each concept uses a stable UUID and slug, polished multi-paragraph copy, and a locally hosted SVG illustration so local resets and production verification remain reproducible. Every demo uses the same permission-first discipline: it names a concrete threat scenario, an authorization, privacy, safety, provenance, or fail-safe control boundary, and measurable proof required before the concept earns a larger test. The earliest five broad previews define bounded first tests, required permissions, privacy limits, measurable continuation evidence, and explicit stop conditions instead of assuming that backing or an operating program already exists. Those five concepts and Project Time Capsule also ask one focused, private-answer validation question so practical demand, permissions, and pilot capability can be evaluated as aggregate evidence rather than public member activity. Three previously generic previews are now sharp Colorado Springs campaigns: challenge the plate-reader dragnet through public records and lawful organizing, force a dangerous Academy Boulevard crossing into the engineering record, and turn Mountain Metro's own accessibility findings into five concrete stop fixes.

## Stack

Expand Down Expand Up @@ -153,21 +153,11 @@ The database models categories, creator-owned ideas, ordered media, explicit lif
- Draft and cancelled ideas reject interest writes.
- Public profiles are readable by everyone, while authenticated members can update only their own profile fields.

## Planned funding and security model
## Landing-page product story

The landing page documents a future architecture rather than an active funding feature. A validated concept could eventually become a campaign with published goals, deadlines, milestones, evidence requirements, fees, and refund/dispute rules. A reviewed smart contract could then hold funds against those terms and release only an approved milestone tranche or follow the published refund path.
The landing page presents Ideascape as a public workshop for early ideas rather than a transaction product. It introduces all six catalog categories, explains the concept-validation flow, offers concrete ways to participate, and asks four proof questions before any idea expands: whose problem it is, what the smallest useful test is, what must stay protected, and what evidence would change the plan.

The threat-model preview includes concrete failure cases: premature milestone claims, tampered wallet prompts, compromised administrator keys, and post-deployment contract bugs. The proposed baseline includes:

- No automatic release from creator-submitted evidence; use an independent review quorum and dispute window.
- Human-readable confirmation of chain, asset, amount, fees, and verified contract address before signing.
- Self-custody: Ideascape never requests wallet seed phrases or private keys.
- Separated roles, hardware-backed keys, least privilege, and multisig for privileged actions.
- Independent audits, reproducible deployments, testnet simulations, capped pilots, version pinning, and timelocked changes.
- Emergency pause and incident runbooks that protect new deposits while preserving release or refund paths.
- On-chain monitoring plus legal, tax, sanctions, privacy, and consumer-protection review.

These are design requirements, not current guarantees. No custody or smart-contract code is live, and a security claim is not considered real until implementation, deployment configuration, tests, governance, and external review prove it.
The current experience accepts no payments or fundraising. Interest is a reversible signal, not a purchase, vote, or permission grant. Deferred funding research remains isolated in `PLAN.md` and requires a separate consequential product decision before implementation.

## Quality checks

Expand Down
145 changes: 85 additions & 60 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,17 @@ describe("App", () => {
}),
).toBeInTheDocument();
expect(
screen.getByText(/concept-validation platform/i),
screen.getByText(/public workshop for early ideas/i),
).toBeInTheDocument();
expect(screen.getByText("Test the possibility")).toBeInTheDocument();
expect(screen.getByText("Permission-first technology")).toBeInTheDocument();
expect(screen.getByText(/evidence about demand/i)).toBeInTheDocument();
expect(
screen.getByText(/if funding is activated later/i),
screen.getByText("Practical ideas, clearer next steps"),
).toBeInTheDocument();
expect(
screen.getByText(/public interest and practical feedback/i),
).toBeInTheDocument();
expect(
screen.getByText(/assumptions, permissions, boundaries/i),
).toBeInTheDocument();
expect(screen.getByRole("link", { name: /sign in/i })).toHaveAttribute(
"href",
Expand All @@ -90,8 +94,10 @@ describe("App", () => {
"/sign-up",
);
expect(
screen.getByRole("link", { name: /start an idea/i }),
).toHaveAttribute("href", "/ideas/new");
screen
.getAllByRole("link", { name: /start an idea/i })
.some((link) => link.getAttribute("href") === "/ideas/new"),
).toBe(true);
expect(
screen.getByRole("link", { name: /explore ideas/i }),
).toHaveAttribute("href", "/ideas");
Expand All @@ -102,8 +108,10 @@ describe("App", () => {
/testing whether people want a place like this/i,
);
expect(
screen.getByRole("link", { name: /join the experiment/i }),
).toHaveAttribute("href", "/sign-up");
screen
.getAllByRole("link", { name: /join the experiment/i })
.every((link) => link.getAttribute("href") === "/sign-up"),
).toBe(true);
expect(screen.getByText("Concept previews")).toBeInTheDocument();
expect(
screen.getByText("Concept previews").nextElementSibling,
Expand All @@ -126,30 +134,61 @@ describe("App", () => {
).not.toBeInTheDocument();
});

it("spotlights a permission-first technology pathway", () => {
it("spotlights a mix of practical community ideas", () => {
renderApp();

expect(
screen.getByRole("link", { name: /explore technology concepts/i }),
).toHaveAttribute("href", "/ideas?category=technology");
screen.getByRole("link", { name: /browse by category/i }),
).toHaveAttribute("href", "#idea-terrain-heading");
expect(
screen.getByRole("img", {
name: /owner-controlled devices.*isolated repair bench/i,
name: /library room with portable air cleaners/i,
}),
).toBeInTheDocument();
expect(
screen.getByRole("img", {
name: /read-only recovery station.*encrypted folder/i,
name: /storefront becomes an evening gallery/i,
}),
).toBeInTheDocument();
expect(
screen.getByText(/permission-first technology/i),
screen.getByText(/practical ideas, clearer next steps/i),
).toBeInTheDocument();
expect(
screen.getByText(/owner-authorized device work/i),
screen.getByText(/cleaner air, safer streets, shared repair/i),
).toBeInTheDocument();
});

it("presents broad community use cases without crypto-first framing", () => {
renderApp();

const main = screen.getByRole("main");
expect(
within(main).getByRole("heading", { name: /ideas for everyday life/i }),
).toBeInTheDocument();
expect(
within(main).getByRole("heading", { name: /ways to take part/i }),
).toBeInTheDocument();
expect(
within(main).getByRole("heading", { name: /proof before scale/i }),
).toBeInTheDocument();
for (const category of [
"Arts & Culture",
"Community",
"Education",
"Environment",
"Health",
"Technology",
]) {
expect(
within(main).getByRole("heading", { name: category }),
).toBeInTheDocument();
}
expect(main).toHaveTextContent(/no payments or fundraising/i);
expect(main).not.toHaveTextContent(
/smart.contract|crypto wallet|multisig|on.chain|seed phrase|funding rail/i,
);
});

it("explains the current idea-validation flow", () => {
renderApp();

Expand Down Expand Up @@ -177,60 +216,46 @@ describe("App", () => {
).toHaveAttribute("href", "/ideas");
});

it("presents smart-contract funding as a planned, safety-reviewed layer", () => {
it("shows concrete participation paths without implying transactions", () => {
renderApp();

const fundingLayer = screen.getByRole("region", {
name: /planned smart-contract funding/i,
const participation = screen.getByRole("region", {
name: /ways to take part/i,
});
expect(fundingLayer).toHaveTextContent(/planned, not live/i);
expect(fundingLayer).toHaveTextContent(/no funds are accepted today/i);
expect(fundingLayer).toHaveTextContent(/milestone-based releases/i);
expect(fundingLayer).toHaveTextContent(/release or refund/i);
expect(fundingLayer).toHaveTextContent(/independent security review/i);
expect(fundingLayer).toHaveTextContent(
/chain, asset, and governance design have not been selected/i,
);
expect(participation).toHaveTextContent(/current invitation/i);
expect(participation).toHaveTextContent(/no payments or fundraising/i);
for (const path of [
"Bring a question",
"Signal what matters",
"Add grounded context",
]) {
expect(
within(participation).getByRole("heading", { name: path }),
).toBeInTheDocument();
}
});

it("explains the planned custody threat model with concrete examples", () => {
it("explains the evidence and permission questions before expansion", () => {
renderApp();

const securityModel = screen.getByRole("region", {
name: /security before custody/i,
const proof = screen.getByRole("region", {
name: /proof before scale/i,
});
expect(securityModel).toHaveTextContent(/no custody is live/i);
expect(securityModel).toHaveTextContent(
/every seeded concept.*threat scenario.*control boundary.*proof required/i,
);
expect(
within(securityModel).getByRole("heading", {
name: /a milestone is claimed too early/i,
}),
).toBeInTheDocument();
expect(
within(securityModel).getByRole("heading", {
name: /a wallet prompt is tampered with/i,
}),
).toBeInTheDocument();
expect(
within(securityModel).getByRole("heading", {
name: /an admin key is compromised/i,
}),
).toBeInTheDocument();
expect(
within(securityModel).getByRole("heading", {
name: /a contract bug is discovered/i,
}),
).toBeInTheDocument();
expect(securityModel).toHaveTextContent(
/no single operator controls funds/i,
);
expect(securityModel).toHaveTextContent(
/never requests seed phrases or private keys/i,
expect(proof).toHaveTextContent(/interest is a starting signal/i);
for (const question of [
"Whose problem is this?",
"What is the smallest useful test?",
"What must stay protected?",
"What result changes the plan?",
]) {
expect(
within(proof).getByRole("heading", { name: question }),
).toBeInTheDocument();
}
expect(proof).toHaveTextContent(/nothing graduates automatically/i);
expect(proof).toHaveTextContent(
/never grants permission to use private data, property, accounts, or community identity/i,
);
expect(securityModel).toHaveTextContent(/independent audit/i);
expect(securityModel).toHaveTextContent(/timelocked upgrades/i);
});

it("renders the sign-in route", async () => {
Expand Down
Loading
Loading