Settings extensions — plan-included, no Store tiles

Maintainer, 2026-10-04: "we have many things in the app store which actually link to the settings tab. in these cases, show on the front page how to use the feature, maybe with a video … then link to the settings. … we should not see individual apps for google maps etc. just settings tab." Two follow-ups in the same session: "you don't need to install these packages bit by bit. they should just come with the sub" and "up to the level of the sub of the user — if i am a pro user, i have a right to enter my google maps key, etc.", and on review: "it must go to settings apps. we must have for user, one for instance. then settings inside the corresponding apps."

This page records the scan and the plan. Status: proposed, no code changed yet.

The rule we are moving to

A settings extension is a package whose user-facing surface is configuration: a key, a provider choice, an account connection, a login. For those:

  1. No Store tile and no launcher app. The package keeps its Store root (that is where its code, guide and tests live), but the catalog and the Home launcher stop listing it as something to Get.
  2. No install. It is not copied into the viewer's space. Its settings appear as a section in its settings home the moment the viewer's plan covers its tier.
  3. Plan-included, up to the viewer's tier. The gate is SubscriptionFact.Covers(package.tier), evaluated live. A pro viewer sees every free, personal and pro extension; a free viewer sees the free ones and an upsell line for the rest. No _Access record and no _Entitlements record is minted. That keeps us inside "no one should have any access, just through subs and tiers" (2026-09-30, AccessThroughPlanTests) and away from the free grants on sight that FreeGrantRetraction removed. A downgrade hides the section and keeps the stored key, so an upgrade restores it.
  4. A how-to front page instead of an app. The package's cover becomes "how to use it": a short guided tour of the screens to click, what to tell the agent, and one primary button, Open settings, deep-linking to the section in its settings home.

Purchasing is plans only

Maintainer, 2026-10-04: "so generally, the purchase functionality will be limited to purchasing the pro / personal / whatever". What a person buys is a plan tier (personal, pro, team, …). No package is bought on its own: a package's tier says which plan includes it, and holding that plan is the whole entitlement. Settings extensions are the first application of this rule, not an exception to it.

Measured 2026-10-04 across the fleet: exactly one package still carries a per-package price — Manufacturing (MeshWeaver.Manufacturing, price: 900 CHF, tier: enterprise). Every other root is priced through its tier already. Consequences for the Store:

The App Store disappears — it becomes "Manage apps"

Maintainer, 2026-10-04: "in instance admin, say 'Manage' then the app store will become a guide to managing the apps, including their settings", then "so app store will disappear in this sense. it will just be manage this instance" — "i.e. manage the apps on this instance." Once nothing but plans is sold, there is nothing left to shop for app by app, so there is no App Store surface for users at all:

Who Where What they see
Every user Home / the launcher the apps their plan includes, nothing else. Each app's front page is its how-to (tour, what to tell the agent, Open settings). An app outside the plan is simply absent. Upgrading is the Plans page and nothing more
Instance admin Admin app › Manage apps every app on the instance with its tier and status (needs configuration / ready / error). Each app's page says what it needs to run and embeds its instance settings section inline (shared keys, registrations, defaults)
Anonymous visitor (public instance) the Plans page what each tier includes, as the storefront. It replaces the catalog

The old store becomes the Add button of Manage apps (maintainer: "the 'store' must be the 'add'"). Manage apps lists the apps that are on this instance. Add opens the registry's catalog of apps that are not here yet: the same cards, guide and tier as today's Store, but with one action, Add to this instance, which runs the existing SystemInstall provisioning. Remove is the inverse. Browsing and choosing apps is therefore an admin act for the instance, never a user purchase.

Adding an app is what makes its settings exist. Settings sections are contributed by the app, so they appear the moment it is added and disappear when it is removed:

  1. The admin adds the app under Manage apps → its instance section appears on its page there.
  2. Its user sections appear in the user settings app (or the host app's Settings tab) for every user whose plan covers its tier.
  3. Values resolve user → instance: a user's own key wins, otherwise the instance key applies, otherwise the section says what is missing.

Example — Google Maps (pre-installed on the public instance): it is listed under Manage apps as added. The global admin opens it and sets one Maps key for the whole system, and every map on the instance renders with Google from then on. Today that key exists only in the deployment configuration, so setting it needs a redeploy. A user may still enter their own key in the user settings app › Maps, which is used for their maps instead.

Keys go to Key Vault (maintainer: "key goes to KV"), never into node content. The instance section reuses the existing path in Hosting/Deployment/Source/SecretDialog.cs, rather than adding a new one:

Manage apps (the apps on this instance) is the instance settings app for apps, not a second surface beside it. Users, access, plans and seats stay in their own Admin tabs. Each app's instance section is the same UiContribution, rendered inside that app's management page, so an admin reads what an app does and configures it in one place.

The Store package survives as the engine, not as a destination: plans, checkout, subscriptions, licences, coupons, install-defaults and the tier gate. Its catalog, cover CTAs and Extensions shelf are retired. Cover pages become the apps' front pages (users) and management pages (admins).

Three settings homes — and only three

Every setting lives in exactly one of three places, chosen by whose setting it is:

Home Address Holds Who edits
User settings app /{user}/Settings (the person app) what belongs to one person and no single app: my map keys, my channel links, my account connections, my signing authority the person
Instance settings app the Admin app (AdminAppNodeType) › Manage apps what belongs to the whole installation: the shared provider keys, the fallback map key and default renderer, bot/app registrations, system mail, payments global admin
The app's own settings the host app's Settings tab (e.g. AI/AiThreads › Settings) how one app works: the Threads app's models and harnesses, Signature's providers, HomeAssistant's connection the app's user

The home is not a new field: it is the package's existing hostedIn. {user}/Settings means the user settings app, Admin the instance settings app, and an app path (AI/AiThreads) that app. A package with both a personal and an instance half (Maps, the channels, Mail) contributes one section to each. No setting is ever offered in two homes for the same scope, so nobody has to guess where to look.

Scan — every Store/Plugin root in the fleet

Scanned 2026-10-04 at origin/main of MeshWeaver, MeshWeaver.Plugins, .Crm, .Education, .FundReporting, .Manufacturing, .Reinsurance and .SocialMedia: 109 packages. Core ships no Store/Plugin root. Crm, Education, FundReporting, Manufacturing and Reinsurance have no settings-shaped package. Their keyword hits (Pricing's "simulation settings", Chess's "settings locked") are false positives.

A — pure settings extensions: remove the tile, become a settings section

Package Today Tier User settings app Instance settings app App's own settings
GoogleMaps app: true, opens GoogleMaps/Examples; key only in the deployment config free Maps: my Google Maps key Maps: fallback key, default renderer —
AppleMaps app: true, installs AppleMaps/MyMaps (holds the key) + Examples free Maps: my Apple Maps Server key Maps: fallback key —
OpenStreetMap app: true, opens Examples; needs no key free — Maps: the keyless default renderer —
Maps base MapControl, not an app free hosts Maps hosts Maps —
MyAi ("AI Settings") app: true, entry MyAi/Settings free AI: my agent/skill/model sources — —
Providers app: true, entry ProvidersApp/area/ProviderSetup free — AI › Providers: the shared keys and tiers Threads › Settings › Models: my own keys
Anthropic, OpenAI, AzureFoundry, AppleIntelligence hostedIn: AI/AiThreads, slot modelProvider, offered on the Extensions shelf free — shared key / endpoint Threads › Settings › Models: rows (my key)
ClaudeCode, Codex, Copilot, Cursor, Grok, OpenCode, Antigravity (+ Acp runtime) hostedIn: AI/AiThreads, slot harness, per-user install into {you}/Harness/* pro — CLI availability (feature flags) Threads › Settings › Harnesses: enable + /login
WebSearch tile; entry ProvidersOverview pro — AI › Web search: search key Threads › Settings: on/off per thread default
Teams, WhatsApp, iMessage tiles, "talk to your assistant on X" personal Channels: link my account / my Mac bridge Channels: bot / Business API registration —
Voice tile; installs Voice/Agent, Prompt, Station pro Channels › Voice: pair my satellite — —
Mail tile; system mail + Graph mailbox tools personal Connections › Microsoft 365: my mailbox consent Mail: system mail + intake —
Stripe tile; instance payments free — Payments —

B — real apps with a settings half: keep the app, move the credentials

Each of these is a dashboard people use daily. The app stays and gets its own Settings tab, which holds its connection (OAuth client, key, account). The app's empty state links to that tab instead of walking the user through four fields on the app page. A credential that is the person's across apps (signing authority) stays in the user settings app.

Package Repo Goes into the app's own Settings
AppleWeather (MyWeather) Plugins WeatherKit team/key id + .p8
AppleMusic (MyMusic) Plugins MusicKit developer token / user token
Google (MyGoogle) Plugins Google OAuth client + consent
ICloud (MyICloud) Plugins app-specific password
HomeAssistant (MyHome) Plugins base URL + long-lived token
Signature (MySignatures) Plugins provider credentials. Signing authority stays in the user settings app, where it already is (Signature/PersonAppTabs/SigningAuthority)
X, LinkedIn, YouTube SocialMedia account / archive import

C — adjacent, not settings (decide separately)

DefaultViews, EntityViews, GraphViews, Radzen, OgCard, Export, Analysis and BusinessRules are app: true but open an Examples/Guide page. They are capability packs (controls, view packs), not apps and not settings. Their natural home is the docs. Out of scope here and listed so nobody re-scans them.

Consolidation — every package gets exactly one place

Maintainer, 2026-10-04: "see what you want to consolidate. we need order." Every one of the 109 Store/Plugin roots lands in exactly one of five places. Today about 40 of them present themselves as tiles; after this, a user sees about a dozen apps.

Place What it is Who sees it
App a launcher tile you work in daily users whose plan covers it
Section of an app a module, channel or course inside a bigger app users of that app
Settings section in one of the three settings homes per home (user / instance admin / app)
Developer app examples, showcases, builder tools builders (free)
Capability no surface of its own: a menu action, a control, a runtime nobody as a tile; listed in Manage apps

Apps — what stays a tile (13 + vertical suites)

App Absorbs Notes
Threads (AI) Chat; providers and harnesses as its Settings the AI home
Learning (Edu) all 14 courses (Education's 11; Reinsurance's RiskTransfer, SwissSolvencyTest, ReinsurancePractice), LearningRoadmap, Training tours courses stop being tiles; one catalog inside the app, filtered by plan and language
Approvals
Signature providers in its Settings; signing authority in user settings
Feedback
CRM (Crm)
Social Media (SocialMedia) LinkedIn, X, YouTube, Marketing networks become channels inside one app, each with its connection in the app's Settings
Google, iCloud personal data apps; connection in the app's Settings
Home Assistant, Apple Music, Apple Weather personal apps; connection in the app's Settings
Games Chess, RolePlay, QualityTime + QualityTimeDe one tile; the language twin is picked by the viewer's language
Reinsurance (enterprise) Reinsurance, Claims, Underwriting, Pricing, LossModelling, Planning, Ifrs17, SST, ILS, EventMonitoring, Portfolio, PortfolioOptimization, TaskManagement, ReinsuranceDemo, Cornerstone one suite app, modules as sections
Manufacturing, Fund reporting (enterprise) one app per vertical repo

Admin — inside the Admin app, never a user tile

Admin section Packages
Manage apps (+ Add) the Store engine; every app's instance settings
Operations Hosting, Governance, BuildServer, AzureCostManagement, Observability
Instance settings Stripe (payments), Mail (system mail), shared AI keys, map keys, channel registrations

Settings sections — no tile (see the scan above)

GoogleMaps, AppleMaps, OpenStreetMap, Maps · Anthropic, OpenAI, AzureFoundry, AppleIntelligence, Providers, MyAi, WebSearch · the seven harnesses + Acp · Teams, WhatsApp, iMessage, Voice, Mail (personal half) · Notifications (already the person app's notification preferences) · Mcp (user settings › Connections: connect an MCP client).

Developer app — one tile for builders

Section Packages
Examples DefaultViews, EntityViews, GraphViews, Radzen, Analysis, OgCard, Export, the three map galleries
Showcases Northwind, DoublePendulum, FractalStars, ThreeBody
Builder tools DataModelling (model browser), BusinessRules (guide), Testing (in-mesh xunit)

Each package contributes its section the same way settings sections are contributed, so a section exists only when its package is on the instance.

Capabilities — no surface of their own

Essentials, Publish, Import, Indexing, Collaboration (review/track changes in any document), Export (the PDF/DOCX menu action — its gallery is in Developer), OgCard (markdown embed), RemoteControl (the Present on screen menu action), Video (the explainer-video skill), Training (the tour player every front page uses), AzureBlob, Hosting.Instance. They appear only in Manage apps, where an admin can see they are present.

Order of the work

  1. Settings sections + three homes (phases 1–3 above). This removes the largest group of false tiles, about 25.
  2. Developer app. It is additive, so it can run in parallel with 1, and it removes 15 tiles.
  3. Suites: Learning (courses), Social Media, Games, Reinsurance. Each is one PR per suite in its own repo. The suite app lists its sections, and the members drop app: true.
  4. Admin › Operations + Manage apps (+ Add), then retire the user-facing catalog.

What exists already (reuse, do not rebuild)

Plan

Phase 1 — the contract (core + Store)

  1. PluginContent.surface: "settings" (core, beside hostedIn/extensionSlot): declares a settings extension. hostedIn names its home ({user}/Settings, Admin, or an app path), a list where a package has both a personal and an instance half; each half is a UiContribution naming the section and the package's own layout area. One field, read by every consumer, so the catalog, the launcher and the three settings homes cannot disagree.
  2. New gate requireTier on UiContribution (core vocabulary, Store evaluates it): the section shows iff Subscriptions.Effective(viewer).Covers(package.tier). It replaces requireAddressAccess for settings extensions, because Read on the package root presupposed an install. Tests: free/personal/pro × package tier matrix; lapsed plan → hidden; key retained.
  3. The three homes host the sections. User settings app: Maps, AI, Channels, Connections (context: PersonApp). Instance settings app: Maps, AI, Channels, Mail, Payments (Admin app tabs, global admin only). App settings: a Settings tab on each host app, fed by a new context: AppSettings contribution addressed to that app (AI/AiThreads first, replacing today's Extensions shelf there). Each lists the covered sections, and the uncovered ones as one upsell line ("Included in Pro"), never as a buy button.

Phase 2 — the App Store goes, Manage apps comes

  1. Home launcher skips surface: settings roots (StoreCatalogLayoutAreas, launcher). app: true is removed from every A-row package.
  2. The user-facing catalog and the Extensions shelf are retired; the launcher lists the apps the plan covers, and the Admin app gains Manage apps (every app, status, inline instance settings) with Add (the registry catalog, Add to this instance via SystemInstall) and Remove. The per-package CoverCta/Get is retired, and the Plans page lists what each tier includes.
  3. Migration: existing per-user installs ({you}/Harness/*, AppleMaps/MyMaps, …) and their stored keys are read in place by the new sections. No re-entry. Retire the copies only after the section reads them, through Store/InstallRequest uninstall, not by hand.

Phase 3 — the how-to front page per package

  1. Each A-row package's cover body is rewritten to how to use it: what it does in one line, a Training/Tour (3–5 steps: open Settings → the tab → paste the key → try it, with the exact sentence to tell the agent, e.g. "show the office on a map"), then Open settings. A Video-rendered MP4 is added where a moving demo helps (harness /login, channel linking).
  2. Maps-specific: the instance Google Maps key is set from Manage apps › Google Maps into Key Vault (SetSecrets) instead of a deployment edit, and a user's own key from the user settings app › Maps. Today neither the admin nor a user can set one without a redeploy.

Phase 4 — B-row apps

  1. Give each B-row app its own Settings tab (the same AppSettings contribution) and move its connection there. The app's empty state becomes "Connect in Settings →". The apps keep their tiles.

Order and repos

Step Repo Gate
1–2 contract + gate MeshWeaver (core) then Store sealed set before Plugins consumes it (Core-ref:)
3–6 three homes, catalog, shelf, migration core (AppSettings context, Admin tabs) + Plugins (Store, AI, Maps) Store Tests area: tier matrix, migration reads old keys
7–8 covers + tours, Maps key Plugins (each A-row package) Training/Tour renders; render_area of each cover
9 B-row connections Plugins + SocialMedia per-app Tests

After each landing, recycle the per-node hubs that serve the changed types: Store/Catalog, Store/Plugin, the person app on a test user, the Admin app, AI/AiThreads. Then verify on the public instance as a free user and as a pro user that the sections, the upsell and the Open-settings links behave as stated above.

Rule this amends

AGENTS.md ("publishing grants nobody anything") says content is reached through a plan tier and only once the user acquires it. For surface: settings packages the plan tier alone is the acquisition: no Get, no install, no minted grant. Phase 1 updates that sentence with the scoped exception, so the rule and the code are changed together.

Decisions