materializeNativeCompiler copied the whole native typescript package into
every fixture. 482 of its 493 files are dist/ (the typescript/unstable/*
JavaScript API) and vendor/ (that API's JSON-RPC transport), which only
toolchain identity hashing and fixture-resolved API imports read.
Per consumer:
- changed-lanes: root-test lint is boundary-free and parses config with the
repository's own API, so the copy was never read; drop it.
- write-plugin-sdk-entry-dts / write-unified-entry-dts: createFixture already
copies the same package with its platform binary since the TypeScript 7
cutover; drop the redundant overlay.
- run-tsgo-worktree, ownership --version preflight, Windows long-path
resolution: launcher-only copies (javaScriptApi: false).
- interceptor fixtures that exec a real compiler: exec the installed binary
(resolveInstalledNativeCompiler); the lint-consumption case keeps its full
fixture-local install and binary because preparation hashes it and admits
default-library reads inside the checkout.
- shard concurrency: its synthetic compiler needs no install.
Build-artifact, extension-boundary, native-declaration, prepare/check
boundary, and tsdown-config fixtures keep the full copy. Copies stay on the
filtered close-on-exec cpSync path; assertions and timeouts are unchanged.
Exclude dotted .test-utils.ts and .test-utils.tsx paths through the existing build-input owner. Preserve runtime support inputs and extend the existing build-stamp regression.
The controlled prepared test-utility-edit workflow at db793644 improved from 67.205s to 27.870s mean wall time. Current-source correctness and changed-file gates remain pending in the draft PR.
Bundled plugins only shared the host loader when their entry was compiled
JavaScript, so a source checkout captured all 87 bundled packages (copy, hash,
and dependency materialization) on every prepared model runtime publication:
79.5 s of plugin discovery per agent turn, which exceeded the 120 s budget on
a loaded host. Bundled plugins now take the shared host loader regardless of
entry extension, the edited-code warning keys on the canonical export so it
survives loader interop wrappers, and the docs describe source and compiled
bundled identity together.
Discovery for the live embedded-runner case fell from 79.5 s to 12-13 s and the
case from ~100 s to ~25 s on the same host. Editing a bundled plugin's
TypeScript source now needs a Gateway restart, matching compiled bundled code;
installed, external, workspace-path, and standalone plugins keep captured
source reload semantics.
Fix red main after #163381 changed friendly provider-error copy. Align five expectations with the existing connection and model-not-found formatting owners while preserving required-answer finalization, permanent WebSocket failure, and model-catalog lifecycle assertions. No production changes.
Proof: provider-error 19/19 and model-dispatch 3/3 on Node 24.21.0 and Bun 1.4.3; changed-file checks and git diff --check passed; P2 autoreview scoped-clean; exact-head ClawSweeper found no actionable defects.
The linked-worktree fixture copied, committed, and checked out the whole
scripts/lib directory (490 files with the top-level scripts), so its
`git add .` exceeded the 10 s spawnSync budget on loaded hosts before any
wrapper behavior ran. Commit only the wrapper's runtime import closure
(29 files), computed by collectRuntimeImportClosure, plus the two files
the CLI shim loads by path (run-tsgo.mts and tsx.mjs).
Interleaved A/B at load 46-78: git add 36.2 s -> 3.0 s median, worktree
add 16.4 s -> 6.1 s, copy 15.3 s -> 1.6 s. Wrapper status/stdout/stderr
are byte-identical between the old and new fixtures; timeouts and
assertions are unchanged.
A 2026.9.5 to 9.7 candidate Doctor died after about five minutes in "Checking data migrations" with a native stack through node::sqlite::DatabaseSync::Exec, and the recorded failure kept only an adjacent plugin warning (#163531). The memory schema storage migration called its UDF in bulk and retained every row embedding JSON in the JavaScript heap until the native call returned, which exhausts the heap on large legacy embedding caches; it now validates and converts one memory vector at a time inside the same transaction, preserving row identities, 64-bit rowids and stored text. Candidate validation now records a signal termination with its phase, fatal header and a bounded stderr tail in the update-run record and report instead of letting an unrelated warning take precedence. Thanks @fenglanhua for the stack.
Refs #163531
The Telegram userbot skill's node:test (*.test.mjs) and Python (*.test.py)
files are not Vitest-routable, so aggressive PR selection drops them as
direct targets. Their only CI owner is the Vitest wrapper
test/scripts/telegram-e2e-userbot-skill.test.ts, which the policy watch
selected for 20 named non-test scripts only. Test-only skill PRs (e.g.
#162968) and later scripts (reply-policy-*, telegram-runtime) planned
nothing in either selection mode.
Watch the skill's whole scripts/ directory, the agents/openai.yaml the
wrapper parses, and the fixture it loads by URL. The wrapper stays in the
release-only core-tooling family; it now also runs on PRs that touch the
skill, the only PRs that can break these self-contained scripts.
* test(core): split oversized subprocess consumer suites
Separate CLI lifecycle, Gateway startup, command dispatch, and bare-root
flows; media reads and storage; catalog metadata and hosted persistence.
Prepare workers during collection only for the six observed consumers.
Keep all 221 cases, assertions, and fixture initialization order; the
exit-only and catalog metadata files remain declaration-free.
Prune the two split baselines and one already-stale baseline entry.
Validation: 221 passing cases; six collection loads and two none results.
Changed-file formatting/lint, affected tsgo graphs, both line-cap ratchets,
and diff checks pass. The global changed-path typecheck remains blocked
by the inherited agents-other root budget (724/720); affected graphs pass.
The review's baseline concern was rejected against the native stale-entry
check and direct lint of the unchanged target file.
* fix(test): collect extension subprocess dependencies
Move Anthropic's real process helper acquisition to collection while
retaining vi.importActual and its mock reset behavior. Move DeepInfra
and xAI's one-time subject imports and mock setup to collection, keeping
their real HTTP transport and negative SSRF assertions intact.
Validation: all 20 cases pass and first declaration loads are collection;
all case names/counts are unchanged. Formatting and extension test types
pass. The normal extension lint lane was blocked while preparing Plugin
SDK declarations by its existing 300000 ms timeout; no timeout or guard
was changed. The final candidate received the scoped P2 review recorded
with the preceding core split commit.
* test(plugin-sdk): preload compiled subprocesses for extension tests
Move worker preparation into collection through a repo-local, non-production
SDK subpath. Let Codex app-server setup preload declarations while keeping
worker-cpu imports after file mocks; preserve per-test imports and assertions.
Register private source and declaration aliases without adding package exports
or production artifacts. Remove unused CLI fixture exports and reuse the alias
normalization owner so the existing dead-export and line-cap gates pass.
* fix(test): preload compiled subprocesses for newly screened suites
* fix(test): preload remaining screened subprocess declarations
Move compiled subprocess preparation out of test and hook deadlines in six confirmed declaration consumers. Preserve lazy imports, mock ordering, and assertions; keep the shared meeting plugin helper unchanged so platform-scoped loading retains its existing order.
* style(test): keep Parallel suite separator
* fix(test): preload compiled subprocesses for the remaining screened suites
Finish the compiled-subprocess deadline screen that #163254 left at its
direct-signal tier. Twenty more suites reached their first
compiled-subprocess declaration inside a test body, so the invocation's
worker preparation ran inside that test's deadline.
Nineteen suites hit the declaration through a production-owned lazy
import (lazy runtimes, lazy CLI command loading, lazy SDK media, secret
and schema loaders) and take the existing preload: the core module for
src suites, openclaw/plugin-sdk/compiled-subprocess-testing for
extensions. control-ui-assets moves its in-test vi.importActual of the
real exec module to collection instead.
* fix(test): preload compiled subprocesses for the Discord state migration suite
Main's #163329 rewrote this suite and retired the lazy thread-binding
import that the first commit targeted, so the merge took main's file.
A re-screen of the merged tree still recorded its first declaration load
inside the first test: migrateLegacyState now reaches it through the SDK
doctor-migration plan adapter's lazy state-migrations import. Restore the
preload; the suite loads the declaration at collection again.
Fixes#141291.
Telegram documents whose downloaded bytes are a PNG or JPEG are now treated as images, so a vision model sees an image sent as a file. PDFs and text documents stay documents.
Proof: real Telegram Test Server with real gpt-5-mini. A PNG sent as a document reached the model as 0 image parts on main (the model said it could not open it) and as 1 byte-identical image part with this change (the model described the red square and its text). A PDF sent as a document stayed a document on both. Regression tests fail on main and pass here.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Compute the "owes a completion" predicate once in retireSupersededSubagentRun
and drop the cohort array whose only remaining use was cohort.includes(entry).
Collapse the three names and repeated live lookups in
reactivateCompletedSubagentSession, keep the prepared announce result instead
of an optional callback sentinel, and give the attachments-removal policy one
exported owner next to safeRemoveAttachmentsDir, replacing four inlined copies
and a protected method. No behavior change.
* fix(codex): authorize canonical sandbox reads
* fix(sandbox): integrate canonical read authorization with current main
Preserve source-bearing reads and current filesystem owners while binding policy checks to admitted paths. Keep identity-validation failures distinct from missing paths.
Local integration checkpoint for PR #150731. Remote tests and changed checks remain pending; this commit is not landing qualification.
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
update-command-handoff cancel and cancel-output-first failed on main (exit 75 instead of 23): d8b18a62a3 moved sentinel publication into the worker, so the caller-only fault injection missed it and production correctly reported the transfer exit. The shared preload support now targets the caller and its worker while allowing helper cancellation publication. Test-support only.
Refs d8b18a62a3
Complete the fs-safe watcher migration for catalog and usage-template caches, with non-persistent subscriptions so one-shot commands exit naturally. Preserve atomic-save and missing-root recovery behavior.
Re-read selected sources after undetailed invalidations and restart the dev child only when content changes. Keep unchanged Skills coverage available, and honor CHOKIDAR_INTERVAL for forced polling and automatic fallback. Remove redundant native transports and transport-specific fixtures.
Completes #159226 and supersedes #158182. Dependency pins remain owned by main.
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix: let long Claude shell jobs release chat turns
* fix(agents): preserve native shell for node exec defaults
---------
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* refactor: split oversized agent and backup files
Move transient agent database disposal into its existing lifecycle owner
while preserving the database facade used by probe and migration callers.
Move backup catalog redaction and agent creation persistence checks to
focused test owners, preserving assertions, cleanup, and protected coverage.
Bring three files below the strict local max-lines limits without changing
GitHub Actions advisory limit policy.
* test: isolate catalog reader retention from fleet refresh
Use individual publication and the existing catalog-worker observation owner
for the agent database cleanup proof. Preserve four agents, one shared worker,
all deletion/liveness assertions, and a live survivor-reader prerequisite.
Owner tracing showed background catalog renewal closing pooled readers during
the old assertion. The focused case, targeted types/lint, formatting, and
independent P2 review pass with the final two-file fixture change.
* test: drain shared state before usage fixture teardown
Join shared-state worker cleanup after agent database retirement while each
usage fixture's environment and temporary root are still valid. Preserve all
five case bodies and preload assertions.
CI exposed stale temporary database references; the exact original shard
passed locally. The bounded cleanup change passes all five cases, targeted
types/lint, formatting, and independent P2 review.
The generated native inventory stored one line per string with every
extraction site inline, sorted alphabetically. Two PRs reusing a string
("Retry") both rewrote its line, and a feature's new strings ("Group by",
"Group chat") landed in the same insertion gap, so parallel native PRs
conflicted in apps/.i18n/native-source.json and needed a rebase plus a
full CI rerun.
Inventory v3 writes one line per extraction site, clustered by source
file, with clusters ordered by a hash of the path so new sibling files do
not share a gap. Each row's position depends only on its own content, so
independent edits merge cleanly (including GitHub's server-side merge)
and the merged text equals a fresh baseline. The new
scripts/native-i18n-inventory.ts owns serialization and parsing; the
generator, Android/Gradle and Apple readers migrate to it together and
receive the same entries in the same order as before.
Every registry-mutating CLI command (doctor, doctor --fix, plugins install, plugins registry --refresh) failed for a non-root service user with "Update history reconciliation could not complete: spawn /usr/bin/node EACCES ... free disk space/quota or set XDG_CACHE_HOME", and the same path made a 2026.9.6 to 9.7 upgrade unrecoverable (#163547). The native snapshot launcher no longer forces a redundant chdir into an inherited working directory the service user cannot enter, and the Doctor history owner no longer aborts repairs on an update-history read failure: the failure is classified by its real errno class (executable not runnable vs. disk space) and persisted as a warning in the update-run record while the mutation proceeds; unsettled process-cleanup errors still block. Thanks @ringbe-cyber for the diagnosis.
Closes#163547
update-command-doctor-delegation flaked on main hourlies (3 cases, 37020939466): source loading exhausted the fixture deadline before the standalone Doctor writer reached readiness, so the settle-after-reject assertion observed a null record. Production already awaits custody settlement; the shared compiled-fixture owner now supplies every import up front. Test-support only.
Refs #162614
Keep Bun plugin resolution on its native/Jiti and Bun.plugin path even when Module.registerHooks exists. Share one runtime predicate across all five loader decisions; Node keeps its hooks path. Preserve Bun's independently evolving require.resolve.paths capability through the existing legacy Jiti control, and document runtime ownership.
The real throwing-hook regression fails before and passes after. All 282 plugin files match old Bun exactly, historical interop passes 68/68 on all three runtimes, and candidate plugin hooks fall from 177 to zero. Old-Bun median load time is unchanged; the residual 2.84% candidate-binary cost is assigned to the fork's registerHooks landing by the maintainer. Production LOC is neutral.
P2 review is scoped-clean and exact-head CI37022559011 passes. The inherited local environment-count check remains477/476 on main; no variable or budget change is included.
Move Mention expiry and retry scheduling into an Inbox-owned scheduler scope. Fence new work when shutdown begins and join descendant work outside callbacks, preserving sibling schedules and durable Mention state.
Fix the cold-reopen fixture to await Inbox/database disposal before reusing its parent scheduler. Exact-head CI, original-code negative controls, original shard order, focused tests and the published 2026.9.7 update with authenticated public SDK reads pass on Testbox. The unrelated expired plugin-registry guard remains recorded with its owning main fixes.
The system-update custom-type constant was counted as an environment variable name; rename it so the
budget only counts real names. Raise the budget to 477 for OPENCLAW_PROMPT_CACHE_ASSERT (#163379),
the owner-approved prompt-cache assertion switch.
The awaited session-persistence extraction moved canonicalizeSessionEntry
and its existing lint directive to session-manager-persistence-entry.ts.
Update the suppression guard's exact path without adding an allowance.
JSON serialization intentionally honors custom toJSON values and omits
non-JSON data to match persisted entries; structuredClone changes that
contract and rejects valid extension payloads.
Validation: suppression guard 3x (9 tests), claim-recovery peer repair
3x (54 tests), core-test-gateway-other tsgo, lint and boundary lint,
Linux Testbox check-changed (387s), and P2 review. All 39 audited
openSessionManager calls are awaited; peer 90897637d3 already fixed
the claim-recovery consumer. Scoped single-file proof follows the
coordinator's instruction; the whole tooling suite was not rerun.
* refactor(gateway): prepare sharing management authority
Use current prepared session and profile facts for management grants, retain logical lifecycle fences alongside physical store identity, and validate fresh stored rows before disclosure or visibility decisions. Preserve existing worker and incognito owners. Prove zero caller-thread SQL for member add/list/remove and refusal of revoked or dirty authority.
* test(gateway): initialize and drain steering custody projection
259033fe97 (#163460) made advisory ClawHub inspections tokenless:
partial registry metadata cannot authorize capability consent. The test
still required an artifact-review token for every inspection response.
Cover partial and unavailable catalog surfaces while retaining rejection
of empty supplied tokens, malformed components, and incomplete declared
contracts. Production schemas and mutation consent checks are unchanged.
Validation: file 3x locally (75/75 cases); the complete gateway-protocol
package on Linux Testbox (86 files, 997 tests); scoped type-aware lint,
boundary lint, formatting, and P2 review passed. The authorized single-file
test exception replaces check-changed and the broader owning-config gate.
* fix(test): QA Lab suite check fails during summary validation
Wait for the real summary validator before reading the runner status in the
concurrent-suite fixture. Preserve the validator promise and the admission,
single-launch, and completion assertions without a separate polling deadline.
Move the existing suite-result file writer into sibling test support while
keeping temporary-directory ownership with all eight callers. Production
behavior and artifact bytes are unchanged.
* chore: incorporate main claim-recovery typecheck fix
Merge pinned main commit 90897637d3 after
PR CI encountered its already-fixed missing await in the worker claim-recovery
fixture. Preserve the reviewed QA Lab source and its original failure evidence.
The integrated dependency context passes the ordered 33-case QA Lab file,
extension test types, and the previously failing gateway-other typecheck.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* perf(gateway): attribute git subprocesses and bound the startup git burst
Two minutes after a Team Gateway start the worker-placement recovery
sweep launched ~800 git subprocesses in one minute (one `for-each-ref`
inventory per historical local checkout, even when no cleanup refs
exist), stalling the event loop for 4 s per minute, and the spawn
counter could only say `family="git"`.
Git executions now carry a bounded operation label (fixed allowlist,
`unknown` for unattributed git, `none` for other families) that the
shared spawn owner records and the Prometheus plugin exports; worker
launches keep the parent-admitted operation across batching and
retries. Startup orphan-ref cleanup runs only while the Gateway is idle,
inventories at most eight roots per full sweep, and remembers completed
roots for the startup pass, so cold-start work no longer scales with
history size while every root is still eventually cleaned.
* fix(gateway): resolve orphan-cleanup workspace roots once per startup pass
Bounded orphan-ref sweeps re-resolved every placement's workspace to
rebuild the root map before cleaning their eight roots, so a Gateway
with 50 historical placements paid the resolution twice. The startup
pass now remembers each placement's resolved root (or that it has none)
while every sweep still admits the current placements, so a sharing
session that was busy is retried against fresh session facts. Failed
resolutions stay uncached and retry on the next sweep.
Also map the optional spawn operation before sorting in the git-worker
lifecycle test.
* feat(llm-core): add Claude in-history system message capability
* improve(agents): pin the stable prompt prefix and append section updates on capable Claude routes
* improve(agents): send turn-scoped runtime context as system messages on capable Claude routes
* fix(plugins): exclude rolled-back registrations from execution scopes
* test(agents): give the live prefix-update case a fifteen-minute budget
Two real plugin-runtime builds on a loaded host exceed the six-minute case timeout; the probes themselves are unchanged.
* fix(agents): preserve dispatch freshness and provider review authority