Darwin killpg excludes zombies and returns EPERM when no signalable group
member remains. Strict normal-exit cleanup mistook this terminal state for
a surviving process group, even when later drainage observed termination.
Reuse the existing zombie census for Darwin, including BSD state flags,
and reconcile a group reaped during the census with a fresh ESRCH probe.
Both observation and termination require positive completion evidence;
live, mixed, and uninspectable groups retain their cleanup failures.
Keep snapshot work inside the existing escalation and drainage deadlines.
Native same-uid Z and ZN groups reproduce EPERM for signal 0 and SIGKILL.
The original owner fails four regression cases; the repair passes all 13.
Shared owner/output tests pass (146 passed, one platform skip). The full
mac-elevation-host shard passes all 123 cases in 383.63s; final metadata
replay passes all 13 selected cases. Independent review is scoped-clean.
Production delta: +44 lines for bounded Darwin termination evidence.
Test cost: node scripts/run-vitest.mjs test/scripts/managed-child-process.termination.test.ts --maxWorkers=1: 5.83s wall; node scripts/run-vitest.mjs test/scripts/managed-child-process.tree.test.ts --maxWorkers=1: 5.05s wall.
* fix(cli): release plugin resources when help finishes
Uncached CLI metadata loads now use the existing inspection acquisition when an executable invocation owns them. The source-plugin regression verifies that invocation release joins module disposal. Caller-owned programs retain their existing lifetime.
* fix(plugins): release retired registry preparation scope
Create the aggregate retirement observer outside the registry preparation
scope so it retains only child waiters. Preserve per-observation options,
cleanup ordering, failure identity, and deferred consumer results.
The unchanged cold registry-retention regression failed on the CI Bun
runtime before this change and passes after it. The original seven-file
shard passes all 172 cases, and Node retirement coverage passes 20 cases.
* fix(ci): carry the chat attachment lint repair
Carry the exact two-file fix from 2e95cdba84
(#160159). Move the unchanged image decoder into its existing helper
to restore the 700-line limit without changing attachment behavior.
Targeted lint and all 21 attachment tests pass on this candidate.
Independent review found no actionable defects.
* test: retain complete lifecycle helpers in lease fixtures
* test: isolate local command fixtures and join recovery cleanup
* test(ci): preserve CLI runtime ownership and harness staging
Keep the moved CLI command fixture in its runtime prerequisite group and
preserve complete agent coverage across the core and CLI process owners.
Carry the test-only trusted-harness fixture fix from #160024.
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(tests): scope Vitest preload to test workers
Apply the jsdom adapter only at Vitest worker entry points while preserving
package-local runtime resolution. Ordinary Workers may inherit the preload
without having a Vitest dependency. Exercise default native inheritance and
await worker termination.
Copy the static-check evidence helper into lint fixtures so the real oxlint
entry point can load its current import closure.
Validation: reproduced both original failure causes before repair; all 76
affected tests pass (351.44 seconds in Vitest), as do canonical changed-file
checks and independent review.
* test: isolate public runtime surface planning fixtures
Verify public runtime entries and packaged assets with a synthetic publishable plugin after the Diffs forwarding APIs were retired. Preserve the existing planner assertions without depending on one bundled plugin layout.
* fix(ci): carry shared lint repairs into CLI preparation
* test(tooling): repair extracted PR and npm fixtures
* test: retain gateway cleanup and isolate Windows temp paths
Close the prewarm gateway when client connection fails and retain cleanup
errors during orphaned recovery. Keep Windows-under-Bun coverage on
host-owned temporary directories, matching the fixture fix in #160985.
Validation: 13 focused fixture tests and canonical changed-file checks.
* fix(ci): keep extracted manifest within script contracts
Resolve inherited manifest lint errors without changing job selection. Move its closed true/1 flag parsing to the dependency-free argument owner and include that helper in trusted fixture copies. Validation passed 718 tests with eight existing skips, canonical changed checks, fixture lint, and independent review. The 74-case argument helper file took 1.79 seconds at one worker with warm inputs.
* test(state): apply upstream snapshot custody fixture isolation
Reuse the fixture repair from #161598 (af16b80a22). Keep the real exit callback and every custody assertion while isolating the synthetic cleanup owner from preceding files.
* test(pr): drain fake GitHub streams before exit
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Select the simulator before compilation, then boot and slim that exact
simulator alongside the app build. Join preparation before XCTest, retain
its failure log, and bound a hung join without changing test selection or
build settings.
Validate both focused groups on cold and warm native runs (139 tests each),
plus preparation failure and timeout controls. Linux proof includes full
test types, the whole tooling config, changed checks, source contracts,
and both preflight harness shapes for PR and scheduled-main inputs.
Use structured Tool Search config from 2026.9.7 while retaining the legacy code-mode migration specimen for older baselines. Read the existing coverage receipt version for baseline assertions; keep post-upgrade cleanup checks strict.
Use the existing memory retrieval pool for noncreating index selection, counts, and vector inspection. Capture caller placement and matching facts before dispatch, share the existing scrub rules, and return only selected row identities and counts. Keep final lineage checks and write settlement with their existing transaction owner.
Validation: causal host count regression, 150 owning tests, native fetched-row and byte bounds, captured-input and read-error controls, full changed-file gate, and independent review.
* test(copilot): deslop t0366 tests
* test(config): deslop t0377 tests
* test(plugins): deslop t0368 tests
* test(auth): deslop t0381 tests
* test(ui): deslop t0382 tests
* test(release): deslop t0384 tests
Port the shard while preserving newer SDK acknowledgement coverage and all six strengthened trusted-tooling cleanup scenarios.
Validation: 109 tests passed with no skips on Blacksmith Testbox from a fresh-main proof checkout; oxlint, oxfmt, diff checks, and independent review passed.
* test(agents): deslop t0369 tests
Port 2533d418dcab93da1aec73ee224072e29402ba08 onto the campaign lane, preserving all 25 test blocks changed on the lane and its four test removals. Retain the existing max-lines baseline because preserving that coverage keeps the planner suite above the limit.
Validation: all 60 tests passed on Blacksmith Testbox from a fresh-main proof checkout, with no skips. Scoped oxlint, oxfmt, diff checks, and independent review passed.
* test(pdf): deslop t0374 tests
* test(auto-reply): deslop t0378 tests
* test(gateway): deslop t0371 tests
* test: preserve persistence and release workflow coverage
Retain cold logout reload, persisted plugin-state reopening, and real workflow-input compatibility while keeping the batch test reductions.
The ClawHub release planner and prepared-artifact resolver read the new public publication-state endpoint (/api/v1/packages/{name}/versions/{version}/publication). Only absent versions are republished; pending ones are skipped, and failed ones are excluded, with the recover command printed to the step summary. A 404, or a 200 without a state field, falls back to the legacy version probe.
Share filesystem core package discovery with npm bundle preparation. Include every selected core package in beta-floor diagnostics and block postpublish on any core floor failure, while preserving reused and superseded core selectors.
Keep the Gateway isolated/database-worker cohort at its existing two-worker budget so cold startup has room within unchanged test deadlines. Preserve former eight-worker complete generations as conservative timing floors without relabeling them as current measurements.
Validation: 325 owning tests, selected changed checks, and fresh managed review. Generated job counts and coverage are unchanged. Exact changed CI remains required.
* fix(update): settle service receipts and interrupted rollback
Await the existing bound worker phase receipt before native service stop,
then revalidate the original executor/requester. Retain already admitted
compensation through signal settlement, including its later phase writes,
without retaining the unbounded forward operation.
Keep current-core and rollback authority policies distinct. Preserve the
existing ledger kernel, records, schema and recovery semantics.
Related: #161385
Canonical stale-baseline context: #161766
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(test): register post-update worker fixture once
Keep its existing worker registration instead of adding a duplicate that
prevents CI compact timing generation. Preserve the strict uniqueness
guard and the three newly required worker routes.
The actual CI merge failed manifest generation and its existing registry
regression; the baseline and one-entry correction passed the same selector.
* test(update): retain real owners in module failure fixtures
Load the mutable-signal and execution-guard owners in the existing VM
fixture so post-update failures reach their original backup-retention
assertions. Keep all19 inner cases and the synthetic service boundary.
The original three-file CI group failed on the unexpected dependency call;
the two real-module additions restore17 outer passes and19 inner passes.
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Retain complete core graph validation in the existing required parallel boundary row for canonical extension-only changes. Discover all four noncore compiler consumers while preserving full fallback for aliases, missing inputs, mixed changes and incomplete inventories.
Zoom meetings, Teams meetings and Slack huddles each carried the same
thirteen-file glue layer (entry, CLI, CLI metadata, config, errors, node
host, node invoke policy, runtime facade, probes, setup, Chrome transport,
types), feeding one platform adapter into a dozen separate
MeetingPlatformAdapter helpers. A new MeetingPlatformAdapter member,
defineBrowserMeetingPlugin, composes those helpers from one declaration,
so each plugin now declares only what is genuinely platform-specific. A
fourth browser meeting platform costs one declaration.
The helpers the factory replaces stay exported and are marked deprecated,
since published plugin versions call them. Tests inject Chrome bindings
through the factory's public spec instead of mocking core internals. The
three plugins drop their unused typebox dependency.
Zoom and Teams now require OpenClaw 2026.9.8 (install and plugin API
floors, catalog, docs), like Slack huddles, because they call a member
2026.9.7 lacks. Released plugin packages already require a matching host.
All plugin registrations and 42 generated page-script hashes are
identical to main.
Release note: Zoom meetings and Microsoft Teams meetings plugins require
OpenClaw 2026.9.8 or newer.
Moves the bundled runtime from fork release ee83b78b18 to
openclaw-v1.4.3-20260930-57fadf566d-webkit-f20ce77445: the upstream Bun
sync through ba3f27d1d1, the full CI-line compatibility port, the macOS
/dev/fd copy fix, child_process stdio handles, bounded compile-cache exit
persistence, TLS over paused CONNECT transports, and the net/fs/
structuredClone parity fixes.
Include generated regular CLI children in both serial packing paths while preserving the 150-second child and 250-second job limits. Keep runner, worker, preparation and process policies intact.
The focused planner regression and neighboring budget case pass in 33.87 seconds on macOS. A local manifest probe emits 88 instead of 89 rows with the identical 3,884-target inventory; Linux integration proof remains required before landing.
The intact published-upgrade-survivor runs in every admitted hourly main CI run
and Full Release Verification through its normal_ci child. Preserve the exact
legacy-operator-state scenario with auto-auth when the target declares it.
No PR owner changes select this survivor, including updater, Doctor,
state-migration, or direct survivor changes. The other five Docker seed lanes
keep their existing PR owner selection.
Frozen historical targets retain their supported base fallback; invalid
catalogs fail. No survivor scenario case or assertion is removed.
Raise first-hop lane weight to two under the existing npm limit of five, admitting at most two concurrent lanes while permitting one to overlap the weight-three survivor. Budget three 3500-second waves plus 20 minutes for the survivor and 10 minutes for setup/artifacts: 205 minutes, rounded to a 210-minute job timeout.
With the six-way contention bounded, return package-update-self-upgrade to the stable profile it was dropped from for 2026.9.7 (#161291, #161257).
Carry the exact per-target routing results through the same planner invocation instead of resolving them twice more. Preserve canonical ownership checks, plugin opt-ins, fallback behavior, and selected rows.
SwiftPM builds each dependency for its own floored platform, so
KeyboardShortcuts (macOS 10.15, built for 12.0) emits its weak
Clock.sleep(for:) ContinuousClock specialization with a 112-byte async
frame while modules built for macOS 13+ emit a 128-byte one. The linker
coalesces the body and the frame descriptor independently, and the
2026.9.7 arm64 build paired a body that writes byte 119 with the 112-byte
descriptor: the 2026.9.6 launch-abort shape that the release async-frame
audit now rejects.
Pass -target <arch>-apple-macosx<LSMinimumSystemVersion> to every Swift
module in both release build commands so all coalesced copies share one
frame layout, independent of dependency pins or link order.
* feat(macos): run the private app runtime on the OpenClaw Bun fork
* fix(macos): let the bundled runtime load unsigned plugin addons
* test(macos): remove obsolete worker pruning closure tests
* test(macos): drop stale packaging test imports
* test(macos): migrate CI scope cases to runtime paths
* fix(release): sweep stale publish children before dispatch and wait for the beta-floor sync
* test(release): drive stale-child guards before dispatch in workflow fixtures
* fix(release): bound publish preflight observation, narrate frv continue, and surface SDK acknowledgement early
* fix(release): replay failed preflight reads with their exact filter
* test(release): model the exact-tag release lookup in preflight inventory fixtures
* fix(qa): pair Inspector pages with fresh dashboard links
Acquire a fresh single-use dashboard handoff for every Inspector page.
Cover real pairing, replay rejection, identity and receipt selection,
reload, and Chat draft preservation in a release-only browser fixture.
Real Gateway proof: 81.29s wall including prerequisites, 17.84s test body.
* fix(ci): complete Inspector pairing fixture inventories
Align private-server discovery and non-release counts with the Inspector
fixture, and include it in the frozen-target fallback command. Shorten
nearby comments to preserve the existing workflow size limit.
Workflow guards: 137 passed, 8 skipped; 85.65s wall.
Focused routing: 6 passed; 11.77s wall.
* fix(ci): include preflight manifest in trusted checkout
Reuse the existing scripts groupBy owner in the shared test-report renderer. Preserve first-seen order, finding order, complete counts, output caps and all CLI/guard contracts. Remove six production lines without changing tests or dependencies.
Validation: 19 existing focused cases, scoped lint, both zero-cycle checks and independent review. Release notes: internal tooling cleanup only.
* refactor: consolidate cross-directory duplicate code
Reuse canonical parsing, bounded-map, session-scope and service-binding owners. Share Markdown breakpoint scanning and Responses web-search detection; route lazy WebSocket consumers through the existing portable transport and remove their obsolete build rewrites. Preserve SDK, wire and persisted-state contracts.
* refactor: reuse allow-from projections in channel setup
* refactor: share literal schema merging through an internal owner
Keep schema guards and provider-specific flattening intact. Isolate the shared web-search predicate from exported projection types so its private declaration does not enter SDK type closures.
* refactor: reuse shared listeners and remove forwarding helpers
Reuse existing listener, normalization, setup-visibility and cache-control owners. Preserve callback ordering, error propagation, string filtering and public SDK exports. Remove obsolete internal aliases and their stale test mocks.
* refactor: retain SDK-reachable setup visibility wrapper
Drop the setup-visibility cleanup group after the strict SDK comparison identified its namespace declaration in 123 reachable export closures. Preserve the existing API without acknowledgement or baseline changes.
* refactor: reuse canonical helpers across runtime consumers
Reuse result, numeric, string, filesystem, blocked-key, and map-eviction owners while preserving caller policy and output. Remove redundant private branches and repeated comments. Doctor inputs, transformations, warnings, and persisted state remain unchanged.
* refactor: consolidate shared runtime and tooling operations
Preserve per-caller validation, ordering, diagnostics and public SDK contracts while reusing canonical owners. Correct the Discord plural reply-count diagnostic with an existing handler regression.
* refactor: narrow consolidation to retained runtime owners
Drop the new SQLite scope and cache invalidation extractions after their local fixture preparation exceeded the maintainer quick-validation budget.
* refactor: keep Discord cleanup behavior neutral
Drop the optional diagnostic spelling change and its unvalidated new test under the maintainer quick-validation limit. Runtime import edges are unchanged; the reverted test only removes an import edge from the verified acyclic graph.
* fix: repair consolidation checks and restart fixture
Remove two obsolete imports, tighten assertion counts after cast removal, and load the real null-writer in the restart outcome VM fixture. The focused restart fixture passes all 19 existing native cases.
* refactor: drop unproven session-runtime clone groups
Keep the original Codex environment reader and session-runtime helpers after an unattributed worker teardown failure. Preserve the test assertions and leave worker lifecycle repairs to their owner.
* refactor: preserve main sandbox string filtering
* test(gateway): await yielded orchestrator cleanup
Wait for the existing registry cleanup publication instead of racing real SQLite worker completion against a two-second polling window. Reuse the plugin-subagent observer and bind the new waits to the test abort signal so timeouts release their subscriptions.
Keep yielded follow-up dispatch on real timers so the acknowledgement helper cannot prematurely run the registry sweeper against mocked run liveness. Preserve all requester lineage, announcement, delivery, cleanup, and predecessor lifecycle assertions.
(cherry picked from commit 0591abe71e703b7cf7c69a42cd8b93287d9fe8d9)
* fix(test): stop resume registry sweeper before gateway teardown
The resume Gateway fixture left its subagent registry sweeper scheduled
across files. A later tick used the retired module generation to open a
shared-state worker against the next fixture's state directory. The worker
registered with the old database lifecycle, escaped current teardown, and
rejected the recreated SQLite pathname.
Reset the fixture-owned registry without persistence before closing the
Gateway so its timers stop before database retirement.
Validation: the six-file same-worker driver reproduced the pathname error
before the fix (270.19s instrumented), then passed all 49 tests (215.72s).
The delete-state-lifecycle file passed all 10 tests alone (102.65s wall).
Targeted oxfmt, oxlint, git diff --check, and independent review passed.
All diagnostic instrumentation was removed.
(cherry picked from commit 613b3f8818d21d0c0d65333b29aabce11dd5afe9)
* test: settle reply recovery before deleting fixtures
The aborted-restart fixture could delete its store while asynchronous
main-session recovery-owner release was still preparing a write. Tracing
reproduced that release recreating/registering the prior store during the
following onAdopted test, invalidating the shared registry generation.
Join reply successor-admission barriers and close each fixture database root
before deleting its directory or resetting the reply registry. Extract the
fixture owner to keep the existing large test file from growing. Re-enable
the adopted-claim cancellation test. Production registry guards and retry
contracts are unchanged.
Validation with OPENCLAW_E2E_SKIP_BUILD=1 pnpm test:e2e:gateway against
src/auto-reply/reply/agent-runner.runreplyagent.e2e.test.ts:
- Original file: 220 passed, 1 registry failure, 1 skipped; 358.38s Vitest.
- Original isolated adoption case repeated 20 times: passed; 170.95s Vitest.
- Repaired aborted-restart/cancellation/adoption sequence: 3 clean runs,
3 tests each; CLI wall 225.68s, 190.48s, 99.70s.
- Repaired full file: 221 passed, 1 different steering timeout; 528.47s Vitest.
Remaining failure: keeps the replacement source when retired admission
completes, first source admission did not persist (existing 5s guard).
Focused replay passed in 151.18s Vitest; this does not establish a fix for
that timeout. No timeout was changed.
- Source test types, scoped oxlint, formatting, and independent review passed.
Broad check:changed guards passed through the core graph boundary; stopped
before its duplicate messaging type pass. pnpm tsgo:test:src passed that
graph plus the remaining source test graphs.
The full original CI shard and Telegram case were not replayed within the
requested 35-minute investigation limit.
(cherry picked from commit 0b679e62f6)
* fix(release): retire the 2026.9.7 live-shard waiver before main moves to 2026.9.7
RELEASE_WAIVED_LIVE_FILES (28597852) keyed on package version 2026.9.7 dropped three live files whose only case was skipped on the release branch. Main keeps those cases enabled, so once the closeout sets main to 2026.9.7 the adapter would silently stop running them. Refs #161083#161084.
* chore(release): record the shipped 2026.9.7 changelog on main
CHANGELOG/2026.9.7.md, its contribution record, the index entry, the finalized Unreleased section, and the Matrix plugin changelog, byte-identical to the 2026.9.7 release SHA c074824a.
* chore(release): set main to the shipped 2026.9.7 version and record its update compatibility
Root version 2026.9.7 with pnpm release:prep version alignment, the macOS Info.plist version, and the verified npm tarball (sha512-/8N2Ln…RQwRWA==) recorded in the update compatibility inventory.
* test(gateway): move yielded orchestrator follow-up cases into their own module
The 0591abe7 forward-port grew agent.sessions-and-models.test-utils.ts past its line-cap ratchet. The yielded-orchestrator follow-up matrix is a self-contained case set, so it moves unchanged into agent.yielded-orchestrator.test-utils.ts, still loaded by agent.test.ts in the same module graph.
* feat(release): accept exact-job recorded flakes in release validation
A release lead can classify one failed Normal CI job of a Full Release
Validation run as a flake through the trusted classification workflow. The
receipt binds the exact job id and attempt, CI child run, FRV parent run and
attempt, and Release SHA, and carries a tracking issue or PR plus a reason.
Release Decision, the manifest, the publisher's live re-derivation, the step
summary, and the GitHub release notes tail treat it as a visible advisory.
Required classes and every other child stay blocking.
* docs(release): fold recorded flakes into the shared release boundaries
* fix(release): scope flake receipt discovery to the CI child run
* fix(release): require main lineage for flake receipt producers
* test(release): copy the flake classification module into tooling fixtures
* fix(release): keep advisory-only release notes verifiable
* fix(ui): stop serving a failed Control UI build on the next Gateway start
Rolldown writes the complete bundle, runs the writeBundle hook, and only
then reports aggregated resolve errors and exits non-zero. scripts/ui.mts
built straight into the served dist/control-ui and reused the runtime build
identity, so a failed build left a correctly stamped tree that the Gateway's
asset health check accepted as ready on the next start (observed: a bare
markdown-it-emoji import broke the Control UI after a gateway-profile worktree
install skipped ui/ dependencies).
scripts/ui.mts now builds into a same-depth dist/control-ui.build-<pid>-*
sibling, runs both validators against it, and renames it into place only on
success, restoring the previous output if publication fails. Dead-process
leftovers are reclaimed on the next build and tsdown's dist cleaning skips
in-flight staging trees. The gateway worktree-setup workload now installs
./ui... because the Gateway builds the Control UI from source on first start.
* fix(ui): restore the previous Control UI bundle after an interrupted swap
A builder killed between moving dist/control-ui aside and renaming its staged build into place left the previous complete bundle only in a dead-process .retired sibling, which the next build's leftover cleanup deleted. The next build now restores the newest dead-process retired bundle when the served path is missing, before reclaiming leftovers, so a failed retry still serves it.
* fix(ui): keep interrupted Control UI builds out of packages
A killed builder cannot reach its cleanup, so a dist/control-ui.build-* staging or retired sibling can survive until the next UI build. Exclude those siblings from the package files list, which also drives the dist inventory, and type the new UI test fixtures for the scripts test lane.
* fix(ui): retry transient Windows denials when publishing the Control UI build
Windows scanners and indexers can briefly deny renaming a freshly written or served directory with EPERM, which failed an otherwise valid rebuild on its first attempt. Every publication rename now retries EPERM, EACCES, and EBUSY on a bounded 100-1600 ms schedule (about 3 s) and keeps restoring the previous bundle when the denial is permanent.
Process-census capability needed to distinguish a dead managed-service handoff owner from a surviving descendant: a Windows process census (PID, start identity, command line, cwd, owner SID with the foreign-owner rule from the Unix contract), verified Unix UID provenance for incomplete observations, and retained-artifact reference matching that reports matching versus unverified PIDs. Existing callers keep their classification when the new evidence is absent.
Refs #159897 (the reclaim itself follows in #160488).
Landed under the pre-existing-red rule: the remaining CI failures were current main reds in the merge window (fast-lane config expectation fixed by e0ec544eb1; cron service tests fixed by 5f76cc437d; update-candidate-canary from b36eb3e7b1).
Adds `pnpm frv watch --run <parent>`: it resolves Full Release Validation children from the parent's dispatch-job logs and reports each attempt transition and failed job once, with runner labels. It tolerates transient GitHub failures and resumes from a small state file.
Adds `pnpm frv rerun --run <parent> --child <key|run-id> [--max-attempts N]`: a bounded, audited single rerun-failed-jobs request. It reruns the green producer when a consumer binds its run attempt (#161317) and checks the new attempt for duplicate or missing jobs.
Retires `pnpm frv prioritize --run`, since the priority variable no longer controls admission. `--restore` stays.
GitHub omits empty-string workflow_dispatch inputs from github.event.inputs,
so every sealed child receipt lacked the "" defaults that the parent-side
request filled in, and receipt validation rejected every candidate. The
per-candidate errors were swallowed, so dispatch logs never said why.
Treat empty and absent inputs as identical on both sides, only spend the
five full validations on receipts for this target and tooling, scan 100
runs, and log why each candidate was reused or rejected. Reuse now requires
the child's Tooling SHA to equal the current parent's, enforced at dispatch,
plan sealing, and final verification (previously any main-ancestor tooling
was accepted, which would have become live with this fix).