Problem
An out-of-process ui_qml backend can resolve a different persistence root from Basecamp during an ordinary installed-app launch.
Basecamp 0.2.3 resolves its default tree with QStandardPaths::AppDataLocation after setting application name LogosBasecamp. ViewModuleHost then starts ui-host with a normal QProcess. When no --user-dir or LOGOS_USER_DIR override was supplied, the child has no explicit parent data root and its own AppDataLocation is based on application name ui-host.
This was reproduced by Atomic Swaps: core modules write under .../Logos/LogosBasecamp/module_data, while the swap_ui backend writes config.json and receipts.jsonl under .../Logos/ui-host/module_data/swap_ui. Every default Basecamp variant on the machine therefore reaches the same UI-host directory. The current config contains signing keys, so this breaks both profile correctness and secret isolation.
The explicit-profile path behaves differently: Basecamp's --user-dir handling calls qputenv("LOGOS_USER_DIR", ...) before spawning the child, and QProcess inherits it. That explains why isolated --user-dir smoke tests can pass while an ordinary installed launch remains unsafe.
Downstream evidence: logos-co/eth-lez-atomic-swaps#99
Required behavior
- Every
ui-host receives the exact persistence root already resolved by its owning Basecamp instance, including ordinary launches with no override.
- The child must not independently derive profile identity from its own Qt application name.
- The contract should be explicit and testable (for example, a child-process environment value or a typed host capability), rather than each UI module guessing Basecamp paths.
- Existing shared UI-host data must not be silently treated as belonging to whichever profile launches first. Receipt recovery and secret migration need separate, explicit policies.
Regression gate
Run two Basecamp profiles/variants without a manually exported LOGOS_USER_DIR, plus two explicit --user-dir instances. Load the same ui_qml test module in each and assert:
- each backend receives its parent's exact resolved module-data root;
- four distinct sentinel files are written under four distinct profile trees;
- no sentinel is written under the generic
Logos/ui-host tree;
- relaunching one profile sees only its own sentinel.
This blocks the public Atomic Swaps Basecamp journey until fixed and released.
Problem
An out-of-process
ui_qmlbackend can resolve a different persistence root from Basecamp during an ordinary installed-app launch.Basecamp 0.2.3 resolves its default tree with
QStandardPaths::AppDataLocationafter setting application nameLogosBasecamp.ViewModuleHostthen startsui-hostwith a normalQProcess. When no--user-dirorLOGOS_USER_DIRoverride was supplied, the child has no explicit parent data root and its ownAppDataLocationis based on application nameui-host.This was reproduced by Atomic Swaps: core modules write under
.../Logos/LogosBasecamp/module_data, while theswap_uibackend writesconfig.jsonandreceipts.jsonlunder.../Logos/ui-host/module_data/swap_ui. Every default Basecamp variant on the machine therefore reaches the same UI-host directory. The current config contains signing keys, so this breaks both profile correctness and secret isolation.The explicit-profile path behaves differently: Basecamp's
--user-dirhandling callsqputenv("LOGOS_USER_DIR", ...)before spawning the child, andQProcessinherits it. That explains why isolated--user-dirsmoke tests can pass while an ordinary installed launch remains unsafe.Downstream evidence: logos-co/eth-lez-atomic-swaps#99
Required behavior
ui-hostreceives the exact persistence root already resolved by its owning Basecamp instance, including ordinary launches with no override.Regression gate
Run two Basecamp profiles/variants without a manually exported
LOGOS_USER_DIR, plus two explicit--user-dirinstances. Load the sameui_qmltest module in each and assert:Logos/ui-hosttree;This blocks the public Atomic Swaps Basecamp journey until fixed and released.