| # Bundled Git Runtime v1 |
| |
| Status: implementation slice for managed-workspace execution. This is a publication capability that |
| sits between M1.2 runtime-host composition and broad managed-workspace enablement; it is not M1.3 |
| dependency/secret provisioning. |
| |
| ## 1. Invariant and owner |
| |
| The Runtime Host may enable the managed-workspace owner only with the Maka-packaged Git toolchain for |
| the current platform and architecture. It must never discover or fall back to a Git executable through |
| `PATH`, a shell profile, a package manager, or the source workspace. |
| |
| Ownership is split deliberately: |
| |
| - `dugite@3.2.2` owns the upstream `dugite-native` release URL and archive SHA-256; |
| - `scripts/prepare-bundled-git.mjs` owns build-time version, executable, license, and digest validation; |
| - `bundled-git.json` binds one packaged artifact to platform, architecture, Git version, archive digest, |
| executable path, and executable digest; |
| - Runtime Host resolves the manifest and refuses missing, malformed, mismatched, escaped, symlinked, or |
| digest-mismatched artifacts; |
| - storage re-hashes the exact executable before every Git process and constructs the `dugite-native` |
| helper environment without inheriting a system-Git `PATH`. |
| |
| Two digests intentionally serve different purposes: |
| |
| - `executableSha256` is rechecked immediately before every Git invocation. It proves which entry binary |
| storage is about to execute; |
| - `runtimeIdentitySha256` is a canonical digest of the declared distribution identity: manifest |
| protocol, provider, Git version, platform, architecture, executable location and digest, and the |
| upstream archive digest. Managed repository, epoch, and worktree-binding artifacts persist this value |
| as `gitRuntimeSha256`, so changing any of that provenance creates an explicit epoch incompatibility |
| instead of silently reinterpreting an existing workspace. |
| |
| The manifest is evidence about one packaged distribution, not a mutable preference and not a system Git |
| probe result. |
| |
| ## 2. Supply chain |
| |
| The dependency is exact-pinned as `dugite@3.2.2`. Its `embedded-git.json` pins |
| `desktop/dugite-native@v2.53.0-3` and provides a SHA-256 for every supported archive. Dugite verifies that |
| archive before extraction. Maka then executes the extracted binary with `--version`, hashes that exact |
| binary, and emits the platform manifest used by packaging and runtime admission. |
| |
| The archive checksum is not an independent trust root. `npm ci` first authenticates the exact dugite |
| package bytes against `package-lock.json` integrity; that pinned package supplies `embedded-git.json`, |
| which authenticates the native archive; Maka then regenerates `bundled-git.json` inside each platform's |
| release job immediately before packaging. Review and branch protection own lockfile changes. The signed |
| and notarized macOS application closes the artifact-publication chain. The current Windows release is |
| explicitly unsigned, so its published SHA-256 and GitHub release transport do not provide OS-level |
| publisher identity; that remains a release security limitation rather than something the runtime |
| manifest can repair. |
| |
| The packaged runtime includes the complete `dugite-native` directory rather than copying only `git`. |
| Git subprograms, templates, MinGit libraries, certificates, and platform support files remain relative to |
| the same root. Runtime environment variables (`GIT_EXEC_PATH`, templates, Linux `PREFIX`/CA bundle, and |
| Windows MinGit paths) are derived only from that declared root. |
| |
| Every managed Git process receives an isolated environment: an owner-specific `HOME` and |
| `XDG_CONFIG_HOME`, `GIT_CONFIG_NOSYSTEM=1`, non-interactive credential settings, a fixed hooks directory, |
| and a `PATH` containing only the declared runtime directories. Runtime Host does not merge the user's |
| shell environment into this map. On Windows, the MinGit DLL/helper directories are included explicitly; |
| the current working directory is the Maka-owned home rather than the source checkout or application |
| directory. |
| |
| The execution profile is also injected at command priority and persisted on Maka-owned repositories: |
| `core.hooksPath` points at the owned empty hooks directory, credential helpers and interactive prompts |
| are disabled, `core.sshCommand` is empty, and `protocol.allow=never` prevents transport activation in |
| the current local-only workspace protocol. Operation-scoped environment values are merged before the |
| hermetic profile, so they cannot override its HOME, PATH, config, or prompt fences. Source repository |
| configuration is never copied into the independent managed repository; unsupported indirection such as |
| includes, alternates, replace refs, partial-clone state, and executable fsmonitor configuration is |
| rejected before baseline import. |
| |
| Production never resolves Git through `node_modules`. Dugite is the build-time supplier; Electron copies |
| the complete extracted distribution to `resources/git`, and Runtime Host resolves only that signed |
| application resource root. Storage receives a narrow verified-runtime input and has no dependency on the |
| dugite npm package or its manifest format. |
| |
| `VerifiedGitRuntime` is currently the Maka-owned adapter boundary between managed-workspace operations |
| and the distribution. A broader public `MakaGitRuntime` interface is intentionally deferred until a |
| second production implementation exists; introducing a swappable system-Git or libgit2 abstraction now |
| would create an unsupported execution mode rather than strengthen the present invariant. |
| |
| ## 3. Ordering and atomic boundary |
| |
| Publication ordering is: |
| |
| 1. install the exact npm lockfile; |
| 2. let dugite download and SHA-256 verify the platform archive; |
| 3. run `prepare:bundled-git` and verify the executable version and digest; |
| 4. package the complete Git directory, manifest, and notices in the signed application; |
| 5. verify their presence in the packaged application; |
| 6. at Runtime Host startup, resolve and verify the manifest before composing a managed-workspace owner; |
| 7. immediately before each Git invocation, storage re-verifies the executable digest. |
| |
| There is no cross-filesystem transaction spanning npm download and application packaging. A partially |
| prepared or mixed artifact is therefore not repaired in place: no `distributionReady: true` manifest is |
| accepted unless all build checks have completed, and runtime fails closed on any mismatch. |
| |
| The v1 identity binds the SHA-256-verified upstream archive rather than hashing every extracted file at |
| startup. This avoids an important signing ambiguity: macOS code signing may legitimately rewrite Mach-O |
| bytes after the prepare step, so a pre-sign tree digest could make the signed application reject itself. |
| A future post-sign runtime-tree/Merkle manifest must be generated and verified inside the release-signing |
| pipeline, not added as an ordinary prepare-time hash. Until then, Maka does not claim per-file integrity |
| for every helper in the extracted tree. |
| |
| That limitation is deliberate but security-relevant: v1 detects entry-binary replacement before every |
| Git process, while helper integrity relies on the authenticated upstream archive plus the packaged |
| application boundary. Closing it requires a dedicated publication slice that observes the final signed |
| helper bytes at the correct signing phase, binds that inventory into the outer application signature, |
| and verifies the inventory at managed-operation admission. Hashing the pre-sign extraction here would |
| be incorrect. The remaining verify-to-spawn window cannot be eliminated portably by a path-based handle; |
| the current threat model relies on packaged resources not being writable by the managed workspace and |
| on platform publisher authenticity. macOS supplies that authenticity today; Windows Authenticode is a |
| separate release-security prerequisite and is not synthesized by `bundled-git.json`. |
| |
| ## 4. Failure states and rollback |
| |
| Stable runtime failure classes are: |
| |
| - `bundled_git_unavailable`: manifest or executable is absent/unreadable; |
| - `bundled_git_manifest_invalid`: schema, path, or distribution metadata is invalid; |
| - `bundled_git_platform_mismatch`: artifact targets a different OS or architecture; |
| - `bundled_git_integrity_mismatch`: packaged executable differs from the build manifest. |
| |
| These failures disable managed-workspace composition. They do not change attached mode and never cause a |
| system Git fallback. Rollback is release-level: ship the prior application bundle or disable the managed |
| workspace feature. Runtime must not rewrite the signed resources or silently regenerate the manifest. |
| |
| ## 5. Platform matrix |
| |
| | Platform | Bundled executable | Helper environment | Current promise | |
| |---|---|---|---| |
| | Windows x64/arm64/ia32 | `git/cmd/git.exe` | MinGit `mingw*`/`clangarm64` bin and `libexec/git-core` | Supported by the pinned dugite-native archive; managed filesystem execution remains separately gated by the Windows sandbox capability | |
| | macOS x64/arm64 | `git/bin/git` | bundle `libexec/git-core` and templates | Supported; release must remain code-signed/notarized as one app bundle | |
| | Linux x64/arm64/arm/ia32 | `git/bin/git` | bundle `libexec`, templates, `PREFIX`, and CA file | Supported where the corresponding pinned archive and filesystem sandbox backend are available | |
| |
| Power-loss durability is not created by bundling Git. Repository/worktree durability remains owned by the |
| managed-workspace artifact protocol and its crash tests. |
| |
| ## 6. Acceptance tests |
| |
| - strict manifest happy path; |
| - platform/architecture mismatch; |
| - executable tampering; |
| - source-repository config and environment poisoning cannot override the managed execution profile; |
| - missing manifest with a system Git present (must still fail); |
| - path escape and symlink rejection; |
| - build preparation from the exact dugite platform record; |
| - Git version mismatch and unsupported platform rejection; |
| - packaged app contains the Git runtime, manifest, and license notices; |
| - production-shaped managed workspace open using the packaged runtime (required before broad enablement). |
| |
| The production-shaped smoke exercises the real commands required by the current owner, including |
| repository creation, ref updates, tree/index operations, and worktree lifecycle. This is the capability |
| gate. Startup `--help` probes are deliberately not used: they are weaker than executing the actual |
| workflow, can invoke pagers or platform-specific help behavior, and would duplicate checks before every |
| application launch. Individual Git failures remain fail-closed at the operation boundary. |
| |
| The last item is deliberately a release gate rather than evidence that managed execution is already the |
| default. Desktop/CLI activation remains a later, explicit product decision. |
| |
| The future M2 `WorkspaceVersionAccepted` fact must carry the same Git runtime identity alongside its |
| parent version, accepted commit/tree, materialization profile, and policy identity. Repository/epoch |
| binding protects the current managed artifact; version-fact binding is separately required to make an |
| accepted mutation historically interpretable. It belongs to M2 and must not be approximated in this |
| publication PR before that fact has a production writer and consumer. |
| |
| ## 7. Licensing and size policy |
| |
| The full `dugite-native` directory is packaged, including whatever component license directories its |
| platform archive supplies. Because those archives do not expose Git's license at one uniform path, Maka |
| also tracks the Git GPLv2 text and packages it consistently as `resources/licenses/git/LICENSE.txt` |
| alongside the Git/dugite notices. Prepare and final-package verification both require that stable asset. |
| A generated component inventory is useful release hardening, but it is not represented as a |
| runtime-authority guarantee in v1 and should be implemented as a dedicated supply-chain slice. |
| |
| The first release keeps the full upstream distribution. Pruning shells, Perl, GUI programs, docs, or |
| helpers is deferred until Maka has an exact command/helper allowlist and the pruned artifact passes the |
| same production-shaped release smoke on Windows, macOS, and Linux. Package size alone is not sufficient |
| evidence that a helper is safe to remove. |
| |
| An application upgrade currently replaces the packaged runtime. Existing managed artifacts whose |
| recorded runtime identity differs therefore fail closed and require an explicit future migration, |
| rebaseline, or compatible-runtime retention policy. V1 does not silently migrate them and does not ship |
| multiple runtime generations. A versioned `resources/git-runtime/<identity>` layout is a possible future |
| carrier, but adopting it requires an owner and retention/patching policy rather than a directory rename. |
| |
| ### Source distribution and license boundary |
| |
| Bundled Git remains a separate command-line program; Maka invokes it through a process boundary, so |
| Maka's own Apache-2.0 license is unchanged. Binary redistribution still creates GPLv2 obligations for |
| the Git program itself. The release pipeline therefore owns two independent artifacts: |
| |
| 1. `prepare:bundled-git-source` materializes commit-addressed source archives and a checksum manifest |
| for the upstream revisions used by Dugite native; |
| 2. every packaged application carries `licenses/git/SOURCE_OFFER.txt`, which promises complete |
| corresponding source on request for at least three years. |
| |
| The source-materials archive is a convenience artifact, not an unsupported claim that a short list of |
| upstream tarballs is necessarily the complete corresponding source for every platform toolchain. The |
| written offer is the fail-safe for build scripts and indirect platform dependencies. A release is not |
| publishable unless the binary artifacts, source-materials archive, source-offer text, and their hashes |
| are all present. The release owner must retain the ability to honor requests for the full offer period. |