Align Telegram artifact reuse and packaged Docker validation with current GitHub Actions and runtime state contracts. Refresh affected regression fixtures and isolate test state.
* 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.