Summary
Make Bundle.toml the primary user-facing distribution configuration, while retaining the existing Cargo metadata integration as a compatibility adapter. The same distribution engine should package Rake apps, ordinary Rust apps using other UI toolkits, and existing native executables.
This is an RFC for the complete current distribution API: configuration, CLI, planning, build integration, native components, resources, helpers, platform packaging, updates, release publication, extensions, and the Rust library. It does not propose replacing Rake's application/router/view APIs.
Status: design proposal, not implemented. All new fields, flags, functions, and defaults below require implementation and tests. Existing capabilities are identified separately. No end-to-end CEF bundle has been produced through the proposed path.
Motivation and goals
Packaging settings are easier to discover and review in a dedicated file than inside a large Cargo.toml. A project should normally run:
rake bundle
rake bundle --debug
rake bundle --plan --jsonRake should own mechanical distribution work: resolving declared inputs, collecting executables, staging native payloads, checking dependencies, signing, verification, archives/installers, and explicit release publication. Applications should declare their requirements and retain ownership of runtime behavior.
Silicon/CEF motivates several missing pieces: one main executable, a Chromium framework, and five macOS helper applications that share one Cargo binary but have distinct names and identities. It is an acceptance case for generic capabilities, not a reason to put a browser engine into Rake's runtime.
Goals:
- One authoritative configuration per invocation, with predictable paths and useful diagnostics.
- A small, readable starting file that can express the full existing configuration surface.
- No dependency on Rake's UI runtime or GPUI for packaging another application.
- Cargo and prebuilt inputs feeding the same validated model and worker pipeline.
- Existing consumers and valid configuration preserved; no silent loss of settings during migration.
- Reproducible native inputs and correct helper signing without an application-specific packaging script.
Non-goals for the first implementation: arbitrary build-command orchestration, a new plugin framework, config includes/inheritance, automatic adoption/re-signing of an already assembled .app, or automatic key creation/publication during bundling.
Current API and what should be reused
Source baseline: 5c818c4d5ee6721546663d7f7e5aac1710c9a6d0.
rake-dist-core::Configalready owns the portable configuration and validates plans.Config::plan_foris independent of Cargo metadata and native packaging tools.BundledDependencyalready lowers grouped dependencies into components, sidecars, resources, and runtime recipes.rake-distalready exposes planning, native execution, artifact reports, publication, and extension adapters without a Rake UI dependency.execution.rsalready resolves native components before the Cargo build, owns staging/output transactions, and producesDistributionrecords with hashes and trust evidence. However, execution currently assumes Cargo metadata and one selected main binary.rake-buildalready embeds build-time resource/update metadata. It currently reads Cargo package metadata directly; that must change for a first-class standalone file.- Existing framework recipes, locks, native loader checks, worker isolation, signing, release verification, and command/Rust extension contracts should be reused.
Coverage of the entire existing configuration
The standalone file should retain the existing names, nested fields, validation, and override semantics for all of these sections. This table is an API coverage map, not a replacement for the generated schema.
| Current surface | Standalone representation / intended treatment |
|---|---|
schema_version, name, identifier, icon, assets, resources | Same top-level keys; paths use the selected input root. |
build_number, package_version, minimum_system_version | Same top-level keys and native-version/deployment rules. Cargo semantic version is obtained from Cargo; prebuilt version is explicit. |
desktop | Preserve category, URL schemes, file associations, and localized labels. |
macos | Preserve formats, privacy strings, universal settings, plist, entitlements, signing identity, and notary profile. Add helper-app declarations. |
windows / windows.msix | Preserve formats, manifest, system DLL declarations, certificate/timestamp references, MSIX publisher and manifest. Remove implicit UI assumptions from the generic path. |
linux / linux.flatpak | Preserve formats, package name, desktop/AppStream metadata, baseline, per-format dependencies, Flatpak runtime/SDK pins and permissions. |
dependencies | Same prepared-tree convenience API, including executables, resources, licenses, and directory/framework/GStreamer library recipes. |
components | Same exact-target local or HTTPS/SHA-256 inputs, archive validation, and component locking. |
sidecars | Preserve ordinary helper installation and descriptor lookup; add Cargo-bin input without changing the existing file-path form. |
runtimes | Preserve built-in/custom recipes, component references, selected plugins, link policy, system dependencies, and options. |
target_overrides, format_overrides | Preserve current layering and replacement/merge rules. Do not invent implicit deep merging. |
updates | Preserve public update policy, provider keys, and installation-channel ownership. Runtime integration remains an explicit capability. |
release | Preserve publishers, required target/format matrix, custom required artifacts, signing references/commands, Sparkle tools, GPG/repository settings, and feed validity. |
custom_formats, component_recipes | Preserve explicit argv/Rust contracts, independent verification, bounded execution, and trust rules. |
web | Preserve base_path, routing, and offline through an adapter to the existing Web pipeline; do not silently ignore them. This does not make native prebuilt programs Web inputs or extend the currently supported Web runtime. |
Every currently valid field must either work with the standalone source or be rejected with a documented, specific unsupported-combination error. No parser may silently accept unknown fields, or ignore settings applicable to the selected source and target.
Proposed file model
Use the existing flat Config plus a separate input envelope:
- Required
schema_version = 1in a standalone file. - Required standalone
name,identifier, and[program]. [program]is a tagged choice:cargoorprebuilt.- Optional
rootselects the input root explicitly; it is not another configuration layer. programandrootare file/source-adapter fields, not a second copy ofConfigor an additional[app]identity section.- Keep strict unknown-key and source-specific validation. In particular, do not rely on unsupported combinations of Serde
flattenanddeny_unknown_fields; preserve useful field/file diagnostics.
Minimal Cargo example
# Bundle.toml
schema_version = 1
name = "My App"
identifier = "com.example.my-app"
[program]
type = "cargo"manifest defaults to Cargo.toml at the selected root. A single-package, single-binary project requires no further Cargo selection. The application need not depend on Rake's UI.
Cargo workspace selection
schema_version = 1
name = "Silicon"
identifier = "dev.silicon.browser"
minimum_system_version = "13.0"
[program]
type = "cargo"
manifest = "Cargo.toml"
package = "browser"
bin = "silicon"
features = []package and bin become required when selection is ambiguous. Error messages should list the available choices. One selected Cargo package per invocation is sufficient initially; the main binary and Cargo-built helpers share that package, target, profile, feature selection, and SDK bindings.
Version comes from the selected Cargo package. A competing program.version in Cargo mode is rejected. Existing native package_version and build_number overrides remain available.
Prebuilt executable example
schema_version = 1
name = "Native Viewer"
identifier = "com.example.native-viewer"
[program]
type = "prebuilt"
path = "build/{target}/native-viewer{exe}"
version = "1.0.0"
target = "aarch64-apple-darwin"This means a loose executable plus explicitly declared payload, not an existing application bundle. It must work with neither cargo nor rustc on PATH. Require a target in the file or via --target-triple in the first version, and verify the actual binary architecture. Reject conflicting targets, Cargo-only settings, and unsupported universal combinations.
The prebuilt path must not inherit a GPUI Windows manifest, require a Rake application runtime, or claim to install a working updater without explicit integration support.
Proposed Silicon / CEF example
This is an illustrative macOS configuration for a prepared, versioned SDK tree. The preparation step must supply the declared CEF license and exact matching SDK metadata; these files are not assumed to appear automatically in an upstream archive.
# Bundle.toml at the repository root
schema_version = 1
name = "Silicon"
identifier = "dev.silicon.browser"
minimum_system_version = "13.0"
[program]
type = "cargo"
package = "browser"
bin = "silicon"
[program.build_env]
CEF_PATH = { component = "cef" }
[dependencies.cef]
path = "vendor/cef/156.0.14/{target}"
licenses = ["CEF-LICENSE.txt"]
resources = { "Chromium-CREDITS.html" = "CREDITS.html" }
libraries = { path = "Chromium Embedded Framework.framework", recipe = "framework" }
[macos]
formats = ["app", "zip", "dmg"]
entitlements = "crates/browser/entitlements.plist"
[[macos.helper_apps]]
name = "Silicon Helper"
identifier = "dev.silicon.browser.helper"
bin = "silicon-helper"
entitlements = "crates/browser/entitlements.plist"
info_plist = "packaging/Helper.plist"
[[macos.helper_apps]]
name = "Silicon Helper (GPU)"
identifier = "dev.silicon.browser.helper.gpu"
bin = "silicon-helper"
entitlements = "crates/browser/entitlements.plist"
info_plist = "packaging/Helper.plist"
[[macos.helper_apps]]
name = "Silicon Helper (Renderer)"
identifier = "dev.silicon.browser.helper.renderer"
bin = "silicon-helper"
entitlements = "crates/browser/entitlements.plist"
info_plist = "packaging/Helper.plist"
[[macos.helper_apps]]
name = "Silicon Helper (Plugin)"
identifier = "dev.silicon.browser.helper.plugin"
bin = "silicon-helper"
entitlements = "crates/browser/entitlements.plist"
info_plist = "packaging/Helper.plist"
[[macos.helper_apps]]
name = "Silicon Helper (Alerts)"
identifier = "dev.silicon.browser.helper.alerts"
bin = "silicon-helper"
entitlements = "crates/browser/entitlements.plist"
info_plist = "packaging/Helper.plist"The framework is at the flattened SDK root consumed by the current CEF bindings, not an assumed Release/ subdirectory. The license is a license entry; Chromium credits remain a separately mapped app resource.
The same source binary is built once per distinct build input and copied into five wrappers. Each wrapper gets its declared identity, generated/validated plist, and explicit entitlement policy. info_plist is optional and can supply additional helper metadata such as activation behavior; it cannot silently override protected identity fields.
Helper input contract
bin = "worker"means a Cargo binary in the selected package.path = "bin/worker"means an existing executable, optionally relative to a declaredcomponent.- Exactly one is permitted. Represent that choice as an enum in the validated Rust model.
- Apply the same binary-input choice to ordinary
sidecars, preserving existingpathbehavior. - A
binreference is invalid with a prebuilt main program in v1. macos.helper_appsis separate fromsidecars: helper apps live inContents/Frameworksand have bundle identities, while ordinary sidecars retain their existing installed location andresources.helper()lookup.- Do not add helper-app fields to the existing installed descriptor without an independently versioned compatibility plan.
- Do not add arbitrary
locationor per-helper Cargo project fields before there is a concrete requirement.
For example, an ordinary Cargo worker is still small:
[[sidecars]]
name = "indexer"
bin = "indexer"Examples retaining the wider current API
These are independent fragments illustrating the existing configuration moved into the standalone file. They are not one universally valid application/release combination: native hosts, enrolled signing references, payloads, runtime integration, and format prerequisites still apply.
Resources, desktop integration, and platform settings
icon = "assets/icon.svg"
resources = [{ from = "assets/help.txt", to = "help.txt" }]
build_number = "12"
[desktop]
category = "developer_tool"
url_schemes = ["my-app"]
file_associations = [{ extensions = ["mynote"], name = "My Note", mime_type = "application/x-my-note" }]
[desktop.localizations.fr]
name = "Mes notes"
description = "Documents et notes"
[macos]
formats = ["app", "zip", "dmg"]
info_plist = "packaging/Info.plist"
entitlements = "packaging/app.entitlements"
# Existing local identity/profile references, never private credentials:
# signing_identity = "Developer ID Application: Example (TEAMID)"
# notary_profile = "existing-keychain-profile"
[macos.privacy]
NSCameraUsageDescription = "Capture an image for a document"
[windows]
formats = ["nsis", "msix"]
manifest = "packaging/app.manifest"
system_dlls = []
[windows.msix]
publisher = "CN=Publisher matching the signing certificate"
[linux]
package_name = "my-app"
formats = ["deb", "rpm", "appimage"]
desktop_entry = "packaging/my-app.desktop"
appstream = "packaging/my-app.metainfo.xml"
[linux.dependencies]
deb = ["libc6 (>= 2.39)"]
rpm = ["glibc >= 2.39"]
[linux.baseline]
name = "ubuntu-24.04"
glibc = "2.39"
kernel = "6.8"
[linux.flatpak]
runtime = "org.freedesktop.Platform"
sdk = "org.freedesktop.Sdk"
runtime_version = "25.08"
finish_args = ["--socket=wayland", "--socket=fallback-x11", "--share=ipc", "--device=dri"]
[web]
base_path = "/my-app/"
routing = "path"
offline = trueGrouped dependencies, explicit components, runtimes, and overrides
[dependencies.ffmpeg]
path = "vendor/ffmpeg/{target}"
executables = { ffmpeg = "bin/ffmpeg{exe}", ffprobe = "bin/ffprobe{exe}" }
licenses = ["LICENSE"]
resources = { "ffmpeg/presets" = "share/presets" }
libraries = { path = "lib" }
[[components]]
name = "media"
target = "aarch64-apple-darwin"
source = { type = "local", path = "vendor/media" }
licenses = ["LICENSE"]
[[runtimes]]
name = "media-runtime"
recipe = "directory"
component = "media"
source = "lib"
[target_overrides.x86_64-pc-windows-msvc]
formats = ["msi"]
[format_overrides.msi]
package_version = "1.2.301"Keep existing HTTPS/SHA-256 component sources and supported archive types as well. The SDK binding proposed here initially targets stable local components; it does not pretend all existing remote runtime recipes automatically produce stable build SDK paths.
Updates and complete release/publication policy
[updates]
enabled = true
channel = "stable"
base_url = "https://downloads.example.com/my-app"
[updates.public_keys]
sparkle = "packaging/sparkle.pub"
velopack = "packaging/velopack.pub"
appimage = "packaging/appimage.pub"
[release]
feed_validity_seconds = 604800
sparkle_tool = "/path/to/Sparkle-2.10.1/bin/generate_appcast"
sparkle_account = "ed25519"
gpg_key = "0123456789ABCDEF0123456789ABCDEF01234567"
[release.publisher]
kind = "directory"
path = "release-site"
public_url = "https://downloads.example.com/my-app"
[release.required]
aarch64-apple-darwin = ["zip", "dmg"]
x86_64-pc-windows-msvc = ["msix", "velopack"]
x86_64-unknown-linux-gnu = ["deb", "rpm", "appimage"]
[release.signing_keys.appimage]
kind = "environment"
variable = "MY_APP_APPIMAGE_SEED"
[release.signing_keys.velopack]
kind = "keychain"
service = "com.example.my-app.updates"
account = "velopack"
[release.repositories]
x86_64-unknown-linux-gnu = ["deb", "rpm", "arch", "flatpak"]Retain release.custom_required, external release.signers, file/environment/Keychain signing references, and directory/GitHub/HTTPS publishers. Existing trust, feed verification, repository preparation, all-target promotion, and failed-publication recovery semantics do not change.
A selected bundle file must also be available to release planning and promotion, rather than requiring duplicated Cargo packaging metadata:
rake release --config Bundle.toml --plan --json
rake release --config Bundle.toml --from mac-output --from windows-output --from linux-outputThe new --config source selection is proposed; release, --from, and the existing publication responsibilities are not new. Merely reading a config or running bundle must never publish, generate keys, enroll credentials, or start update polling.
Existing extension contracts
[[custom_formats]]
name = "company-macos"
platform = "macos"
input_format = "app"
command = ["python3", "packaging/company.py", "package"]
verify_command = ["python3", "packaging/company.py", "verify"]
[component_recipes]
codec = ["python3", "packaging/codec.py"]
[[runtimes]]
name = "codec"
recipe = "codec"
source = "vendor/codec"
options = { plugins = "decoder" }
[release.custom_required]
aarch64-apple-darwin = ["company-macos"]Keep the existing PackageBackend / ComponentRecipe Rust contracts and explicit JSON command protocol. Do not introduce another plugin system or treat a plugin's success response as native signing/verification evidence.
Configuration selection, paths, defaults, and locks
- An explicit
--config <file>selects that file. Otherwise discover exactly./Bundle.toml; do not walk ancestors looking for a nearer/different app. If neither applies, retain the existing Cargo metadata path. - A selected file is authoritative. Do not merge its distribution settings with
package.metadata.rake.bundle. Report selected and shadowed sources in the plan. An explicit legacy--manifest-pathselects the metadata adapter instead of automatic file discovery. - Source selectors cannot disagree:
--configconflicts with--manifest-path,--package, and--bin. With an automatically discovered file,--package/--binalone should be a conflict error, not a hidden switch of authority. - Keep execution overrides for target, formats, output, trust, and component policy.
--featuresis Cargo-only and augments declared Cargo features.--debugis Cargo-only; release is the default. Preserve current target/format override semantics. - All declared input paths and the default
dist/output use the canonical input root. It defaults to the config directory. An optionalroot = ".."can select an ancestor explicitly; require the config to remain inside the selected root. Continue rejecting payload/archive traversal and symlink escapes. This deliberate root selection does not relax native-input confinement. - For
packaging/Bundle.toml, putroot = ".."at the top level; paths such asCargo.tomlandassets/icon.svgthen refer to the project root. The plan must print the effective root. - Propose
<config-stem>.locknext to a standalone file (Bundle.toml->Bundle.lock). Legacy metadata retainsrake-dist.lock. Expose the resolved lock path in the plan and worker request. Programmatic sources need an explicit lock origin/path instead of guessing from a missing config filename. - Explicit CLI
--outputremains relative to the invocation directory; default output is root-relative. Tool, signing-store, and publisher references retain their explicitly allowed external-path rules and are not copied into payloads. - Cargo version comes from Cargo. A prebuilt source requires explicit semantic version and target. Unsupported format/platform/updater combinations fail during planning.
--plandoes no builds, native packaging, signing, downloads, secret-store access, or publication. Cargo-mode metadata inspection may retain its existing locked/offline Cargo metadata call; prebuilt mode must not invoke Cargo/rustc at all.- Emit a standalone-file JSON schema including
program,root, all existingConfigsections and proposed helper declarations. Retainconfiguration_schema()for the legacyConfigcontract; do not silently change that public function's meaning. Unknown keys must remain errors with useful source context.
For example, a config in a subdirectory can begin:
# packaging/Bundle.toml
schema_version = 1
root = ".."
name = "My App"
identifier = "com.example.my-app"
[program]
type = "cargo"Build handoff: one source of truth, including build.rs
Standalone file parsing alone is insufficient. Today rake-build::build() reads CARGO_MANIFEST_DIR/Cargo.toml and may embed a different identity, resource directory, desktop metadata, or update policy than the packager selected.
Proposed contract:
- Resolve the small build-relevant projection of the selected configuration in shared code, including package/version/target/format, public desktop/update bindings, resource naming, and applicable Windows build resources.
- Write an immutable, content-addressed build-context snapshot under the Cargo target cache and pass its path as
RAKE_BUILD_CONTEXTto Cargo. rake-buildtracks that environment key, verifies schema/package/version/content identity, and consumes the same resolved build settings. Identical build settings yield the same context path across runs.- Exclude private credentials,
release.*, machine-specific publication paths, and unrelated signing settings. Editing a signing identity or release destination must not cause recompilation. - Embed/track public-key bytes and content hashes for relevant assets so a real resource change invalidates the build. Handle Flatpak's sandbox paths explicitly.
- Keep SDK/toolchain environment bindings separate and scoped to child builds; never mutate global process environment.
- Support an explicit proposed
rake_build::build_from("Bundle.toml")for directcargo build, with its selector resolved relative toCARGO_MANIFEST_DIR(for example,../../Bundle.tomlin a nested crate). Declared payload paths still use the selected bundle root. A supplied build context takes precedence; legacy metadata remains the fallback. Do not add hidden upward config discovery inside build scripts. - A non-Rake UI application may have no build hook at all. Basic packaging must still work. Features that need embedded policy/resources must require a verifiable integration acknowledgement and fail early if absent; do not claim updater support merely because a dependency exists.
- Preserve worker isolation and native output verification. A content hash is a consistency/cache key, not a sandbox or authentication boundary against trusted project build scripts.
The exact build-context type, error reporting, and Cargo cached build-script message behavior need implementation tests before this becomes a stable public contract.
SDK path binding and reproducibility
program.build_env belongs to the Cargo input variant. A value such as CEF_PATH = { component = "cef" } references the named component produced by existing dependency lowering. An optional confined subpath can serve SDKs that need a lib/ or bin/ directory. Unknown components, escaping paths, and reserved orchestration-variable overrides must be rejected.
For the first version:
- Bind to verified local, stable, versioned source roots, e.g.
vendor/cef/<cef-version>/{target}. Keep development and distribution on the same SDK contract. - Resolve/verify the declared component lock and relevant architecture before compiling. Keep the existing final lock verification as well; generated runtime/CRT inputs may only be known after building.
- Stage the input for packaging and re-digest the bound local source after the build; fail if it changed.
- Do not use a random job directory as
CEF_PATH: it changes the Cargo build-script input each run and causes avoidable rebuilds. - Version the SDK path on upgrades, so Cargo does not reuse objects compiled against an SDK replaced in place.
- Reject HTTPS-backed or universal SDK binding until a stable prepared-tree contract exists. Existing remote runtime component support remains available.
--offline-componentsgoverns Rake component downloads, not all network access by Cargo or arbitrary build scripts. Do not describe it as a hermetic/offline-build guarantee.
CEF-specific exact archive/API compatibility validation and extraction remain a thin SDK preparation step owned by the consumer or an explicit recipe. The current CEF binding may download into an invalid CEF_PATH; an acceptance test must prove the selected prepared SDK is valid and remains unchanged. Rake should not hard-code CEF version rules or silently claim support for archive formats its component extractor lacks.
Proposed CLI coverage
| Entry point | Proposed behavior |
|---|---|
rake bundle | Discover standalone file first; existing metadata fallback. Release profile by default. |
rake bundle --config ... | Explicit standalone source. |
rake bundle --plan --json | Show source/root/program/build selections, effective configuration, lock, output and pending native validation. |
rake bundle --schema | Describe the standalone document; preserve an explicit way to obtain the legacy Config schema. |
rake build --native --config ... | Build declared Cargo artifacts using the same source/build-context adapter; reject prebuilt input instead of pretending to compile it. |
rake doctor --distribution --config ... | Inspect that source and tools without downloading, signing, or requiring Cargo for a prebuilt input. |
rake release --config ... --plan | Resolve the same public source and release policy without accessing credentials or publishing. |
rake release --config ... [--from ...] | Explicit native release/promotion using that source and existing verification/atomicity rules. |
rake update-key ... | Preserve the existing explicit independent key-management interface. No automatic key enrollment through bundle/config discovery. |
rake bundle --target web | Route supported Cargo inputs and the selected web settings to the existing Web pipeline; reject unsupported prebuilt combinations. |
Keep existing supported signing, target/format, features, output, component-lock/offline, and compatibility options. Do not turn this into a generic project/build supervisor.
Proposed Rust API and compatibility boundary
Keep rake-dist-core as the portable validated model, and rake-dist as the host-side coordinator. No new UI dependency or replacement packaging framework is required.
Schematic additions (names/signatures to finalize during implementation):
pub enum Program {
Cargo(CargoProgram),
Prebuilt(PrebuiltProgram),
}
pub struct BundleSource {
pub root: PathBuf,
pub program: Program,
pub config: Config,
}
pub fn load_bundle_file(path: &Path) -> Result<BundleSource, Error>;
pub fn plan_source(
source: &BundleSource,
platform: Platform,
target: Option<&str>,
formats: Option<&[Format]>,
) -> Result<Plan, Error>;
pub fn dispatch_worker(
args_without_argv0: &[OsString],
) -> Option<Result<Distribution, Error>>;- Preserve existing
plan,plan_with,plan_metadata,plan_metadata_with,bundle,execute_worker, schema, publication, signing-key and extension entry points. Add adapters; do not silently reinterpret existing signatures. - The file lowers into existing
Configplus an explicit program/root envelope. Programmatic callers can supply equivalent data without authoring a TOML file. - Carry normalized source data into the existing owned worker job, including explicit root/lock/output provenance. Avoid a second live parse of a different config during execution. Keep Cargo selection, version resolution, and plan revalidation where required.
- Retain
bundle(request, packager_host, cancelled)as the process-isolated execution path. Evolve its request compatibly or add a new source request adapter; reject conflicting legacy/source fields. Do not overload a fake empty manifest path as a source selector. - The dispatcher returns typed errors and never calls
exitor prints on behalf of the embedding host. Mark its result must-use. A caller must handle it before starting any UI/runtime and map errors to process exit status. packager_hostmeans the binary implementing the worker protocol, not the application being packaged. Document that distinction and provide a tiny non-Rake packager-host example.- Keep publication and custom-backend/native-verifier APIs attached to the same resolved identity/configuration. Private signing material stays out of serialized requests, build contexts, artifact metadata, and examples.
- Retain existing installed descriptor compatibility. Helper-app declarations do not justify adding unversioned fields to a strict reader.
Confirmed implementation gaps and items needing validation
- Cargo-coupled execution: the current coordinator always calls Cargo metadata, and builds only one selected main bin. Add the source boundary and collect the deduplicated required Cargo bins.
- Helper wrapper staging: generic sidecars do not produce CEF's nested application layout. Stage declared helper apps after the package engine creates the app and before final signing.
- Filename inspection:
otool -Lcurrently fails on the actualSilicon Helper (Renderer)filename, interpreting the final parentheses as archive-member notation. This was reproduced locally. Replace fragile textual inspection or otherwise prove robust handling of legal filenames; the existing binary parser dependency is a candidate. - Per-helper entitlements: current signing preserves entitlements on already-signed nested code. It does not express the explicit declared policy for newly generated helper wrappers. Apply each helper policy and verify the resulting entitlements; do not blanket-apply the main app's policy to every framework/XPC object.
- Hardened Runtime: local signature integrity alone does not establish Hardened Runtime behavior or Developer ID/Gatekeeper readiness. Test those separately and preserve native trust requirements.
- Build configuration ownership:
rake-buildmust stop silently deriving a different configuration from Cargo metadata when a standalone source is selected. - Non-Rake/prebuilt gates: current Windows/build/update integration checks and host-target detection must not force a Rust toolchain or GPUI defaults onto prebuilt programs. Unsupported integrations should fail explicitly before expensive work.
- Naming and SDK details: settle CEF main/helper executable conventions with a relocated real-process launch test before adding speculative executable-name options. Verify the prepared SDK layout, version match, license/credits, and read-only build behavior.
These findings do not establish that Rake has already successfully packaged and launched CEF through this proposed API.
Acceptance criteria
- Standalone parsing has a documented schema, typo/unknown-key diagnostics, and validation for incompatible program/helper forms.
- Every current
Configfield/nested section remains represented and validated; tests cover migration of current examples, platform settings, overrides, updates, release, extensions, and supported Web configuration. - Explicit/discovered/fallback selection, shadowed metadata, CLI conflicts, roots, lock names, output bases, and symlink/traversal rejection have tests.
- A plain Rust app with no Rake UI/runtime dependency packages and launches after relocation, using a packager host that does not depend on
rake-cli. - A prebuilt native executable packages with Cargo/rustc unavailable; wrong architecture, unsupported integrations, and invalid inputs fail clearly.
- A generic Cargo worker is built/installed correctly and remains discoverable using the existing sidecar contract.
- Build scripts receive the same effective identity/resources/update policy as the packager. Cached Cargo builds replay/acknowledge the binding correctly. Unrelated signing/release changes do not trigger recompilation.
- Two identical SDK-bound runs do not recompile CEF solely because a staging path changed. An SDK upgrade changes the input path/build fingerprint. Mutation and lock mismatch fail before signing or publication.
- All five CEF helper wrappers retain the expected names/IDs/plists and explicit entitlements. Test parenthesized names and paths containing spaces.
- Relocate the generated app, launch from an unrelated working directory, and observe real renderer and GPU subprocesses with the packaged framework.
- Verify native imports/loader paths, every helper's entitlements, strict signatures, and a Hardened Runtime run. Developer ID/notarization/Gatekeeper claims require an actual enrolled native release test.
- Cancellation during build/staging/signing/archive work terminates owned subprocesses, removes temporary state, and preserves the previous successful output.
- File-based release planning/promotion uses the same configuration and keeps existing secret handling, independent verification, native-host requirements, all-target checks, and transactional publication.
- Existing Cargo metadata users and public library entry points continue working.
Suggested implementation sequence
- Add standalone source loading/planning/schema and worker-source plumbing, with plain Cargo and prebuilt fixtures from the start.
- Unify the build-context handoff with
rake-buildbefore relying on the new source for embedded metadata or updates. - Fix filename inspection and add multi-binary collection, ordinary Cargo sidecars, and macOS helper-app staging/signing.
- Add local SDK bindings, early lock/architecture checks, input-mutation checks, and repeat-build coverage.
- Migrate the CEF consumer to the new API, retaining only SDK preparation and a thin run convenience if needed.
- Complete parity across doctor, release, extensions, and supported Web paths; document explicit unsupported combinations.
- Run native release/trust acceptance before declaring the migration complete.
Decisions for discussion
- Confirm
Bundle.toml/Bundle.locknaming and config-root/ancestor-root rules. - Confirm the proposed Cargo/prebuilt vocabulary, source-selection precedence, and CLI conflict rules.
- Decide the final source-request and build-context public/private boundaries without duplicating Config or weakening worker isolation.
- Decide how helper lists participate in override layers, using existing array replacement rules unless there is a demonstrated need for merging.
- Decide whether an explicit empty entitlement file is sufficient, or whether a typed explicit-none policy is needed; never silently inherit stale policy for a newly declared helper.
- Define the supported standalone Web/update/Windows integration matrix precisely. Do not equate generic packaging with automatic runtime/updater integration.
The key proposal is one readable standalone file, one validated distribution model, and one packaging engine, usable independently of Rake's application framework.
Activity
0No activity yet.