From 167d8a59db28f96ee3cc025f17b0af288c681112 Mon Sep 17 00:00:00 2001 From: Sasha Date: Tue, 1 Sep 2026 07:47:35 +0000 Subject: [PATCH] =?UTF-8?q?LP-0024:=20Basecamp=20Theming=20=E2=80=94=20the?= =?UTF-8?q?me=20engine,=20format,=20and=20community=20themes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an adoption-first prize covering runtime theming for Basecamp: the theme engine in logos-design-system, a data-only theme format, three initial themes, an authoring path for contributors, and LGX/catalog distribution. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 1 + prizes/LP-0024.md | 201 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 prizes/LP-0024.md diff --git a/README.md b/README.md index d4ad00d1..16e3eb4a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ All prizes live in the `[prizes/](prizes/)` directory. Each prize is a markdown | [LP-0015](prizes/LP-0015.md) | General cross-program calls via tail calls | Large | Closed | | [LP-0016](prizes/LP-0016.md) | Anonymous Forum with Threshold Moderation | Large | Closed ([Solution](solutions/LP-0016.md)) | | [LP-0017](prizes/LP-0017.md) | Whistleblower: document upload and indexing Basecamp app | Medium | Closed ([Solution](solutions/LP-0017.md)) | +| [LP-0024](prizes/LP-0024.md) | Basecamp Theming: theme engine, format, and community themes | Medium | Draft | ### Proposing a New Prize diff --git a/prizes/LP-0024.md b/prizes/LP-0024.md new file mode 100644 index 00000000..864584eb --- /dev/null +++ b/prizes/LP-0024.md @@ -0,0 +1,201 @@ + + +--- +dependencies: [] +--- + +# LP-0024: Basecamp Theming — theme engine, theme format, and community themes [DRAFT] + +**`Status: Draft`** +**`Logos Circle: N/A`** + +## Overview + +Logos Basecamp is the shell of the decentralised super-app: the launcher users open first, keep open, and return to between every app they run. It is also the only surface in the stack whose appearance every user sees, and today that appearance is fixed at compile time — one dark palette, baked into the binary. + +This prize funds **user-selectable, community-authored themes for Basecamp**: the theme engine that makes the shell restyleable at runtime, a declarative theme format that a designer can write without touching C++ or QML, an initial set of themes that proves the mechanism and sets the conventions, and a packaging and distribution path so a theme is something you publish and someone else installs — not something you patch into a fork. + +The work spans three repositories that are already open source: [`logos-design-system`](https://github.com/logos-co/logos-design-system) (where the tokens live), [`logos-basecamp`](https://github.com/logos-co/logos-basecamp) (where they are consumed), and [`logos-package-manager`](https://github.com/logos-co/logos-package-manager) (where an installable artefact is routed). The enabling changes are expected to land **upstream**, as community contributions, not as a maintained fork. + +## Motivation + +Basecamp's own specification already lists this as missing work: *"Theme customization — User-selectable color themes beyond the default design system"* ([`docs/spec.md:362`](https://github.com/logos-co/logos-basecamp/blob/master/docs/spec.md), Future Work). The design system has the beginnings of the plumbing and stops short of the feature. + +Three things make this worth a prize rather than a backlog ticket: + +**It is a contribution surface nobody else in the stack offers.** Every other way to contribute to Logos requires C++, QML, Rust, or Nix. A theme is a document of colour values. Themes are how designers, and people who are simply opinionated about how their launcher looks, get a first commit into the ecosystem — and a community that can restyle the shell it looks at every day is a community with a reason to keep the shell open. + +**A theme system is only real once other people use it.** A one-off "add a light mode" patch is a week of work and proves nothing. What has to be proven is that a stranger can author a theme against a documented format, publish it, and have it install and render correctly on someone else's machine — including inside third-party apps they have never seen. That is an adoption question, not a code-review question, which is why this prize is graded adoption-first. + +**The security posture has to be designed in, not retrofitted.** Basecamp already sandboxes untrusted `ui_qml` apps (see `app/restricted/`): their QML engine gets a deny-all network stack, a URL interceptor confining them to their own install directory, and a rule refusing any `qmldir` under an untrusted root that declares a native plugin. That same interceptor deliberately stops a module's own folder from answering a `Logos.Theme` import, because "the design system owns the `Logos.*` namespace". A theme, however, is loaded into the **shell** process, which is not sandboxed. Getting the format wrong — shipping themes as QML, for example — hands third-party content the one privilege even sandboxed apps are denied. The right answer is cheap if chosen up front and expensive afterwards. + +## Starting Point + +The criteria below assume the tree as it stands at `logos-basecamp` [`76bcd03`](https://github.com/logos-co/logos-basecamp) and `logos-design-system` [`3312444`](https://github.com/logos-co/logos-design-system) (the revision Basecamp's `flake.lock` pins). Submitters should re-measure; these numbers are what the work looks like today. + +**What already exists.** + +- `Logos.Theme` is a real token layer: `Theme.palette` (61 semantic colour tokens in `DarkTheme.qml`, mapped from 65 raw values in `ColorPalette.qml`), `Theme.spacing` (5 spacing steps, 5 corner radii), `Theme.typography` (Public Sans loaders, 3 weights, 8 type sizes). +- `Theme.qml` already exposes `setTheme()`, `switchTheme()`, `availableThemes`, `themeNames`, and persists the choice through a `QtCore` `Settings` block under the `LogosDesignSystem` category. +- `Logos.Controls` ships 47 controls that consume those tokens, and is already fully token-clean: the only colour literals left in the set sit inside a documentation comment. +- `LogosIcon` recolours icon assets at render time through a `MultiEffect`, defaulting to `Theme.palette.text` — so icon *tint* is already token-driven. +- 31 of Basecamp's 46 QML files import `Logos.Theme`. + +**What is missing, and is the actual work.** + +- `availableThemes` is a compile-time object literal containing exactly one entry, `"dark"`. `DarkTheme.qml` is the only theme in the tree; there is no light theme and no way to add one without recompiling. `setTheme("anything-else")` logs a warning and returns. +- Themes are QML types registered in `Logos/Theme/qmldir`, and the design system is built as a `STATIC` `qt_add_qml_module` linked into `main_ui` with `WHOLE_ARCHIVE`. Nothing about the current shape can accept a theme that arrives on disk after the build. +- Basecamp's shell is not fully token-clean: 48 hardcoded hex literals remain in five production QML files — `Settings/PluginInterfaceView.qml` (24), `Shell/ConfirmationDialog.qml` (14), `Settings/DashboardView.qml` (7), `Sidebar/SidebarAppDelegate.qml` (2), `Shell/ContentViews.qml` (1) — plus 4 `setStyleSheet` call sites in C++ (`src/WorkspaceArea.cpp:560`, `src/WorkspaceArea.cpp:625`, `src/MainContainer.cpp:41`, `app/macos/trafficLightsTitleBar.cpp:18`). Those pixels will not move when the theme changes. +- The LGX manifest's `type` field is a classification string, but the toolchain understands `core`, `ui`, and `ui_qml`; `logos-package-manager` selects an install location from that set. A theme package is a fourth kind of artefact and has nowhere to land. +- Basecamp's Settings view has four sections (Dashboard, Apps Inspector, Module Inspector, Repositories). There is no appearance section, and no UI anywhere that calls `setTheme()`. + +## Success Criteria + +### Functionality + +- [ ] **Runtime theme registry**: `Logos.Theme` resolves themes discovered on disk at runtime, in addition to the built-in default. Adding a theme must not require rebuilding the design system, Basecamp, or any app. +- [ ] **Declarative theme format**: a theme is **data, not code**. A theme package must not be able to execute QML, JavaScript, or native code in the Basecamp process. The submission defines and documents the format (see *Design Decisions*), which must at minimum express: every semantic colour token in the palette, the spacing and corner-radius scales, and typography sizes and weights. +- [ ] **Full token coverage**: every semantic token exposed by `Theme.palette`, `Theme.spacing`, and `Theme.typography` is themeable. A theme may override any subset; unspecified tokens fall back, per token, to the built-in default rather than to an unset value. +- [ ] **Live switching**: changing the active theme restyles the running shell **and** every open app view without a restart, and without unloading or reloading modules. +- [ ] **Persistence**: the active theme survives a restart, including when it is a theme installed from a package rather than a built-in one. +- [ ] **Selection UI**: Basecamp gains a user-facing appearance surface (a Settings section is the natural home) that lists installed themes, applies one, and offers an unconditional "reset to default" path that works even from a theme that has made the UI unreadable. +- [ ] **Themes apply to third-party apps**: a `ui_qml` app built on `Logos.Controls` renders in the active theme. A sandboxed app can **read** the active theme; it cannot change it, and it cannot install one. +- [ ] **Token-clean shell**: the hardcoded colour literals and `setStyleSheet` sites listed under *Starting Point* are replaced by token references, so no part of the shell chrome ignores the active theme. Any pixel deliberately left un-themed (platform-drawn traffic lights, for example) is documented with the reason. +- [ ] **Three initial themes**, shipped as real theme packages built with the same format and tooling a third party would use — no privileged path: + - a **light theme**, complete across every token; + - a **high-contrast accessibility theme** in which every foreground/background token pairing the UI actually uses meets **WCAG 2.1 AA** contrast (4.5:1 for body text, 3:1 for large text and UI boundaries), with the measured ratios published; + - one **expressive theme** exercising whatever the format supports beyond flat colour (backgrounds, accent treatment, icon assets), demonstrating the ceiling of what a theme can do. +- [ ] **Theme packaging**: a theme is distributable as an LGX package, installable through the existing package-manager path (`lgpd` / the package-manager UI) alongside modules and apps, with content hashes and signatures verified exactly as they are for any other package. +- [ ] **Catalog distribution**: themes are publishable to a Logos module catalog (a [`logos-modules-release-base`](https://github.com/logos-co/logos-modules-release-base) fork, `logos-repo.json` + `index.json`) and installable by a third party from that catalog with no manual file copying. If a decentralised software-directory mechanism is available when this prize opens, integrating with it is preferred and the catalog path remains as the fallback; if it is not, the catalog path alone satisfies this criterion. + +### Usability + +- [ ] **Theme authoring guide**: a document that takes a designer with no Logos background from zero to an installed theme, including a complete reference for every themeable token, what it controls, and where it appears. +- [ ] **Starter template**: a copyable theme skeleton (repository template or generator command) that produces a valid, installable theme package out of the box. +- [ ] **Validator**: a command that checks a theme for missing, unknown, or invalid tokens and reports contrast failures against the WCAG thresholds above, so an author finds problems before publishing rather than after installing. +- [ ] **Preview**: a way to view a theme across the component set before shipping it — extending the design system's existing storybook is the obvious route. + +### Reliability + +- [ ] **Hostile and malformed themes are inert.** A theme file that is truncated, wrongly typed, carries unknown keys, declares out-of-range values, or attempts to reference paths outside its own package is rejected or clamped with a clear diagnostic. It must not crash the shell, and must not produce arbitrary code execution or filesystem or network access — demonstrated by an adversarial test fixture in the spirit of `tests/sandbox/evil_app/`. +- [ ] **No unrecoverable state.** Selecting a theme that renders the UI unusable (transparent text on transparent background, zero-size type) must still leave the user a way back to the default — the reset path cannot itself depend on being able to read the screen. +- [ ] **Uninstalling the active theme** reverts to the default immediately, without a restart and without leaving a dangling selection that fails at next launch. +- [ ] **Version skew**: a theme written against a newer token set installs and renders on an older Basecamp (unknown tokens ignored), and a theme written against an older set renders on a newer one (missing tokens fall back). Neither case may fail closed. + +### Performance + +- [ ] Switching themes on a running shell with at least three apps open completes in **under 200 ms** with no visible relayout artefacts, measured and documented. +- [ ] A theme installed from a package adds **no more than 50 ms** to cold start versus the built-in default, measured on both supported platforms. +- [ ] Steady-state memory overhead of the theme engine with a package theme active is measured and documented. + +### Supportability + +- [ ] The enabling changes are **merged upstream** into `logos-design-system` and `logos-basecamp` (and `logos-package-manager`, if the packaging route requires it), following each repository's `CONTRIBUTING.md`. A long-lived fork does not satisfy this prize. +- [ ] The submission builds and runs end-to-end on both **macOS (Apple Silicon)** and **Linux (x86_64)**. +- [ ] QML unit tests covering theme resolution, per-token fallback, live switching, and persistence are added to the design system's existing test suite; the malformed/hostile-theme cases are covered by a Nix check in the style of `sandbox-test`. +- [ ] CI is green on the default branch of every repository touched, and on the theme packages' own repositories. +- [ ] A README documents: building the changes, authoring a theme, packaging it, publishing it to a catalog, and installing it as an end user. +- [ ] **No mandatory centralised external services.** Beyond the user's configured catalog and the Logos protocols, theming must not depend on any third-party web service. Fonts, icons, and every other asset a shipped theme needs must be present in the theme package or in the build; no theme may fetch assets at runtime. Any analytics is strictly opt-in. + +### Adoption + +> These metrics measure traction attributable to a given submission for this prize. +> +> **All of the following are required in addition to the FURPS criteria above.** We publish the dimensions we look at, but hitting a raw number is not by itself sufficient (see [Terms & Conditions](../TERMS.md) for the evaluation policy that applies to all prizes). Evaluators will inspect commit histories and the posting history of vouching accounts. Volume that is clearly manufactured (fresh accounts, purchased engagement) does not count, regardless of the headline number. + +- [ ] **Upstream adoption.** The theme engine is merged into `logos-design-system` and `logos-basecamp` `master` and is present in a released Basecamp build. This is the one adoption signal the submitter cannot manufacture: it means the maintainers took the design, not just the demo. +- [ ] **15 third-party themes** published by **at least 10 authors independent of each other and of the submitting team**, each installable by an evaluator from a public catalog with no manual file copying, and each rendering the shell correctly (no unreadable text, no invisible controls) under the validator. Themes must be publicly hosted on a mainstream forge (GitHub, GitLab, Codeberg, etc.) with a genuine history — a real author working over time, not a bulk import. Trivial recolours of one another do not count as distinct themes. +- [ ] **At least 3 of those 10 authors have no prior code contribution to any Logos repository.** The point of this prize is that theming is a contribution surface for people the stack currently has no on-ramp for; this criterion measures whether that actually happened. Evaluators will check contribution history across the `logos-co` and `logos-blockchain` organisations. +- [ ] **5 third-party Basecamp apps** (`ui_qml` modules) shipped by developers independent of each other and of the submitting team that are **theme-clean**: they render correctly under all three initial themes plus a fourth chosen by the evaluator, with no hardcoded colours in place of tokens. Apps that hardcode their palette and merely happen to sit inside a themed shell do not count. +- [ ] **Sustained authorship**: the 15 themes are published over **at least 2 months**, with **at least 5 new themes in each of those months**. A single launch-week burst does not qualify, however large. Publication dates are verifiable from catalog releases and commit history. +- [ ] **20 testimonials on Discord** and **20 on Twitter/X** vouching for the theming feature, from accounts with real history. Testimonials should say which theme the person is running and what they used the theme system for; screenshots of Basecamp under a community theme are encouraged. Account history will be checked. +- [ ] **50 on-chain testimonials** submitted through the testimonial mini app on the official Logos zone, from **at least 50 distinct accounts**, each clearly identifying this submission's theming work, with the same anti-Sybil standard as [LP-0021](LP-0021.md). *This criterion applies only if the testimonial mini app is live when this prize opens; if it is not, the criterion is waived and the Discord and Twitter/X counts above rise to **35 each**.* + +> **On install counts.** Basecamp ships no telemetry and this prize does not add any, so "number of users" is not a criterion. Catalog release-asset download counts may be submitted as supporting colour, but they are not primary evidence and will not substitute for any criterion above. + +## Design Decisions Left to the Submitter + +The following are deliberately not prescribed. A submission must pick a position on each, document it, and justify it: the reasoning is part of what is evaluated. + +- **What is the theme document?** JSON, a restricted QML-object subset parsed as data, or something else. The hard constraint is that it must not be evaluated as code in the shell process. A submission should say how it reached that guarantee, not merely assert it — the `ui_qml` sandbox exists precisely because "it's only markup" turned out to be false once before (finding F-008). +- **How far past colour does a theme reach?** Colour, spacing, and typography are required. Backgrounds, icon replacement, per-component overrides, animation, and window chrome are open. Each thing a theme can control is a thing every future component must honour, so the boundary is a maintenance commitment, not a feature list — argue for where you drew it. +- **Fonts.** Themes may reference the bundled families, or ship their own. Shipping font files means the shell parses untrusted font binaries, which is a real attack surface; restricting to bundled families closes it and costs expressiveness. Either is defensible; pick one and say why. +- **How does a theme reach the design system?** The design system is linked `STATIC` into `main_ui`, and the `ui_qml` sandbox interceptor deliberately prevents a module directory from answering `Logos.*` imports. Whatever path a package theme takes into `Theme.palette`, it must not weaken that rule. +- **Where do themes live on disk, and who installs them?** A new LGX `type`, a reuse of an existing one, or something outside the package system entirely. If a new type, `logos-package-manager` needs to route it, and that is an upstream change to argue for. +- **Do apps get to extend the token set?** An app with genuinely app-specific surfaces may want tokens the shell has no opinion about. Allowing that risks a token space nobody can theme completely; forbidding it pushes app authors back to hardcoded colours. State a position. + +## Scope + +### In Scope + +- The runtime theme engine in `logos-design-system`, and the token-cleanup and appearance UI in `logos-basecamp`. +- The theme document format, its versioning, and its validation. +- Three initial themes (light, high-contrast, expressive), authored through the public path. +- Authoring guide, starter template, validator, and preview. +- Theme packaging as LGX and distribution through a Logos module catalog. +- Upstream PRs to every repository the above touches. + +### Out of Scope + +- **Theming other Logos apps' internals.** This prize themes the shell and everything built on `Logos.Controls`. An app that draws its own widgets is that app's problem. +- **Per-app theme overrides** — one active theme applies shell-wide. +- **A theme marketplace, payments, ratings, or curation.** Publishing and installing is in scope; deciding which themes are good is not. +- **Building the decentralised software directory itself.** If it exists, integrate; if it does not, the catalog path suffices. This prize does not fund that mechanism. +- **Layout restructuring.** A theme restyles; it does not move, add, or remove UI. +- **Windows support** — Basecamp's supported desktop targets for this prize are Linux and macOS. +- **Retheming Logos apps' legacy Qt Widgets surfaces** beyond the four `setStyleSheet` sites named above. + +## Prize Structure + +- **Total Prize:** TBD +- **Effort:** Medium + +## Eligibility + +Open to any individual or team. Submissions must be original work. Teams must hold the rights to all submitted code and agree to license it under MIT or Apache-2.0. + +Third-party themes and apps counted under **Adoption** must come from authors independent of the submitting team; a team member's second account, or a contractor engaged by the team to produce themes, does not count as an independent author. + +## Submission Requirements + +- Public repository (dual licensed MIT **and** Apache-2.0) containing the theme engine work, the theme format specification, the validator, the starter template, and the three initial themes. +- Links to the upstream pull requests in `logos-design-system`, `logos-basecamp`, and any other repository touched, with their merge status. +- The three initial themes published as installable packages in a public catalog, with the `logos-repo.json` URL so evaluators can install them through the package-manager UI / `lgpd`. +- The theme authoring guide and the complete token reference. +- Measured evidence for the performance criteria (switch latency, cold-start delta, memory) on both supported platforms, and the published WCAG contrast measurements for the high-contrast theme. +- Evidence for each adoption criterion: links to the 15 themes and their repositories and authors, the 5 theme-clean apps, per-month publication counts so the sustained-authorship criterion can be checked, and the Discord, Twitter/X, and (where applicable) on-chain testimonials. +- A narrated video walkthrough (see [demo requirements](../README.md#evaluation-policies)) covering: installing a theme from a catalog as an end user, switching themes live with apps open, a third-party app picking up the theme, the reset path recovering from a deliberately unusable theme, and a malformed or hostile theme being rejected. +- FURPS self-assessment as part of the solution (see [solution template](../solutions/LP-0000.md)). +- GitHub issues filed for any problems encountered with Logos technology. + +## Evaluation Process + +By default, submissions are evaluated first-come-first-served against the success criteria. The first submission that meets **all** criteria — functionality gate and adoption alike — wins. + +Because the adoption criteria require sustained authorship over at least two months, a submission cannot qualify until that window has elapsed. Builders are encouraged to land the engine upstream early and start accruing community themes while continuing to develop, rather than treating the build and the adoption push as sequential. + +Evaluators will independently build the modified Basecamp from a clean environment, install themes from the submitted catalog through the normal package-manager path, and author a fourth theme from the guide alone — if the authoring guide is not sufficient to produce a working theme without asking the submitter, the usability criteria are not met. Evaluators will also run their own malformed and adversarial theme fixtures against the engine. Technical follow-up questions may be asked to verify authorship and understanding. + +The following policies apply to all prizes (see [evaluation policies](../README.md#evaluation-policies)): + +- **Submissions:** each builder (or team) is allowed a maximum of **3 submissions** per prize, with at most **one submission/review per week**. +- **Feedback:** initial evaluation feedback is limited to a pass/fail indication against the success criteria. + +## Resources + +- [`logos-co/logos-design-system`](https://github.com/logos-co/logos-design-system) — `Logos.Theme` (`Theme.qml`, `ColorPalette.qml`, `DarkTheme.qml`, `Spacing.qml`, `Typography.qml`) and `Logos.Controls`; the storybook is the fastest way to see the token surface +- [`logos-co/logos-basecamp`](https://github.com/logos-co/logos-basecamp) — the shell. `docs/spec.md` (§ *QML App Sandboxing*, § *Distribution*, § *Future Work*), `docs/project.md` (§ `QmlSandbox`), `app/restricted/`, `tests/sandbox/`, and `src/CMakeLists.txt` for how the design system is linked in +- [`logos-co/logos-package`](https://github.com/logos-co/logos-package) — the LGX package format and `lgx` CLI; `docs/spec.md` covers the manifest schema, the `type` field, variants, content hashing, and signature verification +- [`logos-co/logos-package-manager`](https://github.com/logos-co/logos-package-manager) — install routing by package type +- [`logos-co/logos-modules-release-base`](https://github.com/logos-co/logos-modules-release-base) and [`logos-modules-release-action`](https://github.com/logos-co/logos-modules-release-action) — running a catalog: `logos-repo.json`, `index.json`, trusted signers +- [`logos-co/logos-module-builder`](https://github.com/logos-co/logos-module-builder) — `mkLogosModule` +- [WCAG 2.1 contrast minimums](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) — the basis for the high-contrast theme criterion +- Prior art worth reading before designing the format: VS Code's [colour theme contribution point](https://code.visualstudio.com/api/references/theme-color) (a large, versioned, data-only token surface with documented fallbacks), and Qt Quick Controls' [`Universal`/`Material` style attached properties](https://doc.qt.io/qt-6/qtquickcontrols-styles.html) (why per-component overrides get expensive) +- [LP-0023](./LP-0023.md) — LEZ Program Registry; the closest existing precedent for publishing and discovering third-party artefacts in this ecosystem, and a reference for the adoption-first evidence standard +- [LP-0021](./LP-0021.md) — LEZ Zone Wallet; source of the testimonial mini app referenced under *Adoption* + +## Potential for Subsequent λ Prizes + +This prize covers the **first adoption tranche** for Basecamp theming. A follow-up λPrize is expected with higher authorship thresholds, adapted to the phase the ecosystem is in at that time, and may extend the system into areas explicitly out of scope here — notably discovery and curation once there are enough themes for those questions to be meaningful, and per-app or per-workspace theming. + +If a decentralised software directory ships after this prize opens, a subsequent λ Prize may cover migrating theme distribution onto it from the catalog path.