Skip to content

Update fails on Homes with the local AI engine: sealed llama.cpp tree cannot be replaced (2.0.1) #515

Open

Description

@andersalm

Problem

Updating a Home that has the local AI engine (llama.cpp) installed fails when the release changes the engine archive. Seen 2 Nov 2026, rc.1 -> 2.0.0-rc.2 on a Mac (darwin archive sha256 5c182a73 -> a3ba8ae2; Linux archives unchanged).

  • CLI: update refused; original release files restored / Trusted source Carrier fetch failed for llama-server (...): Permission denied (os error 13).
  • System: "The update could not be completed." Each try leaves a sealed ~780 MB DATA/.tmp*.

Cause (7bc3704)

Setup seals the engine tree (dirs 0500, files 0400; receipt check requires it, setup/local_model_engine_receipt.rs). setup.rs atomic_copy_dir swaps the new tree in, then remove_dir_all on the old sealed tree -> EACCES. System path: install_transaction/support.rs copy_tree creates the 0500 dir before its children -> EACCES. Fresh installs do not include llama-server (not in profile home); rc.2 -> 2.0.0 ships byte-identical engine archives on every platform, so that hop restages nothing (plan_update_support, setup.rs ~3697-3760).

Workaround (used on a real Mac Home)

Move DATA/libexec/llama.cpp aside, chmod -R u+w and delete DATA/.tmp*, stop Home, elastos update --yes, start Home. The engine is reinstalled at the new version on start.

Fix branch

fix/2.0-sealed-tree-removal (unpushed): 98651b7e8 (proof on a sealed clone, CLI path rc.1 -> rc.2 exit 0), 5f6920475, 957cb64c2. Codex reviews: FAIL (P1 path walk, P1 chmod by path, P2 recovery) -> FAIL (P2 recovery accepts 0700 root) -> FAIL (3 x P2 on the reseal record: interrupted record creation, record used before scratch validation, record deletion durable before reseal).

Design question before any further attempt

All three attempts share one assumption: installed and staged engine directories must be 0500, so every move, copy, removal and crash recovery has to unseal and reseal them. Each attempt adds crash windows. Test that assumption first: the owner can always chmod its own directories, so 0500 directories give no protection against the same user; the receipt's content hashes do. Candidate: seal files only (0400), keep engine directories 0700, receipt checks hashes and file modes. Then the plain swap/remove/rename paths work unchanged. Constraint either way: a Home's update runs the OLD release's support code, so until a release with the fix is installed, no release may change a llama-server archive that existing Homes have installed.

Activity

  1. andersalm commented on Nov 2, 2026

    @andersalm
    ContributorAuthor

    Root design review for the paused #515 lane: favor owner-only 0700 engine directories, with payload data and the receipt 0400 and executables 0500, provided the compatibility and integrity checks below pass. This is a design recommendation from source review; the replacement implementation still needs review and tests.

    0500 directories protect against accidental entry changes by cooperating code. They provide limited protection against code running as the owning user, which can change their mode. Moving to 0700 allows that user to unlink or replace entries even when files are read-only. Runtime owns capsule filesystem authority; hashes, receipt validation and launch checks retain their separate roles. These permission effects follow Apple's chmod and unlink contracts. A local unsigned receipt alone does not establish resistance to a hostile process with the same user authority.

    The exact 7bc3704b5 source requires 0500 directories in both full verification (setup/local_model_engine_receipt.rs:110–144) and identity projection (:170–185), and writes that mode at :290–296. Setup uses full verification for installed state (setup.rs:1784–1799) and before engine launch (:2622–2627). Keep these paths consistent, preserve trusted archive bindings, inventory/hash checks, owner/link/path checks and rejection of invalid bundles, and explain the changed protection contract in code and tests.

    Compatibility is the main unresolved design point. Existing 0500 trees still need a bounded, owned-path migration or recovery route. An old signed updater executes its old removal code. Also, an rc.2 Runtime restored by Undo would reject a newly produced 0700 tree. Define and prove forward update, interruption recovery and Undo behavior across that boundary before changing the on-disk mode. Source-mode changes alone do not prove those journeys.

    The supplied third peer review remains FAIL on incomplete reseal-record creation, scratch validation before recovery effects, and durability ordering. Keep that implementation paused while choosing the simpler contract; retain all three failures. Main remains the sole writer. Root read immutable 7bc source and the supplied peer report, and ran no build, fixture, update, chmod or cleanup. The stable ship authorization remains separate from this 2.0.1 design review.

  2. andersalm commented on Nov 2, 2026

    @andersalm
    ContributorAuthor

    Codex Root design view (grook.md 2026-11-02T14:50Z, source-only): favour engine directories 0700 with data/receipt 0400 and executables 0500, conditional on proof. All current receipt/identity/setup checks at 7bc3704 require 0500 directories (local_model_engine_receipt.rs verify 110-144, identity 170-185, write 290-296; setup.rs 1784-1799, 2622-2627). Must define and test: migration of existing 0500 trees, older signed consumers moving forward and recovering, interruption, and Undo (restoring rc.2's Runtime over a new 0700 tree is rejected by rc.2's check). Do not chmod live trees ad hoc. Lane stays paused until this design is settled.

  3. andersalm commented on Nov 2, 2026

    @andersalm
    ContributorAuthor

    2.0.0 check (2 Nov, Mac): on an APFS copy of a real 2.0.0-rc.2 Home with the sealed engine installed (dr-x------, receipt archive_sha256 a3ba8ae2...), elastos update --yes went 2.0.0-rc.2 -> 2.0.0 and ended "ElastOS 2.0.0 installed successfully!" with the engine left in place. rc.2 and 2.0.0 ship byte-identical llama-server archives, so the engine is not restaged. A Mac on 2.0.0-rc.1 or earlier with local AI still meets this bug on its way to 2.0.0 (its darwin archive differs, 5c182a73 -> a3ba8ae2); a second report came in today. Workaround as above: stop Home, chmod -R u+w and move libexec/llama.cpp out of the Home's data folder, update, start Home. Not concluded: the install command on an rc.2 copy stopped on a copy-only controller receipt check before setup, with no engine error.

  4. andersalm commented on Nov 5, 2026

    @andersalm
    ContributorAuthor

    With #531 and #532 merged, Main’s stated next step is the #515 design, followed by the remaining #527 work. The three failed repair attempts stay paused while that design is settled.
    Define directory/file modes, migration of an existing sealed tree, the old signed consumer’s forward/recovery behavior and Undo before changing the disk contract. Start with a small sealed-engine regression for both CLI replacement cleanup and System tree copying, while preserving the original failures.
    Main owns the design and implementation; Root reviews the frozen design/source and supplied results. An unchanged-engine update remains partial evidence because it avoids the failing replacement path.

  5. andersalm commented on Nov 5, 2026

    @andersalm
    ContributorAuthor

    The new #535 release order supersedes the earlier #515-first handoff: 2.0.1 includes Jetson Browser and the selected fixes, with local-AI engine archives held byte-equal to 2.0.0 before signing. #515 stays open for the changed-archive defect and its design/proof.
    That archive guard avoids replacement for the supported 2.0.0 update; it leaves the original failures and older-consumer migration/recovery/Undo work intact. Main owns the release check and engine-present installed update proof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions