How OpenLogi Uses `-dev` Identifiers to Isolate the Development Bundle from Production
OpenLogi isolates its development bundle from production by hard-coding the Channel::Dev identifier throughout the build process, ensuring separate bundle IDs, socket paths, and Launch Service registrations.
The AprilNEA/OpenLogi repository maintains two distinct macOS application bundles: a production release (OpenLogi.app) and a sandboxed development version (OpenLogi-dev.app). By systematically applying -dev identifiers across the build pipeline in xtask/src/commands/macos/dev_bundle.rs, the development bundle achieves complete runtime isolation, preventing configuration leakage and socket conflicts with production instances.
Channel-Based Isolation Architecture
The isolation mechanism centers on the Channel enum, with the development bundle explicitly selecting Channel::Dev to propagate dev-specific metadata through every build stage.
Hard-Coded Dev Channel Selection
In xtask/src/commands/macos/dev_bundle.rs, the macos::dev_bundle command explicitly instantiates the channel as Channel::Dev at lines 34-36. This constant propagates through all subsequent build steps, ensuring that the main application, embedded agents, and overlay helpers receive consistent dev-specific stamping.
Bundle Identifier Stamping
The identity::stamp(&app, CHANNEL, components) function (lines 102-105 of dev_bundle.rs) writes the final bundle identifier into each component’s Info.plist. When CHANNEL is Dev, the resulting identifier becomes org.openlogi.openlogi-dev rather than the production org.openlogi.openlogi, creating distinct macOS application identities that the system treats as separate entities.
File System and Socket Isolation
Physical separation on disk prevents accidental data sharing between environments by using dedicated directory constants.
Dedicated Development Directory
The core crate defines DEV_APP_DIR as "openlogi-dev" in crates/openlogi-core/src/paths.rs (lines 40-42). This constant serves as the root directory for all development-specific configuration, distinct from the standard "openlogi" directory used in production XDG config paths.
Separate IPC Socket Paths
The dev agent writes its Unix socket to …/openlogi-dev/agent.sock, while production uses …/openlogi/agent.sock. As noted in crates/openlogi-ipc/src/transport.rs (lines 25-27), this path divergence ensures that local macOS dev bundles use the sibling openlogi-dev profile, preventing development agents from occupying or interfering with production sockets even when both bundles run concurrently.
macOS Bundle Configuration
macOS-specific metadata and system registrations maintain the boundary between builds through dedicated resource files and selective registration.
Development Info.plist
The dev bundle utilizes a dedicated plist template located at crates/openlogi-desktop/bundle/desktop-dev/Info.plist. During the build, the APP_PLIST constant in dev_bundle.rs (lines 37-42) references this template, ensuring the final OpenLogi-dev.app contains dev-specific bundle metadata rather than the production configuration generated by cargo-bundle.
Launch Services Registration
After construction, the register_with_launch_services function (lines 50-55 of dev_bundle.rs) executes lsregister to associate the openlogi:// URL scheme with the dev bundle. Because the dev bundle identifier (org.openlogi.openlogi-dev) differs from production, this registration affects only the current session without overwriting the installed production bundle's URL handlers.
Helper and Agent Isolation
Embedded components inherit the dev channel's isolation properties to prevent cross-environment process communication.
Embedded Helper Components
When OPENLOGI_DEV_AGENT is not set to 0, the dev bundle builds and embeds agent and overlay helpers under the openlogi-dev profile (lines 72-98 of dev_bundle.rs). These helpers use the dev socket path and inherit the -dev identifiers, preventing accidental connections to a production agent running on the standard socket.
Transport Layer Boundaries
The IPC transport layer explicitly recognizes the openlogi-dev profile as a sibling configuration. This architectural boundary ensures that even at the network transport level, development bundles route messages exclusively to dev sockets, maintaining strict separation from production IPC endpoints.
Building the Development Bundle
To generate an isolated development build, invoke the xtask command from the repository root:
cargo xtask macos dev-bundle --binary target/debug/openlogi-desktop
This command orchestrates the isolation logic, producing OpenLogi-dev.app with all -dev identifiers stamped throughout the bundle structure, sockets, and Launch Services metadata.
Summary
- Channel-based isolation: The
Channel::Devconstant hard-coded indev_bundle.rsdrives all dev-specific stamping logic viaidentity::stamp. - Separate file paths:
DEV_APP_DIR("openlogi-dev") inpaths.rsensures distinct XDG config directories and socket locations. - Unique bundle identifiers: The stamp function applies
org.openlogi.openlogi-devto all components, preventing macOS from conflating the apps. - Dedicated plist templates:
desktop-dev/Info.plistprovides dev-specific macOS metadata separate from production. - Launch Service isolation: Separate bundle IDs prevent URL scheme conflicts, with
lsregistertargeting only the dev bundle. - Helper embedding: Dev helpers connect exclusively to
openlogi-dev/agent.sock, avoiding production agent interference.
Frequently Asked Questions
What is the difference between OpenLogi.app and OpenLogi-dev.app?
OpenLogi.app represents the production bundle built via cargo-bundle using standard Cargo.toml metadata. OpenLogi-dev.app is generated by the macos::dev_bundle xtask command, featuring the -dev suffix in its bundle identifier, dedicated socket paths at …/openlogi-dev/agent.sock, and isolated Launch Services registrations to prevent conflicts with the production version.
How does the dev bundle prevent socket conflicts with production?
The dev bundle uses the DEV_APP_DIR constant ("openlogi-dev") defined in crates/openlogi-core/src/paths.rs to construct its socket path, whereas production uses the "openlogi" directory. This physical path separation, enforced by the IPC transport layer in transport.rs, ensures development agents cannot bind to or communicate through production sockets.
Can I run both production and dev bundles simultaneously?
Yes. Because the dev bundle carries the distinct identifier org.openlogi.openlogi-dev and registers separately with Launch Services via lsregister, macOS treats it as a separate application entity. The separate socket paths in the XDG config directories allow both agents to run concurrently without state interference or cross-communication.
Where is the dev bundle build logic located?
The primary orchestration resides in xtask/src/commands/macos/dev_bundle.rs, which coordinates channel selection, identity stamping via identity::stamp, helper embedding, and Launch Services registration. Path constants for the dev environment are defined in crates/openlogi-core/src/paths.rs, while the identity stamping utilities live in xtask/src/commands/macos/bundle/identity.rs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →