* fix(runtime): require Node releases that reject compromised CA keys
Require Node 24.22.1 or 26.12.1 even when SQLite capability checks pass.
Align active managed runtime selectors, archive checksums, image digests, native macOS selection, diagnostics, and coupled fixtures while preserving update recovery.
* fix(tooling): use pnpm that rejects compromised CA keys
* test(runtime): align pinned Node fixtures and generated guidance
* test(runtime): qualify service and update fixtures at patched Node floor
* fix(security): update Alpine test trust and aligned workflow contracts
* test: align guest runtime fixture and preserve mock exports
The official Docker images were built on Debian 12 bookworm, whose coreutils 9.1 lacks mv --exchange/--no-copy, so Doctor's btrfs NOCOW repair was always skipped in containers (e.g. Synology NAS). Build, runtime and sandbox images now use Debian 13 trixie (coreutils 9.7) with pinned digests and the NOCOW repair utilities; Node stays on 24 to match release CI. Installer test coverage keeps bookworm alongside trixie. Default/slim image +6.1 MB, browser +32.9 MB. Verified: default/slim/browser builds, isolated Gateway, Chromium, and a real btrfs NOCOW repair.
Fixes#171930
node-runtime-recovery.mjs imports cli-parent-lifetime.mjs after #174268.
Ship that dependency in both Docker launcher stages, cleanup smoke, and
the remote-node bootstrap artifact, and keep copied runtime fixtures in
sync. Require the module in the bootstrap archive regression.
Preserve existing launcher and detached update lifetimes. No new closure
framework, dependency, configuration, or timeout changes.
Preserve explicit profiles across standalone CLI respawns through one bootstrap-safe invocation owner. Select loose runtime/script arguments or direct compiled arguments from the embedded builder fact or adjacent manifest. Include the owner and compile-cache workers in packaged launchers and standalone builds.
Settle worker execution and native resource closure independently after snapshot failure. Release startup-refused broker claims only after native process and pipe closure, retain cleanup transport on operation failure, propagate Doctor snapshot errors, and cancel further inspections without losing maintenance restoration.
Document the private Unix-domain bind/connect allowance required by both loose and standalone snapshot workers. Keep network, home, Keychain, launchctl, and host-SQLite denials in the relocated verifier.
Validation: signed production-pinned JIT and bytecode artifacts at 4aa64f9ddc passed explicit-profile Doctor, Gateway/agent/restart campaigns, denied-IPC failure, and SIGTERM settlement in 364/375 ms with unchanged deadlines. Later source repairs passed owning-boundary regressions, scoped checks, and independent review. Signed artifact identity is preserved separately from the final CI head.
Exact-head CI for 9617855492: 172 successful jobs, 19 skipped, zero failures (run 38833042547). Tested merge 58c3b87a8594 has the same tree as the prepared PR head. No CI exception, rerun, or timeout increase.
* chore: refresh all dependencies with seven-day cutoff
Select compatible releases published by 2026-10-08T06:25:51Z across npm, native apps, CI actions, containers and downloaded tools. Align lockfiles, hashes, license labels and consumer fixtures; preserve documented compatibility holds and runtime floors.
* test: align remaining dependency refresh fixtures
Align the Linux native-hook pressure proof with the audited Codex 0.161.0 binary. Use the existing real-Gateway fixture for Telegram conversation-binding proof instead of unrelated package-install preparation; preserve every authority and transport assertion. Original CI failures and focused proof limitations remain recorded in the PR.
* fix(whatsapp): name reply plan declaration contracts
Preserve the existing six-field reply plan and branded dispatch parameter through named public SDK type references. This avoids TS4058 while emitting the package-local declaration boundary; runtime behavior is unchanged.
* fix: align dependency fixtures with current lifecycle owners
Await automatic plugin retirement instead of polling, retain exact Codex prompt ordering, and align the newly added UI media dependency with the already eligible 1.61.3 resolution. The complete prior dependency candidate and this incremental repair have independent scoped-clean review.
* test: retire obsolete Matrix preview and simplify Telegram fixture
Keep the existing message-content privacy regression and all Telegram provider failure, continuation, and visible-settlement assertions. Use the established real-Gateway fixture instead of unrelated packaged-install preparation; do not raise test or compiler timeouts.
* fix: avoid native hook priority inversion and palette hover leakage
Keep synchronous Codex policy relays at inherited process priority instead of nice 10. The 20-way two-core pressure failure lost nineteen hook completions at the unchanged ten-second deadline; preserve the complete stress, denial, retry and output assertions for exact-head CI.
Move the browser pointer off the select before checking its idle palette. Scheduled main reports the identical hover color failure. Independent P2 review is clean; local browser replay stalls in the pre-existing menu-opening phase, and Linux stress execution remains assigned to CI.
* fix: preserve sealed worker and browser lifecycle contracts
Retain native-disabled fs-safe behavior in sealed bundles and fail closed on a native batch request instead of emitting a missing native helper URL. Preserve the nonnative permission path and reject upstream transform drift.
Use controlled native animations for the WebKit closing lease, require abort in active Talk close, and scope video failure text to the alert surface. Independent P2 review is clean. Original worker archive case passes (39.390s; 283.23s total); original Talk and video cases pass (1.876s and 1.485s; 55.96s total), excluding unrelated cases. WebKit proof belongs to CI because its matching browser is unavailable locally.
* test: wait for side-turn and favicon startup signals
Refresh npm/pnpm, Cargo, Swift, Ruby, Gradle and CI/tool/image dependencies using the fixed 2026-10-07T02:36:46Z publication cutoff. Preserve documented compatibility holds and existing newer main pins.
Adapt TypeScript retained-source APIs and Vitest project cache registration; scope package declarations to package inputs instead of repeatedly compiling UI ambient types. Repair stale receipts, dependency contracts and test fixtures, including retention-safe memory timestamps and unordered rollback assertions. Re-audit OpenAI desktop source pruning and preserve main's native Solid migrations.
Scoped proof and isolated review are recorded in the PR. The maintainer explicitly accepts the documented remaining unclassified CI failures and authorizes force landing; this is not an all-green or inherited-only claim. Current-head security review passed. No release or deployment is performed.
Closes#171650.
After the pnpm 12.7 bump, frozen-lockfile installs validate every lockfile importer. The root Dockerfile was fixed in b7e788b23e; the documented smoke images still failed on current main: pnpm test:docker:qr (scripts/e2e/Dockerfile.qr-import, missing extensions/microsoft-foundry) and pnpm test:docker:cleanup (scripts/docker/cleanup-smoke/Dockerfile, missing examples/ai-chat). Both now stage every workspace manifest before the frozen install; the QR image still installs only the root dependency closure. Follow-up to #167923.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
When the updater or recovery selected the compatible private Node runtime and ran npm's JavaScript CLI with it, npm lifecycle children (preinstall and friends) resolved plain node from PATH and picked the unsupported system Node, so the install rejected itself. One shared PATH handoff now prepends the selected runtime's bin directory for every package-manager spawn in recovery, update environments, and explicit npm/pnpm execution, preserving npm_config_node and the explicit executable, scoped to the child only. Real-npm regression: lifecycle child reported v22.22.3 before, the private runtime after. Closes#164525.
* refactor(config): remove retired agents.list and default markers from the authored config type
The authored OpenClawConfig type still declared AgentsConfig.list and
AgentConfig.default after #162612 made config validation reject both, so
`satisfies OpenClawConfig` kept admitting fixtures and writers that Gateway
startup then refused (#163766, #163623). Production code also read the
untyped runtime agents.list projection, which structuredClone drops, so
config-mutation drafts and canonical configs silently saw an empty roster.
The authored type now rejects both shapes. Doctor and pre-admission
migration inputs use the Doctor-owned OpenClawConfigWithLegacyRoster type
(src/config/legacy.roster.ts), which stays structurally assignable to
OpenClawConfig, so legacy fixtures need no casts. Runtime readers use the
roster owners (listAgentEntries, resolveAgentEntry, resolveAgentConfig).
Raw default-marker compatibility for raw SDK inputs is unchanged.
The non-enumerable runtime agents.list projection is kept, untyped, for
plugins built against SDK releases through 2026.9.x and registered as the
deprecated compatibility record agent-list-runtime-projection (removal after
2027-01-02), documented in docs/plugins/sdk-migration/how-to-migrate.md.
Fixes found by the cutover:
- Feishu dynamic agents: lock-time duplicate and maxAgents checks saw an
empty cloned roster and wrote an agents.list that validation rejects.
- TUI abort, sessions_send, harness compaction preflight, and run-session
lookup resolved a default agent even when an explicit owner was known;
models.list now uses the ambient owner like models.ts.
- ACP session-metadata migration ignored plugin-declared owners; Talk lost
configured wake names; per-agent model normalization and model-auth policy
cleanup skipped canonical agents.entries.
About 1,075 test fixtures now author canonical agents.entries with the
explicit per-surface owners Doctor materializes; Doctor/migration tests keep
legacy input typed as OpenClawConfigWithLegacyRoster.
* refactor: convert roster fixtures added on main to keyed agents.entries
Keep runtime fixtures canonical and preserve explicit per-call ownership. Pin the Doctor schema rehearsal session-store owner without restoring an implicit default. Remove file-transfer reload selectors for rejected list and default fields; canonical workspace paths continue to cover roster changes.
* test(zalouser): keep raw legacy-list coverage in Doctor state migration test
The legacy-list case had been converted to keyed entries, duplicating the keyed-roster case. Doctor state migrations receive raw pre-migration config, so restore the raw agents.list input under a plugin-local raw roster type.
* fix(memory-host-sdk): preserve raw default-marker workspace inheritance
Use the shared raw legacy default-marker reader before first-agent workspace inheritance. Preserve explicit ownership resolution and restore the marked secondary-agent regression with the legacy input type.
* refactor: split oversized files below their line-cap baselines
Extract Mistral cache-cost normalization, sessions-send input readers, and Feishu roster collection. Move session-repair and QMD migration coverage into protected sibling suites and consolidate existing test fixtures without dropping assertions.
* fix(ci): clear lint, Docker e2e boundary, and ratchet failures for the roster cutover
Keep the npm Telegram live runner on a local historical-config type instead of importing src, fix oxlint diagnostics in converted tests, move the agents.list runtime projection compat record into its own module, split branch-grown files back under their line-cap allowances, and shrink the assertion-safety baseline for casts this branch removed.
* test: canonicalize fixtures added during main merge
* test(memory-core): type split QMD Doctor fixture as raw legacy config
The QMD cases moved into doctor-contract-api.qmd.test.ts lost the raw pre-Doctor config type, so check-test-types rejected their agents.list fixture. Share RawLegacyDoctorConfig from the test support module and use it in both files.
* fix(doctor): name canonical agent workspace paths in removed-workspaces warning
The warning reads agents through listAgentEntries, so it now labels configured workspaces as agents.entries.<id>.workspace instead of the retired agents.list path.
* test: type preserved canary inputs as legacy rosters
Support host-bound GitHub Enterprise discovery and repository defaults with presence-aware prepared cloud workers.
Preserve current identity and repository authority through clone, publication, cached reads and worker preparation. Keep explicit user destinations and supported Git URLs, separate public GitHub issuer paths, and retain cleanup, activation and stop-deadline guarantees.
Validated with exact-head CI, focused lifecycle/identity/UI regressions and native review. The maintainer also reports validation in an existing deployment; that evidence is distinct from the agent-run local and CI checks.
Co-authored-by: galiniliev <5711535+galiniliev@users.noreply.github.com>
Refresh application, plugin, native, build and container dependencies through the fixed 2026-09-19T16:27:11Z cutoff. Migrate native TypeScript snapshot/printer APIs while preserving compilation and filesystem contracts; retain existing patches and compatibility holds. Document offline container-image preparation.
Include the verified compiler process-census and loading-clock fixture repairs and deterministic warm-history regression. Adopt the canonical production history fixes from #159924 and #159955.
Land under the maintainer's explicit approval to treat proven pre-existing CI failures as non-blocking and repair main afterward. CI36365552098 failed an unchanged Android Compose fixture's asynchronous catalog projection assertion (3518 passed,1 failed); the Android/Gradle tree matches its main parent byte-for-byte. Security and dependency reviews passed. The final rebase preserves reviewed source changes and regenerates only the intentional Node-image documentation fingerprint. See PR159401 for complete validation and the follow-up repair obligation.
Consolidate repeated tooling flows while preserving command contracts. Fix swallowed HTML translation errors and browser-realm error handling in the Google Live smoke. Owner tests and CLI parity passed on Testbox; final broad gate replay follows a fixture lint correction.
Share build-scoped compile-cache ownership between the launcher and runtime. Reuse inherited namespaces, avoid redundant respawns, and retire superseded builds with best-effort seven-day and 512 MiB maintenance.
Testbox: 304 focused tests passed with one Bun-only skip; pinned changed-file checks passed. Thirty child launches used 41,544 bytes instead of 1,185,000 bytes, and same-build launch time fell from 2.46 s to 1.22 s. Persistent external-plugin source capture reuse remains outside this scoped change.
* refactor: remove TypeScript 6 from plugin runtime and tooling
Keep source plugin loading on Jiti and native module transforms, move development analysis and declaration builds to TypeScript 7, and preserve captured loader and input ownership contracts. Scaffolds compile to the same entry path without shipping a compiler in production.
* refactor: use native checker for restart preflight detection
* fix: keep test-directory docs out of native helper scans
* fix: preserve native compiler tooling across CI runtimes
Keep compiler-backed tests on the supported Node transport, preserve declared Windows aliases and partial-source analysis, and bind relocated SDK reports to their installed compiler. Retain strict package input admission and the existing fixture assertions.
* test: compare messaging guard diagnostics without sorting
* fix: bound native tooling memory and preserve bootstrap loading
* fix: bound native declaration builds with tsdown scheduling
* fix: retire compiler-only helpers from installed packages
* test: migrate routing import scan to native parser
* test(ui): wait for recovered model catalog receipt
Artifact and tool acquisition can recover from provider transport errors
without repeating tests. Existing recovery paths did not consistently
identify these attempts in GitHub annotations.
Emit warnings only when infrastructure recovery fires, preserve immutable
inputs and budgets, and keep terminal errors fatal. A synthetic HTTP 503
then 200 probe retained the exit status and produced one warning; a normal
download produced none. Owner tests, syntax and workflow checks passed.
Source and performance budgets shared fatal exits with correctness checks,
so ordinary growth could block otherwise valid changes. Centralize limit
severity and GitHub annotations/summaries, keep local checks strict, and
carry warnings across native lint, container, and BuildKit boundaries.
Keep semantic lint, types, API inventories, source ownership, invalid
measurements, process failures, and runner admission guards blocking.
Validation: P2 review clean; three Linux owner-configuration replays and
20 standalone policy runs passed; typechecks, targeted type-aware lint,
Knip export scans, workflow checks, formatting, and diff checks passed.
The changed gate found a test environment typing error, corrected and
verified by the root-test typecheck. One unrelated preparation process
cleanup failure did not reproduce in its diagnostic replay; no fix claimed.
* refactor: retire pre-June import and verification compatibility
Remove pre-June task, flow, and plugin-state sidecar imports, obsolete
runtime chunks, package/installer validation exceptions, the old MCP
attachment fallback, and the April self-upgrade lane with its orphan helpers.
Leave retired data files untouched and document migration through 2026.6.1.
Preserve June-and-later contracts and September delivery recovery receipts.
Refs #156190
* docs: route legacy upgrades through 2026.9.5
* test: await Telegram fixture lifecycle events
Replace the setup stopwatch with the actual stop event or terminal run outcome. Keep cancellation assertions and outer execution bounds, and prove early terminal outcomes fail promptly.
Validate the canonical package-install identity as well as the released global update label. Keep status, requested tarball, build identity, and no-activation checks unchanged; extend existing runner and parser fixtures for the candidate result.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(gateway): preserve work during recovered Node restarts
Let Unix Node recovery wrappers respect the existing Gateway stop budget.
Share startup-safe command classification and deadline facts, and resolve
managed restart intent against the live serving owner in its write
transaction with current update authority.
Preserve the existing public PID intent API, record format, and Windows
behavior. Keep cold lifecycle test preparation outside timed hooks.
Inspired by @ly85206559's wrapper-grace approach in #147054; this repair
is independently authored from main. Related: #146956. Windows cooperative
shutdown remains a follow-up.
* refactor(gateway): stabilize restart callback and test setup
Declare receiver-independent restart intent callbacks as arrows and retain typed signal spy handles for lint-safe assertions. Move cold lifecycle imports into test collection so worker preparation cannot consume timed setup hooks.
* feat(node): update headless runtimes automatically when idle
Stage private packaged node runtimes and activate only after all owned work
and cleanup settle. Preserve pairing and launch options, keep automatic
activations at least 12 hours apart, and leave shared-state migration and
Gateway installation ownership with the normal updater.
Document defaults, opt-outs, runtime version discovery, and recovery.
Support recoverable Windows selector replacement across service restarts.
Refs #151462
* fix(node): complete auto-update integration and settings defaults
Capture the launcher in compiled test runtimes and trusted wrapper inventories, register the package update proof, and use the canonical Kysely read path. Preserve the inherited enabled state in the config UI and align caller tests with the node shutdown lifecycle.
* fix(node): preserve retained plugin work during automatic updates
Require an explicit idle result from plugin commands, preserve older-plugin work, and connect bundled lifetime owners to automatic node updates. Join canceled inference and failed terminal cleanup before command settlement; keep historical state repair with Doctor. Document compatibility and extend installed-package proof for retained legacy plugin work.
* test(browser): align idle-work fixtures with runtime exports
* test(browser): extract proxy request fixtures
* test(node): retain idle assertions across native cleanup
Validate the successful update and fresh CLI before classifying the
published 2026.9.4 process's warning. Accept only the proved 9.4-to-9.5
case, with a fresh PATH entry bound to the updated global package.
Keep the original warning visible, preserve all other skew failures and
deadlines, and cover stale/foreign executables and failed update results.
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: RomneyDa <6581799+RomneyDa@users.noreply.github.com>
* fix(runtime): reuse an available compatible Node at startup
Share startup recovery between the launcher and legacy CLI runtime admission
so older updaters can run target Doctor through dist/index.js under an
already installed compatible Node. Preserve process-contract exclusions,
arguments, environment, standard streams, and exit status.
Refs #140465
* test(runtime): include recovery proof in E2E routing
* fix(runtime): secure Node discovery and decode service scripts
Reject relative candidates and cwd-resolved runtimes before probing, except
for explicit absolute PATH directories. Parse generated Windows command
quoting and recorded code pages without loading application dependencies.
Skip CP850 and CP949 with a diagnostic instead of guessing executable paths.
Use real task-writer fixtures for encoding, quoting, and fallback coverage.
Refs #140465
* fix(runtime): reject cwd-local manager symlinks
* test(runtime): keep recovery home outside launcher cwd
* fix(runtime): isolate recovery from dotenv environment
* fix(runtime): canonicalize discovery paths before use
* fix(runtime): preserve private Node recovery from home
* refactor(runtime): trim Node recovery comments and aliases
Behavior-neutral cleanup of the recovery launcher module: fold the serviceHome and managerHome aliases into homeDir and shorten five comment blocks to the invariant they protect.
* fix(runtime): gate node:sqlite on a NUL round-trip capability probe
Validate the loaded SQLite library and TEXT, BLOB, and JSON round trips across startup, doctor, Gateway install, update preflight, and installers. Admit capable Node 24+ vendor builds with a support-policy note while retaining the package engines and Node 22 exclusion. Refs #140465#140672.
* fix(runtime): expose capability diagnostics through doctor
Register the runtime check in the ordered Doctor contribution catalog. Keep shared audit types in a leaf module, include the bootstrap probe in duplicate scanning, and update native runtime and compiled-worker fixtures for the capability protocol.
* fix(update): preserve target Node version requirements
* fix(install): remove unused Node major probe state
* fix(scripts): use system Bash for macOS tooling and owned Mach-O fixtures
Pin native entrypoints and package commands to /bin/bash, guard portable heredoc callers on Darwin, and preserve Bash 3.2 boolean parsing. Streamed installers explain how to use system Bash when their input cannot be replayed.
Generate deterministic x86_64, arm64, and arm64e framework fixtures instead of borrowing /bin/ls. Preserve the existing framework pipeline repair from #141056 and verify merged slice bytes.
* fix(scripts): keep guarded portable scripts bash 3.2 compatible
* fix(scripts): keep macOS Bash CI coverage green
Distinguish sourced installer returns from stdin exits without ShellCheck unreachable-code warnings. Retain the shebang regression suite in changed-target routing, and repartition hosted tooling tails toward 50-second groups within the existing 150-second budget and 80-job cap.
Validation: 635 interpreter and routing tests plus 53 planner tests passed; ShellCheck, targeted lint, formatting, and fresh Codex review passed. The broader local changed-file check hit an unrelated existing dependency graph crossing through extensions/reef/node_modules/@noble/hashes; exact-head hosted CI remains required.
* docs(install): use system Bash in install and recovery commands
Align macOS-facing copy-and-paste commands and emitted installer guidance with the supported streamed interpreter. This addresses the remaining installer-command review finding without changing the PR body.
Validation: streamed help for both installers, install.sh dry-run, 16 selected fresh-install and upgrade lifecycle tests, formatting, diff check, and fresh Codex review passed. Landing remains blocked by unrelated provider-transport integration CI failure caused by an unchanged incomplete plugin-registry mock.
* fix(scripts): preserve streamed installs and CI packing
Keep public installer commands portable while replaying Darwin Bash 5.3+
stdin under system Bash through an immediately unlinked private temp file.
Retain actionable sourced-install rejection and the SC2317-safe check.
Restore the original CI packing policy and move the Bash policy scan into
its existing macOS tooling owner without adding a routed test file.
Validation: real Homebrew Bash streamed help and cleanup; 642 scan/routing
tests; 23 selected installer tests under both PATH orders; planner cap and
coverage tests; 139 Bash syntax checks; ShellCheck; 1,135 changed-gate tests;
focused lint/changed-check repair; fresh Codex review with no P0/P1 findings.
* fix(release): freeze shipped plugin scan inventories before current shrink
* test(release): distinguish installer no-op from applied update
Keep the baseline-to-candidate update strict while separately validating the documented already-current outcome for the second identical-candidate invocation. Require unchanged build identity, successful staging without activation, and an idle service namespace; do not count the no-op as an applied upgrade.
* docs(release): name the already-current idle proof accurately
* fix(qa): verify leased Telegram tester group access
Check tester membership and effective text permission in the leased user driver before group readiness. Reuse the check in doctor and select trusted skill scripts for frozen release candidate QA. Preserve supported private DM turns and leave credential repair to the pool owner.
* ci: install Chromium for native live browser tests
The native-live-test shard includes the real Gateway widget restart proof,
which launches Playwright after restoring the interrupted session. Chromium
was installed only in separate Repo E2E jobs, leaving the live shard without
its required executable.
Install the candidate UI's pinned Chromium and system dependencies only for
the selected native-live-test row. Preserve profile selection and all test
gates. Verified the unchanged dc420 widget restart test with real OpenAI,
Gateway process replacement, and interactive Chromium dashboard assertions
on Blacksmith Testbox; canonical workflow checks and formatting also pass.
* test(release): prove supported cross-OS 9.2 transition
Select the explicitly supported external package-manager and fresh Doctor
transition only for 2026.9.2 to 2026.9.3. Preserve the old updater's safe
schema-15 refusal as negative evidence and never report self-update passed.
Verify backup, exact package identity, schema migration, retained settings
and session history, candidate serving version, and a fresh persisted turn.
Keep credential-bearing backup archives out of CI evidence and remove them
on both successful and failed runs. Other release pairs retain existing
updater and Windows fallback behavior.
Validation: 13 cross-OS upgrade lane tests, two pre-fix regression failures,
full changed checks, and independent review. Real packaged cross-OS/live
qualification remains required against the aggregate candidate.
* test(installer): prove supported historical package transitions
* test(release): exercise same-schema updater boundaries
Keep updater-specific plugin repair and consent checks on the prepared
candidate, then target explicit synthetic later versions with the same
runtime and storage schema. Retain installed-version and plugin-policy
assertions, and remove the obsolete legacy post-update fallback.
Add versioned future-tarball generation to the existing first-hop fixture
owner, with immutable input and source/target digest receipts. Restore the
reserved runtime-promotion staging ignore in package-derived Git fixtures
so the updater's unchanged-source check stays meaningful.
Validation: 26 focused tests, a pre-fix Git staging regression, full changed
checks, exact candidate tarball fixture generation, and P2 review. Actual
Docker update/consent/channel qualification remains required in aggregate CI.
* test(release): verify channel update staging cleanup
Assert the real channel flow refuses ordinary untracked user files without changing source, then require successful channel updates to remove every reserved runtime staging entry. Preserve recovery data when the assertion detects leftovers. No ignore or production cleanup policy is broadened.
* test(onboard): select configured model through explicit picker
* ci: pin release performance checks to reviewed Kova accounting
Select the reviewed Linux process-lifetime CPU accounting and bounded worker-watchdog implementation from Kova PR #110 for canonical, legacy-list, and trusted live fixtures. Keep existing trust classification, timeout values, and performance thresholds.
* fix(ci): distinguish bundle build modes in job names
* test(release): build matching future runtime fixtures
Derive a synthetic Codex runtime cohort from its verified candidate package by changing only package.version and openclaw.build.openclawVersion. Require matching source metadata and preserve payload, constraints, immutable input, and source/target digest receipts. Reuse the existing private tarball lifecycle and sequence validation. Validated 11 focused tests, pre-change CLI failures, full changed checks, and P2 review.
* docs(release): prepare private QA before local E2E
* fix(release): admit package metadata before validation dispatch
Port the reviewed early source admission into trusted Tooling, preserving the current selected REST transport. Reject invalid version notes and misaligned core packages before any Git push, non-GET API write, or workflow dispatch; retain explicitly allowed substantive draft notes.
* test(release): qualify supported historical upgrade transitions
Prove the published 2026.8.2/2026.9.2 to 2026.9.3 external package-manager and fresh Doctor contract through one shared helper. Preserve the old in-process updater refusal and schema 15, require owner-stopped migration with a verified private backup, and verify schema 16 plus retained Gateway history afterward.
Keep current-runtime update coverage distinct: managed restart uses separately identified future core and matching runtime fixtures, with real updater, canary, service replacement, authentication, and serving checks. Fix fixture-only channel environment pollution and mock serving nonce responses.
Sealed Docker journey, historical first-hop, current-candidate survivor, root-managed VPS, and onboarding pass. Managed-auth historical preservation passes; its future canary exposes an independent existing plugin projection blocker, retained as failing proof for the candidate repair owner. No product schema or refusal guard changes.
* test(release): narrow recorded update command before indexing
* fix(ci): align historical upgrade fixture ownership
Keep all seven external transition assertion cases with the first-hop package fixtures: both own the historical upgrade boundary and now share its temporary-state lifecycle. Preserve helper test selection and all assertions while avoiding an additional standalone tooling group.
Provide the new inference and future-package preparation boundaries in isolated service, mobile, and cron bootstrap probes, and verify each updater argument without changing readiness or migration assertions. Register the path-launched assertion CLI as a Knip entry.
Validation: 67 related tests; 70 exact-merge planner and combined-suite tests; five 80-job stress plans; full Knip unused-file scans; scoped checks and P2 review.
* fix(ci): model upgrade preparation in isolated probes
Complete the companion fixture and Knip repairs for the preceding transition-test consolidation. Model the independent inference and future-package preparation producers, verify exact updater argument boundaries, and retain service-readiness, authored-state, and cron migration assertions. Declare the path-launched transition assertion CLI in the existing Knip entrypoint list.
* test(release): preserve fixture registry on managed restart
Capture the fake service manager registry alongside its endpoint paths, then refresh that owned context after preparing the future cohort. Projected native service callers cannot drop or replace it; transient update state still stays outside the managed child.
The executable service regression fails on the original shim and passes with missing and conflicting caller registries. Four focused tests, the changed gate, and P2 review pass. Reuse the existing d928 package for the final managed-upgrade replay.
* test(release): preserve prepared UI identity in future fixtures
Advance synthetic package versions while retaining the opaque build ID already embedded in unchanged Control UI assets. The canonical asset-health regression fails the prior builder as stale, then verifies readiness and unchanged UI bytes for both future fixture sequences. Package-version update admission and managed-restart proof remain unchanged.
* test(release): retain manager-owned fixture policy
Capture the existing automation and offline-channel policy with registry identity when generating the manager shim. Native service clients project these values away; losing them activated retained synthetic channel credentials and correctly failed readiness. Restore only this explicit manager allowlist and keep transient update/compatibility state excluded.
The executable service regression fails on missing manager flags and passes across projected or conflicting caller environments. Four focused tests, the full changed gate, and fresh P2 review pass. Actual corrected managed Docker proof remains pending.
* docs(ci): keep bundle identity with routing guidance
* fix(release): retry transient GraphQL EOF failures
Classify the observed gh unexpected EOF transport failure within the existing five-attempt retry budget. Preserve authentication, invalid-response, inventory and snapshot handling. Exercise recovery, exhaustion and fail-fast errors through the real verifier CLI with a fake gh transport; also modernize the existing disposable-array sort required by touched-test lint.
* test(release): align survivor fixtures with manager preparation
Supply manager environment JSON to directly launched supervisors, and model the independent manager preparation phase in config-parking and companion fixtures. Preserve service readiness, restart, diagnostics, and strict phase-order assertions without changing production behavior or test limits.
* test(release): align upgrades with deferred schema publication
Restore installed-updater survivor and first-hop coverage after shared migration ownership moved into the durable update ledger. Record applied schema content separately from published schema version, retain the genuine missing-chunk negative control, and label external installation as an alternate with no self-update attempt. Preserve production-owned unsupported migration refusals.
* test(release): restore supported packaged upgrade coverage
Restore real 2026.9.2 to 2026.9.3 self-update after ledger-driven schema migration support. Keep retained conversations, private backup, settings, candidate identity, and serving inference proof. Require migrated content independently of publication grace and remove obsolete external-install diversion from cross-OS and installer update smoke. Shared external helper remains separately owned.
* test(release): refresh legacy manager before updater restart
Bind the service manager to the candidate registry before the published baseline updater starts its managed service. Preserve restart verification for successful and recoverable outcomes alongside explicit future targets. Exercise stale registry capture, replacement failures, pre-update identity, and attribution without changing timeouts or caps.
* fix(runtime): require Node builds with lossless SQLite reads
* fix(runtime): preserve upgrades and guard sealed workers
Validate downloaded Node before switching the active runtime alias, reject unsupported sealed-worker runtimes, and keep the Gateway error fixture on a supported Node release. Document the approved ARMv7 and older macOS compatibility losses and decoder fix boundaries.
* test(runtime): use typed process exports in worker fixture
* test(runtime): align installer fixtures without growing test shards
* test(runtime): align release and guest runtime fixtures
* fix(test): canonicalize Windows temp roots for Node 24
Expand Windows short paths before creating test directories and owned child environments. Node 24 filesystem watchers otherwise abort when native long event paths differ from inherited short temporary paths. Preserve explicit custom-root spelling and existing cleanup ownership.
* test(ci): run Windows temp-root regressions in the native lane
Prune the workspace bind mount during config ownership repair while retaining workspace-root and OpenClaw metadata repair. Preserve project ownership on same-filesystem mounts and keep the existing no-follow protections.
Verified with real offline Docker setup on current main and the candidate, fresh/rerun and sibling controls, and independent behavior validation.
Closes#140968
Co-authored-by: Ayaan Zaidi <hi@obviy.us>