openclaw/scripts/check-install-dependency-ownership.mjs
Jason (Json) 000af986dc
feat(update): retain compatible package rollback and safe recovery admission (#140339)
* feat(update): verify served agent turns are persisted

Related: #124396
(cherry picked from commit a12b5fa6acea52487837257289c1d45299660375)

* feat(update): persist recovery claims and guard interrupted admission

Related: #124396

Persist exact operational records in the existing shared machine-state owner, with revision fencing, observed effects, candidate handoffs, serving proofs, and history-preserving checkpoint carry-forward. Refuse new admission and diagnostic completion while operational recovery remains pending.

Integration checkpoint: package descriptors, terminal pair retention, checkpoint publication discovery, and matching-runtime replay still require the coordinated producer and finalizer consumers. Focused recovery/history/CLI tests: 75 passed; typechecking, focused lint, and independent P0-P2 review passed. Production unused-export checks remain blocked by the unfinished consumer integration.

(cherry picked from commit 5037c12fe8528136d7b32e6804230db23af63c10)

* fix(update): bind recovery checkpoints to admitted source

(cherry picked from commit 9d8bbc7bcabec9ae5fddbcb8fcc88935136fc49c)

* fix(update): reject aliased recovery databases

(cherry picked from commit b1d10c113bdf6d2ff8eae0c8d7bbb0af6318f418)

* feat(update): capture and restore verified update checkpoints

Related: #124396

Capture digest-bound config, plugin payload, service files and SQLite state.
Restore compatible newer work with three-way preservation, preserving FTS and
row identities, while refusing incompatible changes before publication.

Integrate the existing recovery owner for immutable plan references, exact
record/logical-data binding, two-copy sealing, interrupted preparation and
resource reconciliation. Keep live SQLite reads artifact-preserving.

Integration checkpoint: 34 focused tests, core/core-test typing, scoped type-aware lint and independent
P0-P2 review pass. The full changed-file gate still identifies absent real
production consumers; finalizer lifecycle and recovery admission/replay wiring
remain coordinated follow-ups. No complete whole-state rollout or containment
claim is made here.

(cherry picked from commit ec216121b2a8e6214576709fd0774eff28e0ae0a)

* fix(update): revalidate checkpoint sources before sealing

Bind source content, physical identity and absence again after all resource
copies so service and environment preimages cannot silently become stale
before manifest publication. Recheck owner-held exclusion before returning.

Three regressions reproduce edited, same-byte recreated and newly-created
service resources on the previous implementation. All 37 focused checkpoint
and real recovery integration tests pass, along with production/test typing,
scoped lint and fresh P0-P2 independent review.

The full changed-file gate still fails on missing production consumers in
the existing checkpoint/recovery/verifier stack. This additive integration
commit changes no public API and does not claim complete rollback or landing.

Related: #124396
(cherry picked from commit 85976a48ca3858cabab3de19c53c274614e5d90f)

* fix(update): block admission across interrupted database publication

Detect existing checkpoint restore families before any writable admission when the canonical shared database is missing. Treat locators as evidence requiring reconciliation, never as mutation authority. Keep first-install admission and existing pending-recovery checks intact.

Four real CLI negative controls reproduced new history database creation. All 65 focused recovery and CLI tests pass; production/test typechecks, scoped lint and independent P0-P2 review pass. Full changed gate still flags missing production consumers in the unfinished stack. Private integration checkpoint; no full replay or retention claim.

(cherry picked from commit 324bcd2d1c09d39b66442d56951177f9cdf0e459)

* fix(update): bind displaced recovery to publication record

(cherry picked from commit 4936cbfefd95f71934c3de75c31324d2e48b3616)

* fix(update): bind checkpoint file restores to mutation outputs

(cherry picked from commit f855a3ed6fa757a7797e1dc6f03468ce73fd5644)

* fix(update): bind plugin rollback to committed row receipts

(cherry picked from commit 2c4a077dbeeae6db9a03d9939fa469a396363371)

* test(update): verify exact checkpoint inventory and SQLite capture

(cherry picked from commit c24926024c64a7c718f1d1df15ab3a3b3c07d73c)

* fix(update): expose canonical recovery row ownership selector

* fix(update): enforce staged runtime validation before sealing

* fix(update): bind legacy admission plans to original config sources

* feat(update): persist checkpoint after-images by completed interval

(cherry picked from commit ee2bf95f44d624f258a8fbe2f9fe4cd4ef38b6b6)

* fix(update): preserve pre-stop file preimages through checkpoint sealing

(cherry picked from commit 5c81b9caf154334fa65d17d298417bedf5e5208e)

* fix: require saved agent turns before update verification succeeds (#140274)

* feat(update): verify served agent turns are persisted

Related: #124396

* fix: verify update serving and persistence on the final Gateway boot

* fix: retire advisory inference after durable update verification

* test: align Doctor update controls with boot-bound verification

* fix(test): accept release subpages in docs route shape

(cherry picked from commit 20673ed72fb87e2c428b69bfa07b33ccb0e2cf79)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit cbd5419a5d)

* fix(update): converge plugins before managed service activation

* fix(update): keep the service profile when switching to Git (#140263)

* fix(update): keep the service profile when switching to Git

Resolve the admitted managed-service environment when package-to-Git backup, Doctor, and source-publication recovery consume it. Preserve deferred inspection and mutation ordering.

Follow-up to #139722; original all-agent preflight context is #135541.

* fix(update): restrict deferred Git profile to owned service

(cherry picked from commit add29edb0b)

* fix(update): await post-core writer settlement before continuing

Join child close and termination helper before returning committed plugin results, preserving committed work across termination races. Keep convergence as a step so restarting and verifying history remain monotonic.

* fix(update): validate checkpoint publication by resource role

(cherry picked from commit dd3e2e9ba7136acc87616ffd97560c8d53dfac15)

* fix(update): report unavailable checkpoint exclusion before apply

(cherry picked from commit 5c4021420f9f466da55fb656fc0ac1d80c100e12)

* feat(update): reconcile checkpoints before recovery claims

(cherry picked from commit 57ac8738a103bdf5b00a3a59278c047d8615a606)

* fix(update): stop repair continuation after authority loss

* feat(update): seal staged service files before native load

* feat(update): validate restored state with previous runtime

(cherry picked from commit cec342aa8e1e8e33e22f789c430e936e716b63e4)

* fix(update): retain pending staged-load failures

* test(update): supply retained runtime to checkpoint adapter

* feat(update): import immutable package recovery runtime

Use the exact four-file runtime closure from package-owner commit 6703db8f2b925e9c28235e24e418eb0f66ce5967. Package swap integration remains with its owner.

(cherry picked from commit 5f7338df8a87e07e51570a92208df0531d4148a7)

* feat(update): commit verified recovery outcomes and retained pairs

Persist typed package effects with fenced retry acknowledgements. Atomically commit terminal history and select the next retained package/checkpoint pair before superseded retirement. Preserve selection during rollback and interrupted cleanup; complete CLI runs from durable outcomes.

(cherry picked from commit bbf6f99bf05d6e6d88c651fcddd1120e5c735a6b)

* fix(update): consume durable terminal outcomes in finalization

* fix(update): reject serving proof after recovery changes

* feat(update): integrate retained package generation prerequisite

Exact committed-source slice: 56b29249997c0742b44018fdd83faff311c2e224..fc221149203aeb8e6766aafbb545d6889d71dfc0.
Includes only missing package owner paths; existing runtime imports preserved.

* feat(update): integrate bounded retained-generation readers

Exact committed-source slice: fc221149203aeb8e6766aafbb545d6889d71dfc0..e2279391b42f7794de0c82bded390e6f114477ba.
Includes only missing package owner paths; existing runtime imports preserved.

* feat(update): integrate canonical package recovery swap

Exact committed-source slice: e2279391b42f7794de0c82bded390e6f114477ba..6703db8f2b925e9c28235e24e418eb0f66ce5967.
Includes only missing package owner paths; existing runtime imports preserved.

* test(update): reopen retained recovery after-images with source binding

(cherry picked from commit 409b1ce3165bd9b3a06a72ecbb2b24d0bd10d2a5)

* feat(update): bind early recovery file preimages

Keep purpose-validated original file artifacts in a separate fenced recovery slot before lifecycle mutation. Reopen and recheck current claims before early lifecycle actions; require a later full checkpoint to link the exact early artifact without accepting it as complete state.

(cherry picked from commit e929332b9ee6794930d96e1626907205d35eda36)

* test(update): cover retained-reader publication races

(cherry picked from commit c20f9ff59aa9a4b3e515940ab72fbacbb80e5af8)

* fix(update): propagate durable package recovery hooks

* fix(update): retain exact backup diagnostics after failed publication

* fix(update): revalidate resource before recovery progress

(cherry picked from commit 85d3929a12968b5dd0feba2ede6f2e7ac1c07533)

* fix(update): validate restored agent databases with retained runtime

(cherry picked from commit 95a8ba67873858fd43970be8d11e003b09c69cb8)

* fix: coordinate cached state and direct config writes

* fix: coordinate shared-state checkpointing on retirement

* fix(state): retain handle exclusion through native and source-reader lifetimes

* fix(state): retain heartbeat exclusion through renewal and worker exit

* test(macos): preserve canonical modes in worker install fixture

* fix(state): bind source capture to its current physical exclusion

* fix(state): bind maintenance capture to settled heartbeat ownership

* fix(state): compose live lease owners for checkpoint capture

* feat(update): persist native manager recovery intent

(cherry picked from commit 8a0a2a3af098f4036b51a0bf82462578bb25ddaa)

* fix(update): bind checkpoints before releasing source exclusion

* fix(config): serialize writes to shared include targets

* feat(update): replay sealed checkpoint restoration

(cherry picked from commit b922f75b28db236c37131e4e26e649862ed8ef03)

* test(update): reconcile retained runtime replay fixture

* feat(update): bind systemd recovery manager identities

(cherry picked from commit a8b359cd7aa6852397bd00041c524b58ff3665ee)

* fix(update): inspect loaded systemd commands without activation

* fix(update): guard interrupted preview history settlement

(cherry picked from commit 588f70478515c7cfd53c642ba46b32bf4c5e6f3a)

* fix(update): settle interrupted previews within admitted command scope

* fix(update): reject uncertain loaded service admission

(cherry picked from commit 00c9931e91a8174feda08fa80af74ef4a61b43a7)

* fix(update): inspect loaded systemd runtime without activation

* fix(update): keep definition admission non-activating

* fix(update): retain observed native manager account identity

* test(update): exercise physical checkpoint publication owners

(cherry picked from commit 73bd1544bbf35bf51df7c83a2c1c8ba005837cae)

* feat(state): rebind live leases after checkpoint publication

(cherry picked from commit 1832bd986d1905f89e76a71ca11196f97a0c940b)

* fix(update): replay sealed recovery from rollback

(cherry picked from commit d4c2ad61c400e36d0fd582bee8b6b18b584f346f)

* fix(update): bind recovery CAS to publication custody

(cherry picked from commit d7da34a4480ced7cf28a5caa18543fd1be091d1e)

* fix(update): classify native admission read failures

(cherry picked from commit 0bf7e1faf2230885ec5236a4ce748e01949c9683)

* fix(update): defer legacy config writes until admitted execution

* fix(update): consume live publication in rollback

(cherry picked from commit 30ee0442378d9768c8324926a097d80c7cd06bf8)

* fix(update): preserve pending recovery through finalization and unwind

* fix(update): refuse finalization before displaced source admission

* fix(update): retain live executor ownership through command settlement

Reuse the managed handoff lease for direct invocations and borrow only the exact live helper assignment. Check the original executor after awaited candidate validation and retain it through recovery unwind. Keep physical checkpoint exclusion and durable recovery startup as separate unfinished integration.

* fix(update): retain executor authority across native lifecycle effects

* fix(update): inspect legacy terminal outcomes without granting mutation authority

* fix(update): fence migrated workers through descendant extinction

* fix(update): bind staged startup and original source capture

* fix(update): bind original native facts under lifecycle ownership

* fix(update): retain native stop authority through acknowledgement

* fix(update): preserve owned recovery across CI and artifact replacement

Retain the live state coordinator through heartbeat worker teardown, preserve the first lease failure across nested maintenance, and settle fresh locally owned pre-activation signals without migrating state. Treat explicit artifact targets, including package aliases, as replacements regardless of equal versions.
Separate shared type and fixture contracts to remove static dependency cycles, register the real Gateway client callsite, and correct platform and atomic-publication fixture boundaries.
Source-bound regression checks and independent review are retained with the CI correction proof; hosted exact-head checks and clean-head built presenter verification remain separate landing requirements.

* fix(update): finish package baseline reads before durable startup

Keep bounded file observations within their own reader lifetime. Await
startup and descriptor persistence afterward, preserving independent
package readback, retention, and native activation fences.

* fix(update): preserve typed recovery queries and isolated test owners

* fix(update): reconcile untouched preparation under live owners

Keep bounded package roots concurrent, preserve no-effect failed preparation evidence, and support loaded-only synthetic service inspection. Make the native deletion test barrier explicitly owned.

* fix(update): distinguish SQLite metadata reader export

* fix(update): resume journaled rollback with absent package root

* test(update): isolate Windows ACL creation in platform simulations

* fix(update): drain logical owners before checkpoint publication

* fix(update): settle retained agent WAL under publication custody

* fix(update): preserve WAL boundaries and deterministic lease fixtures

* fix(update): retain exact mutation custody through Doctor and rollback

* Fix preflight signal ownership and failed native restart recovery

* test(state): isolate competing maintenance lease claims

* fix(update): bind all phase receipts during checkpoint recovery

* fix(update): reconcile stopped candidate suppression under fresh authority

* fix(update): inspect collected systemd units under recovery custody

* fix(update): admit retained stopped service replay under fresh custody

* fix(update): inspect collected service processes on the native interface

* fix(update): admit sealed stopped recovery on ordinary entry

* fix(locks): report bounded stale-owner acquisition evidence

* fix: keep shipped SDK context aliases pending removal (#142708)

(cherry picked from commit c7cb45dfd5)

* fix(update): validate ordinary interrupted-update recovery

Simplify the ordinary recovery path, retain strict existing-record refusal, and
repair cross-version admission, source ownership, native observation, and
checkpoint startup-metadata handling. Exclude the inactive capsule subsystem.

Validate the exact source with complete package build, independent reviews,
and serial installed rollback, upgrade, transport, signal, and interruption cases.

* fix(update): remove type cycle and scope migration test cleanup

* fix(update): retry owned PID-less activation observation transitions

* test(update): isolate refusal cases and join fixture descendants

* feat(update): defer full-state recovery and retain compatible rollback

* fix(update): separate type contracts and remove deferred recovery orphans

* fix(update): retain executor checks across native task recovery

* fix(update): avoid unsolicited notices after package rollback

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Jason Sy <jsy@jasons-mac-studio.tailb01b0a.ts.net>
2026-09-09 21:35:58 -06:00

36 lines
1.3 KiB
JavaScript

import { lstatSync, realpathSync } from "node:fs";
import path from "node:path";
const root = realpathSync(process.cwd());
const configured =
(process.env.PNPM_CONFIG_MODULES_DIR ?? process.env.pnpm_config_modules_dir) ||
process.env.npm_config_modules_dir ||
undefined;
const modules = path.resolve(root, configured || "node_modules");
const workspaceModules = path.join(root, "node_modules");
function inspectDirectory(directory, explicitTarget) {
const entry = lstatSync(directory, { throwIfNoEntry: false });
if (!entry) {
return;
}
if (entry.isSymbolicLink() && explicitTarget && realpathSync(directory) === explicitTarget) {
return;
}
if (!entry.isDirectory()) {
throw new Error(
`Refusing to reconcile dependencies through ${directory}: it is not a physical directory. Preserve the borrowed install and use an independently owned checkout.`,
);
}
}
// pnpm can still reconcile workspace modules when its metadata directory is explicit.
inspectDirectory(modules);
const explicitTarget =
configured && modules !== workspaceModules && lstatSync(modules, { throwIfNoEntry: false })
? realpathSync(modules)
: undefined;
inspectDirectory(workspaceModules, explicitTarget);
for (const directory of new Set([modules, workspaceModules])) {
inspectDirectory(path.join(directory, ".pnpm"));
}