* perf(sqlite): cache synchronous prepared statements
* fix(sqlite): refresh cached statement metadata
* fix(sqlite): bound cached statement retention
* fix(sqlite): close statement cache lifecycle gaps
* test: suppress SQLite warning in retention child
* test(sqlite): make transcript-load counter statement-cache-aware and allowlist raw test SQL
* test(sessions): type the wrapped iterate against its overloaded signature
* test: share a statement-cache-aware SQLite execution counter across prepare-count tests
* fix(pr): validate head SHA with bash regex so fork-CI runners without ripgrep pass the artifacts-init guard
---------
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
scripts/pr review artifacts carried no PR identity, so a review authored for
another PR validated clean and could gate someone else's landing. Stamp both
review.json and review.md with the reviewed PR number and head, anchor
pr-meta.json to the guarded pr-meta.env, and re-stamp foreign artifacts on init
instead of silently adopting them. review-claim now works in the PR worktree so
no subcommand writes review state to the shared canonical checkout.
* fix: reject malformed UTF-8 in live provider model catalog responses
Add { fatal: true } to TextDecoder in readLiveModelCatalogJson so
invalid UTF-8 bytes throw a TypeError before JSON.parse instead of
silently becoming U+FFFD.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(plugin-sdk): add fallback proof for malformed UTF-8 in live catalog
Adds a focused test that constructs raw bytes with an invalid 0xFE byte
inside a JSON string value and validates that buildLiveModelProviderConfig
catches the Typeerror and falls back to the static catalog rows.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(pr): classify auto-merge failures without ripgrep
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(config): compaction.enabled is rejected as invalid config
Setting agents.defaults.compaction.enabled in openclaw.json made the
whole config fail to load with "agents.defaults.compaction: Invalid
input", so auto-compaction could not be turned off.
The runtime already reads the field (SettingsManager.getCompactionEnabled
returns settings.compaction?.enabled ?? true, and setCompactionEnabled
writes it), and the documented config example in
docs/reference/session-management-compaction.md already shows
"enabled: true". Only the zod schema was missing the key, and the
compaction object is .strict(), so the unknown key rejected the config.
Adds enabled to AgentDefaultsSchema and to AgentCompactionConfig.
Closes#110065
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(config): wire compaction enablement through runtime
Align the accepted compaction.enabled contract across runtime precedence, help, labels, docs, and generated schema baselines.
Co-authored-by: Zakaria Rahali <zakariarahali288@gmail.com>
* test(config): preserve omitted compaction setting
Document the reload lifecycle and lock in project-setting precedence when the OpenClaw config key is absent.
Co-authored-by: Zakaria Rahali <zakariarahali288@gmail.com>
* refactor(config): centralize compaction runtime override
* fix(config): preserve compaction safety guards
* fix(scripts): avoid ripgrep in merge fallback
* docs(config): refresh current main baseline
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The relevant-mainline-drift check in scripts/pr merge-verify hard-failed
any landing whose prepared head predated a sibling merge, serializing all
agent landings behind a fresh CI cycle per merged PR. Required checks
still gate at the prepared head and GitHub mergeable state still blocks
real conflicts. OPENCLAW_PR_STRICT_DRIFT=1 restores the previous hard
gate for release-critical flows.
* feat(scripts): serialize pr prepare gates and add remote testbox test gate
Concurrent scripts/pr gate runs across .worktrees queued on the shared
heavy-check lock mid-test: the queued run's children hit the 10-minute
lock timeout while its unlocked build stage piled CPU load onto the
holder's vitest shards, which then stalled past the 120s no-output
watchdog and were SIGTERMed with zero real test failures (observed
landing PRs #99935/#100026 on a loaded maintainer Mac).
- scripts/pr-gates-lock.mjs holds the shared heavy-check lock for the
whole local gate block; gate stages inherit the existing *_LOCK_HELD
child contract, so concurrent gate runs now queue as whole units
before their first command.
- OPENCLAW_PR_GATES_REMOTE=testbox runs the full-suite pnpm test gate on
a Blacksmith Testbox via scripts/crabbox-wrapper.mjs (same delegation
as check:changed). The tbx_ lease id and Actions run URL from the
crabbox --timing-json report are recorded in .local/gates.env
(REMOTE_GATES_*) and .local/prep.md. Local remains the default;
pnpm build/check stay local.
Formatting verified with the primary checkout's oxfmt (hook bypassed:
linked worktree has no hydrated node_modules).
* fix(scripts): refresh the gate stamp when lease-retry gates rerun for a rebased head
The lease-retry path reran build/check/test for the rebased prep head but
left .local/gates.env describing the pre-push head, so prep.md/prep.env
attributed stale evidence (including the new remote testbox lease id) to
the pushed commit. Extract write_gates_env_stamp as the single stamp
writer, rewrite the stamp from the retry path for all modes, and re-source
gates.env in prepare_push after the push settles.
Found by autoreview (codex/gpt-5.5); formatting verified with the primary
checkout's oxfmt (hook bypassed: linked worktree has no node_modules).
* fix(scripts): harden remote PR gate evidence
* fix(scripts): serialize complete gate setup
* fix(scripts): clear stale docs gate proof
* fix(infra): stop package-root walks at node_modules boundaries
Nested git worktrees (.worktrees/<pr>, .claude/worktrees/*) have no local
node_modules, so vitest workers run with argv1 inside the enclosing
checkout's node_modules. resolveOpenClawPackageRoot* walked up past that
boundary, resolved the enclosing checkout as the openclaw package root,
and bundled plugin discovery loaded the ancestor's stale extension
manifests, failing ~12 test shards and the scripts/pr prepare-run test
gate whenever the primary checkout sat on a different branch.
A package.json above a node_modules directory belongs to the workspace
that installed the tooling, never to the package owning the running code,
so the ancestor walk now stops there. Installed layouts
(node_modules/openclaw, .bin shims, global installs) match at or below
the boundary and are unaffected.
* fix(scripts): pin bundled plugin discovery in nested PR worktree gates
scripts/pr gates run pnpm test inside .worktrees/<pr>, which resolves
vitest tooling from the primary checkout's node_modules. PR branches that
predate the openclaw-root node_modules-boundary fix would still discover
the primary checkout's stale bundled plugin manifests, so pin
OPENCLAW_BUNDLED_PLUGINS_DIR to the worktree's own extensions before the
build/check/test gates.
One-time maintainer-authorized bootstrap merge for the release-gate verifier policy. Exact hosted CI and all supporting workflow gates passed on 66133de419.
Route maintainer prepare pushes through GitHub createCommitOnBranch by default so PR repair branches do not accumulate unsigned git-protocol commits. Keeps git-protocol pushes behind an explicit override.
Fix the Windows stale-import guard regex used by the Parallels npm update smoke path, with related maintainer-flow and regression-test cleanup preserved on a verified branch.
The hardcoded `OPENCLAW_VITEST_MAX_WORKERS=4` default in gates.sh
short-circuits the host-aware scheduling introduced in c247e366.
`resolveLocalVitestScheduling` sees the explicit override and returns
maxWorkers=4, which falls below the >= 5 threshold required by
`shouldUseLargeLocalFullSuiteProfile`, so every machine—regardless of
resources—gets the DEFAULT profile (4 shard parallelism) instead of
the LARGE profile (10 shard parallelism).
Drop the hardcoded default so `test-projects.mjs` can detect actual
host resources and pick the appropriate profile automatically. When
the user explicitly sets OPENCLAW_VITEST_MAX_WORKERS, forward it as
before.