Repository navigation
feat(xim): recipe packaging revision and the install_targets record (2026.9.27.1) - #622
Merged
Merged
Conversation
…2026.9.27.1) A version entry may now state `revision = N` (libxpkg 0.0.58): a change to what a recipe installs under an unchanged upstream version. Until now the store could only answer "is 2.44.3 here", so a fixed recipe never reached a machine that had installed the broken payload: `install` of that version returned on the strength of the `installed` hook or the version database. Revision (#620) - The payload stamp records the revision it was built from (`"revision": N` in `.xpkg-install.json`, always written). - One verdict, `payload_revision_verdict` (install_state): a payload is current iff its recorded revision equals the recipe's. A stamp without the field reads as revision 0, so only a recipe that states revision >= 1 reinstalls, and it reaches every older payload. No stamp at all, or a stamp that records a failed install, gives no verdict. - The resolver plans a stale payload as not installed (its artifact is downloaded and verified first); the installer asks the same verdict again after its own fast paths and says why: `reinstalling glibc@2.44.3: recipe revision 1, installed revision 0`. - The replacement never leaves the version without a payload: the old tree is renamed to `<data>/stale/`, the new one is installed at the real path (recipes embed install_dir()), and the old tree is deleted on success or renamed back on any failure (`PayloadReplacement`, payload.cppm). Files other tools wrote into the old tree go with it. - `install_plan` entries carry the revision as a third element and the reinstall reason as their note. install_targets (interface protocol 1.1, additive) - The top-level install reports, per request and in request order, `{request, namespace, name, version, revision, status, payload_dir}` with status `installed | already_present | failed`, on every path: fresh installs, "everything already installed" (which previously put nothing on the wire), and failures. Nested installs requested by recipes and dry runs do not report. Registered as interface-only for the terminal. - A node whose payload was present and current is recorded as present rather than installed, so `install_summary.success` counts what the run installed, as its comment already stated. - docs/spec/interface-ndjson-v1.md documents install_plan, install_summary (as emitted) and install_targets; docs/spec/xpkg-manifest-v1.md documents `revision`. Crash recovery for an interrupted reinstall - `PayloadReplacement`'s rollback is a C++ destructor, so it only runs within the same process. A kill (SIGKILL, power loss) between the rename into `<data>/stale/` and that destructor left the parked directory there forever: nothing else ever revisited it, and every crash during a revision reinstall leaked one directory. - Fixed with a marker written next to the parked directory before the rename that creates it (`<parked>.origin`, atomic write-temp-then-rename; `write_parked_payload_marker`), recording the payload's original path and the pid doing the parking. At the start of every `install` -- once per command, where `Installer::execute` first touches the store, not once per package -- `recover_parked_payloads` sweeps `<data>/stale/`: an entry whose pid is no longer running is moved back when the original path is missing or is the empty placeholder `set_aside_payload` leaves behind, or discarded with its marker when the original path already holds something else. An entry whose pid is still alive is left alone. Recovered and discarded entries are logged at the same level as other install diagnostics. - The in-process rollback is unchanged; a successful replacement deletes the marker along with the parked directory. - The message for a rename that fails on a file held open (Windows only -- POSIX `rename(2)` on a directory does not depend on what is open inside it) now names the specific file, not only the two directories being exchanged. - docs/spec/xpkg-manifest-v1.md gets one sentence on the recovery. Version-grammar conformance vectors - tests/data/semver-vectors.tsv: request, available versions, active version, expected result; driven through the resolver by tests/unit/test_semver_vectors.cpp. Self-describing for vendoring. Also: xlings 2026.9.27.1, mcpplibs.xpkg 0.0.58, E2E-121 (install_revision_test.sh, now with a crash-recovery case). Refs: #620 mcpp.lock is regenerated against the published libxpkg 0.0.58 with mcpp 2026.9.26.2 (the earlier edit only renamed the version and kept 0.0.57's hash). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sunrisepeak
force-pushed
the
feat/install-targets-revision
branch
from
September 27, 2026 05:45
818b191 to
8fb9a43
Compare
speak-agent
added a commit
to mcpp-community/mcpp
that referenced
this pull request
Sep 27, 2026
kXlingsVersion and every .github pin check_version_pins.sh reads move to xlings 2026.9.27.1 (openxlings/xlings#622), released on GitHub and GitCode and published in the xim index. It is the release that emits install_targets and records a payload's revision, which this mcpp reads first. The vendored semver-vectors.tsv already matches that release's file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
xlings 2026.9.27.1: a recipe's packaging revision (#620), and a record of what each install request resolved to.
Revision (#620)
A version entry may state
revision = N(libxpkg 0.0.58), counting changes to what a recipe installs under an unchanged upstream version. Until now the store could only answer "is 2.44.3 here", so a fixed recipe never reached a machine that had installed the broken payload."revision": Nin.xpkg-install.json.payload_revision_verdict(install_state), decides whether a payload is current.reinstalling glibc@2.44.3: recipe revision 1, installed revision 0.<data>/stale/and the new one is installed at the real path.PayloadReplacement).install_planentries carry the revision as a third element and the reinstall reason as their note.Recovery of an interrupted reinstall
The rollback above is a destructor, so a killed process (SIGKILL, power loss) used to leave the old tree parked under
<data>/stale/forever.<parked>.originrecords the payload path and the parking process, written atomically.installcommand,recover_parked_payloadsvisits<data>/stale/: an entry whose process is gone is moved back when the payload path is missing or is the empty placeholder, and deleted with its marker otherwise; an entry of a live process is left alone.install_targets (interface protocol 1.1, additive)
{request, namespace, name, version, revision, status, payload_dir}per request, in request order, with statusinstalled,already_presentorfailed.install_summary.successnow counts only what the run installed, as its comment already stated. This is the one observable change for existing clients.docs/spec/interface-ndjson-v1.mdanddocs/spec/xpkg-manifest-v1.md.Version-grammar conformance vectors
tests/data/semver-vectors.tsvlists request, available versions, active version and expected result.tests/unit/test_semver_vectors.cppdrives every vector through the resolver. mcpp vendors the file and runs the vectors without an active version against its own implementation.Tests
test_install_state,test_interface_protocol,test_payload_remove(includingParkedPayloadMarkerandRecoverParkedPayloads),test_semver_vectors. The fullmcpp test, 58 test binaries, passes locally as a non-root user against the published libxpkg 0.0.58.tests/e2e/install_revision_test.sh(E2E-121), cases R1 to R9; R9 fabricates a parked tree with a dead process's marker and a missing payload path and checks thatinstallrestores it and emptiesstale/.Dependencies
mcpp.lockis regenerated against it.install_targetsand the recorded revision..agents/docs/2026-09-27-release-2026.9.27.1-notes.md; the post-release verification is appended there after the release.Refs #620, #621. They are commented on and closed after the release is verified in an xlings subos sandbox.