Commit graph

445 commits

Author SHA1 Message Date
Peter Steinberger
46ab36a493
improve(anthropic): append system prompt updates and runtime context in history on Claude routes (#163461)
* 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
2026-10-02 08:01:42 -07:00
Peter Steinberger
ba811fafc1 fix(scripts): pin the session-store runtime imports in the request wrapper inventory
The wrapper now reaches supported-session-store, channel-route, delivery-context.shared, and the message-channel helpers at runtime; the closure tests reported them missing on main.
2026-10-02 07:17:31 -07:00
Peter Steinberger
82a4cfbe57
feat(plugin-sdk): awaited session persistence; deprecate sync transcript writes (#163264)
* feat(plugin-sdk): await session persistence and deprecate sync writes

* test(sessions): fix awaited persistence fixture types

* fix(sessions): preserve binding and delivery publication

* test(sessions): isolate compaction retarget authority

Model the retarget as an independent operation so the fixture reaches post-commit publication validation. Keep the committed receipt, accounting, and replacement-transcript assertions intact.

* fix(ci): remove duplicate database-worker test routing

Main already routes attempt-phase-lifecycle.test.ts through the database-worker owner. Remove the duplicate introduced by the SDK branch. Exact-head preflight and the native local manifest both reproduced the failure; the corrected manifest passes with 69 selected Node rows. Unique test coverage and the duplicate guard stay intact. Formatting and P2 review pass.

* fix(sessions): keep maintenance projections with the host owner

Return committed projection-rebuild facts from maintenance workers and schedule them through the existing host owner. Preserve custody, rollback, and synchronous compatibility. Update async fixtures and host-broker test routing, restore the native wrapper import inventory, and route memory visibility declarations through their existing producer.

Focused Linux proof passed342 tests across17 suites; old-code controls fail at pending projections. SDK declarations retain legacy signatures with four additive exports. Types, lint, T1, Madge, focused routing checks, and P2 review pass.

* test(cli): await blocked-run hook entry without polling

Await the existing hook-entry gate instead of racing awaited transcript persistence against vi.waitFor's one-second default. Preserve the early-settlement failure and the assertion that agent_end must finish before the CLI run settles.

The two focused cases pass in 155.98s including preparation; their test bodies take 3.656s and 1.804s. Fresh P2 review is clean.

* test(cli): use the deferred helper default type

* test(gateway): keep worktree fixture on the shared state root

Use the nested fixture only for workspace and device files. Activating its environment switches process state roots underneath the shared Gateway, whose projection retains its startup environment. Preserve the registry witness guard and every cwd, transcript, initial-run, and follow-up assertion.

CI observed AgentDatabaseRegistryChangedError during creation. The exact callback interleaving was not captured, and unmodified main passed the whole file in 172.229s; that is non-reproduction, not inherited-failure qualification. The corrected fixture passes all 10 cases in original order in 164.077s. Semantic lint, formatting, and fresh P2 review pass.

* refactor(sessions): separate hydration types and CLI hook fixtures

Keep transcript hydration results beside their request contracts and retain aggregate exports. Move the CLI hook fixture owner into test support without changing coverage. This removes both line-cap increases after main integration; 112 composition tests and all 52 reliability tests pass.
2026-10-02 07:03:11 -07:00
Peter Steinberger
cee0906f38
improve(agents): explain unknown tool outcomes and assert append-only request history (#163379)
* fix(agents): describe unrecorded tool results as unknown outcomes

Use shared unknown-outcome guidance while preserving the Responses-family aborted convention. Retain synthetic provenance in model context so late real results can replace repair placeholders without changing existing detection or stored transcript rows.

* improve(agents): assert provider request history stays append-only

Track converted message prefixes and record declared compaction, pruning, runtime-context, and image rewrites. Notify every cache-affinity baseline for the same session identity. Memoize message/content and schema fingerprints, with strict assertions enabled only by an opt-in environment flag.

* fix(agents): pin the shared tool-result text for the request wrapper

Include packages/llm-core/src/types.ts in the PR wrapper's extracted source inventory. Main commit 93625aa3d1 pulled tool-result-pairing.ts into that graph, so its existing shared tool-result text import must be included for standalone wrapper execution.
2026-10-02 07:50:31 -05:00
Peter Steinberger
f40ee2069f
feat(state): incognito actor report and outbox adapters (P4a, inactive) (#163494)
* feat(state): add inactive incognito report and outbox adapters

Bind transcript reports and closed-turn outbox commands to the retained incognito actor connection and shared FIFO publication owner. Keep production routing host-owned until P7 and preserve durable outbox semantics.

* fix(tooling): retain incognito transcript wrapper dependency
2026-10-02 07:42:42 -05:00
Peter Steinberger
bb40f2c70b
chore(deps): update fs-safe to 0.23.0 (#163408)
* chore(deps): update fs-safe to 0.23.0

* fix(fs-safe): complete migration tooling metadata
2026-10-02 05:14:28 -07:00
Peter Steinberger
7fbcd48629 fix(scripts): guard empty merge capture arrays under Bash 3.2
scripts/pr merge-recover --cancel-auto aborted with 'prior_names[@]: unbound variable' when the retained outcome held no prior merge captures: the wrapper re-execs /bin/bash 3.2 on macOS, where set -u rejects an empty array expansion, so the cancellation returned before retiring the auto-merge request. Use the ${arr[@]+"${arr[@]}"} idiom for the prior and supplied capture arrays. test/scripts/pr-merge-outcome.test.ts: 76 passed.
2026-10-02 04:37:03 -07:00
Vincent Koc
df93a28f0b
fix(pr): recover stale admin intents on replacement heads (#163429) 2026-10-02 11:16:15 +00:00
Peter Steinberger
93625aa3d1
refactor(models): prepare persisted catalogs off the Gateway thread (#163425)
* refactor(models): prepare persisted catalogs off the Gateway thread

* fix(tooling): retain catalog worker imports in PR wrapper

Include the catalog read operation and its runtime import closure in trusted wrapper extraction. The existing wrapper closure checks reproduce the missing modules and pass with the repaired inventory.
2026-10-02 03:33:45 -07:00
Peter Steinberger
6785b4d612
refactor(config): move legacy agent roster reads into Doctor (#162612)
* refactor(config): move legacy roster ownership into Doctor

* test(doctor): isolate sandbox egress fixture from roster migration

* fix(update): explain recovery for included legacy rosters

* refactor(doctor): isolate roster migration owner preparation

* test(config): use canonical ownership in touched model fixture

* test(config): retain ownership literals in migration fixtures

* chore(doctor): attach roster cast invariant to its assertion

* docs(doctor): clarify Copilot config repair ownership

* chore(config): shrink roster assertion budgets

* fix(config): preserve roster key order across repeated writes

* test(doctor): check migration owner fixture config type

* test(config): check retained owner fixture types

* refactor(config): share authored roster cleanup sequence

* test(sessions): check transcript owner config fixture

* fix(config): finish canonical roster producer cutover

* refactor(cron): consume canonical roster ownership

* fix(config): complete canonical roster validation

* fix(config): preserve canonical roster ownership boundaries

* test(cron): bind shutdown fixture to live default owner
2026-10-02 03:01:52 -07:00
Vincent Koc
295a324d1a
fix: use file payloads for native GitHub operations (#163279)
* fix: use file payloads for native GitHub operations

* fix: preserve native GitHub failure capture bytes

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-10-02 14:38:15 +07:00
Peter Steinberger
8f364a7e80
fix(update): settle Doctor writers before recovering migrated Gateways (#162614)
Doctor left its child writers (spawn-broker process groups) without durable custody, so an update that found an unsettled writer could neither prove settlement nor safely start the migrated candidate, and an operator could be left with a down Gateway. The update command owner now reserves custody before spawning, binds native process identity before admitting input, retains its inventory through Doctor death, and admits migrated-candidate Gateway recovery only after proven writer settlement; unverified writers keep the data-at-risk refusal with PID guidance. Recovery snapshot capture drains SQLite writers first so a refused candidate start still rolls back. The immutable 2026.9.5 parent limitation is documented.

Closes #162055
2026-10-02 00:32:37 -07:00
Chris Eckert
40d284f9a6
fix(agents): release model and auth readers when deleting agents (#159013)
* fix: release deleted agents' model and auth resources

* fix: await only existing deleted-agent builds

* fix: close deleted agents' native memory managers

* fix(agents): close deleted database readers across worker isolates

* fix(agents): revive deleted stores by their captured owner

* refactor(state): remove superseded reader-close entry points

* fix(agents): preserve commit outcomes and close readers before trash

* fix(tooling): include agent readers in native wrapper inventory

* fix(agents): adapt deleted-reader cleanup to native worker owners

* fix(agents): preserve deletion fences across worker generations

* fix(agents): release deletion guards and repair CI proof

Release worker heartbeat references when a deletion lease closes. Keep the
journal authority SELECT in its worker-only module and route the catalog
reader fixture through the existing database-worker lane.

Close the survivor fixture's seed writer before recovery, establish archive
LRU order, and restore the shared logger mock's trace contract. Add effect
boundary coverage for revoked deletion authority and move bounded transport,
channel logging, and fixture code to their existing modules.

Preserves the agent deletion and recreation repair for #159007.

Co-authored-by: Chris Eckert <christopher.k.eckert@gmail.com>

* test(ci): retain native command and auth retirement diagnostics

Wait for a native command receipt before checking its result so a terminal
failure exposes its reason immediately. Include isolated Gateway logs in the
removed-profile assertion, with a debug-only publication retirement summary
that identifies cache, owner, pending-build, and Gateway-loan state.

This diagnoses UI and auth failures from CI run 36965599681 without relaxing
assertions, extending timeouts, or changing retirement/recovery authority.

Co-authored-by: Chris Eckert <christopher.k.eckert@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Chris Eckert <christopher.k.eckert@gmail.com>
2026-10-02 02:30:07 -05:00
Peter Steinberger
3224ed9341
refactor(plugins): retire npm declaration stubs (#163231)
* refactor(plugins): retire obsolete npm declaration stubs

* fix(tooling): remove retired npm stub from trusted inventory
2026-10-02 00:25:12 -07:00
wangmiao0668000666
970faff428
fix(channels): surface a channel doctor artifact's own load failure (#162645)
* fix(channels): surface a channel doctor artifact's own load failure

* fix(channels): ship the optional artifact loader in the PR wrapper inventory

doctor-contract-api.ts now imports ./optional-public-artifact.js, so the
trusted-anchor PR wrapper extraction must include it; the eager import
closure test failed with an unresolved relative specifier in the extracted
dependency context.

Co-authored-by: wangmiao0668000666 <wangmiao0668000666@users.noreply.github.com>
Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>
2026-10-02 11:51:23 +07:00
Dallin Romney
a4ad0b67b1
fix(update): avoid copying busy databases just to check ownership (#162268)
* fix(update): inspect live state ownership without copying the database

* fix(update): retain private ownership reads during offline maintenance

* test(update): run POSIX swap case on POSIX

* refactor(state): own ownership inspection worker

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-10-02 12:42:35 +08:00
Vincent Koc
2e705107ff
fix(crabbox): start remote checks from code-only worktrees (#163035)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-10-02 12:07:18 +08:00
Peter Steinberger
70ca83470f
fix(storage): join WAL maintenance before database retirement (#162166)
* fix(storage): join WAL maintenance before database retirement

* refactor(storage): keep WAL retirement in its close owners

* chore(storage): shrink the WAL assertion allowance

* test: join WAL maintenance fixture callbacks

* test(sqlite): exercise scoped WAL dispatch in lifecycle fixtures

* test(sqlite): initialize the native fixture source loader

* test(sqlite): share the compiled WAL scheduler with native fixtures

* test(sqlite): join fixture databases before removing their files
2026-10-02 02:50:33 +00:00
Markus Hartung
13ed30a660
fix(ai): raise HTTP continuation idle TTL to a fixed 90 minutes, bound the cache (#128848)
* fix(ai): rebuild onto main after #134425's tool-call-ID-shape merge

Main moved again since the last push -- #134425 (non-canonical
tool-call-ID handling) merged directly into openai-responses-continuation.ts
and its test file, conflicting with this PR's default/cache-bound changes
in the same functions. Reconstructed via GitHub's own PR diff applied
fresh onto current main; hand-merged the three real conflicts (the
90-minute default + capacity/byte-bound eviction logic around Patrick's
new dispatchedPreviousResponseId/recordResponsesContinuationState call
shape in claimOpenAIResponsesHttpContinuation, and the matching test
additions).

Split the growing continuation.test.ts (now over the 700-line ratchet
after merging both PRs' additions) into a new sibling
openai-responses-continuation.cache-bounds.test.ts carrying the
capacity/byte-budget/eviction-order/reclaim-race tests -- new max-lines
suppressions aren't allowed, and this group was already a coherent,
separable unit.

No functional changes to this PR's own default-TTL/cache-bound logic.
Full targeted suite green (73 files, 1205 tests); oxfmt/oxlint clean;
max-lines ratchet and config-doc baseline verified.

* refactor(ai): simplify bounded continuation ownership and strengthen proof

* fix(plugins): queue compatibility removals pending reader migration

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-10-01 19:10:00 -07:00
Peter Steinberger
4809de9b6a
fix(update): make global-install failures actionable and retry stale dependency caches (#163039)
Update failure reports with reason global-install-failed showed only "[redacted-command]: exit 1": the step name was redacted together with the command and no package-manager error class survived (#163005). The step-completion owner now classifies the package-manager error once into a closed code set with the offending package spec, the report keeps the step name while the command stays redacted, failure text states the next step, and the staging owner retries a dependency-only ETARGET/E404/EINTEGRITY once with a cache refresh (npm --prefer-online, Bun --no-cache; never for the openclaw target), which is the stale-packument cause behind #162977.

Refs #163005 #162977
2026-10-01 18:04:12 -07:00
Peter Steinberger
461a995b8c
refactor(doctor): drop pre-July-2026 config migrations
## What Problem This Solves

Doctor still carries migrations for config formats last written before the July 2026 support window.

## User Impact

Upgrades from pre-July-2026 versions are no longer migrated for retired whole-agent runtime/embedded settings, sandbox `perSession`, prompt overrides, direct silent replies, custom memory index paths, queue aliases, parent-fork limits, Browser relay/SSRF aliases, Gateway WebChat config, and authored `plugins.installs`.

Doctor preserves these inputs and directs the operator through OpenClaw 2026.9.5 with `openclaw doctor --fix` before upgrading again. Config written by July-or-later shipped releases remains supported, including June extended-stable releases published after July 1.

## Why This Change Was Made

Removes the old migration steps, detectors, config-install import/receipt lifecycle, whole-agent route readers, obsolete tests, and exact inventory entries. The whole-agent cutover also removes a duplicate config rewrite pass used only to predict whether old pins would be cleared. Doctor remains the single migration owner; its existing unsupported-input guard protects preflight, backup planning, and the locked config write.

Current provider/model runtime policies, transient plugin install carriers, canonical SQLite install records/provenance, roster/ownership conversion, streaming/channel migrations, and migrations with uncertain writer history remain. No SQLite schema/version steps or public plugin SDK APIs change. `CHANGELOG.md` stays release-owned.

Writer history was checked against real persistence code and strict shipped schemas, including `v2026.7.1-beta.1` (published July 2 UTC) and `v2026.6.35` (September extended-stable):

| Retired source | Writer cutover | Last producing release |
| --- | --- | --- |
| Browser relay bind / SSRF alias | `476d948732` March 15 / `c7a947dc0a` April 4 | `v2026.3.13-1` / `v2026.4.2` |
| Authored plugin install records | `888448facc` April 25 | `v2026.4.24` |
| Parent-fork limit / queue aliases | `10b89a3b55` May 2 / `70df2b8fe2` May 13 | `v2026.4.30-beta.1` / `v2026.5.12` |
| Direct silent-reply/rewrite | `f0ceb3c5aa` May 15 | `v2026.5.14-beta.2` |
| Whole-agent runtime / embedded settings | `bb46b79d3c` May 27 | `v2026.5.27` |
| System prompt override / Gateway WebChat | `e12a6d6a67` May 29 / `d1b514af2e` May 31 | `v2026.5.28-alpha.1` / `v2026.5.31-alpha.1` |
| Custom memory index path | `f324f7e281` June 19 | `v2026.6.9-alpha.6` |

The local census records per-item source locations, release dates, DELETE/KEEP decisions, retained uncertainty, and full-read coverage for the migration owners.

## Evidence

- Both import-cycle checks: **0** on the exact candidate tree.
- Focused Doctor/config owner suites exercised migration, registry/provenance, backup/refusal, include write authority, runtime routes, and wrapper extraction. The first run found two leftover pre-window fixture expectations; those were removed. An earlier three-file rerun passed **86 tests** with one worker in **73.57 s wall**.
- Test execution times in that rerun: legacy config migrations 4.277 s; plugin registry 4.560 s; existing workspace persistence suite 38.696 s. The latter exercises real config backups, workspace/cron ownership and idempotence; the new refusal and July-shape assertions reuse its existing fixture lifecycle.
- Oldest July config fixture migrates, persists canonical agent entries, and stays unchanged on a second Doctor pass. Unsupported settings preserve authored bytes, backups, and canonical install records, including late root/include changes.
- Full `node scripts/check-changed.mjs` **passed** on final head `9ca6bc214e`, including lint, typechecks, dead-export scans and architecture guards. The full remote proof command completed successfully in 26m06s.
- Independent review completed. One backup-recovery finding was rejected: the cited function already throws for retired formats before either recovery fallback; the real preflight test proves active config and backup preservation.
- Net reduction: **1,136 production lines**, **947 test/support lines**, plus 9 docs/tooling lines. Runtime tests and full changed-file checks ran remotely; one local frozen install refreshed landing-tooling dependencies. After the last docs-only conflict, coordinator timeouts exceeded ten minutes, so cycle/docs checks used the authorized serial local fallback at nice 15.

Conflict recovery preserved main's session-entry-state repair (#162595). The later CI-planner inventory failure was fixed by the coordinator in #163071; that fix is included in the final base, with no duplicate inventory change in this PR.

Final correction head `9ca6bc214e` has both cycle checks at zero and **37 passing tests across four focused files**, including the real CLI exec-approval migration, include persistence, July upgrade fixture, and planner inventory. Full `check-changed` passed on that exact committed tree.

### Fixes found along the way

- Keep queue-refusal paths typed as strings rather than inferring unknown tuple keys.
- Keep the existing browser include/rotation regression on the supported July `browser.color` migration trigger.
- Remove the pre-July custom memory-index path from the retained real-CLI approval-import regression; its durable approval and memory-merge assertions stay intact.

The final rebase to `5d93ba471bb` resolved only duplicate wording of the July cutoff already landed on main. It keeps main’s wording; `git range-diff` confirms the production/test patch is unchanged. Both cycle checks remain **0**, docs link audit checked **14,738 links with 0 broken**, and `git diff --check` passed. Prior-head full CI run [36943104907](https://github.com/openclaw/openclaw/actions/runs/36943104907) passed; the final head is awaiting its own hosted gate.
2026-10-02 00:45:32 +00:00
Peter Steinberger
9137cfcc5f
perf(ci): run qualified unit tests with native Bun (#159988)
* perf(ci): run qualified unit tests with native Bun

* test(ci): keep a V8-only cache warm fixture

* fix(ci): include shared timeout in PR wrapper inventory

* perf(test): skip Bun bytecode cache during test teardown

* test: handle worker fixture retirement notifications

Handle rejected observer returns without delaying retirement, matching the
worker pool contract, and avoid shadowing the lane fixture input helper.

* perf(ci): qualify and tune Bun test workers

Complete SQLite admission before Bun Vitest threads start and retain each
worker generation's canonical cleanup decision in lifecycle fixtures.
Keep proxy-agent fixture values out of Bun's native fetch cache and compare
large socket payloads with full byte equality.

Renew the 292-file native qualification from paired 2,518-case proof.
Apply the existing UI JIT and allocator settings to ordinary unit-fast
Bun/Vitest selections and their cache warmer, preserving Node and native
Bun settings and dual-runtime release coverage.

Proof: 208 routing/warming cases; 61 lifecycle cases on each runtime;
66 ordered proxy/fetch cases plus the canonical 11-case proxy owner on each
runtime; independent P0-P2 review. The changed-file gate was interrupted
by the local disk reserve guard after core typing and 14 core-test type
shards passed. Tuned full-cohort performance remains to be measured;
the completed untuned comparison was 4.60% slower than Node.

* perf(test): expand native Bun coverage and reduce artifact IO

* perf(test): yield between artifact verification batches

* test: qualify native Bun cases after runtime integration

* test: refresh native Bun qualification after main integration
2026-10-01 17:28:11 -07:00
Peter Steinberger
aa9fcc5cea
fix(models): preserve explicit providers when aliases collide (#162973)
When a model alias collided across providers, explicit provider/model selections were rewritten to the colliding provider, so operators could not route explicit picks such as openai/gpt-6.1-sol on 2026.9.7. Shared alias preparation now owns the collision decision and preserves an explicit registered or configured provider; indexed and configured-primary resolution both consume it. Credited replacement for #162621 (thanks @RXQ6).

Refs #162621
2026-10-01 16:39:22 -07:00
Peter Steinberger
545f961614
fix(config): preserve shorthand model primaries in path writes (#162974)
config set and the chat config setters dropped a shorthand model primary when writing a model path, so operators lost their primary model after an unrelated config write. Path writes now preserve recognized shorthand primaries through one shared normalization helper (the same preservation models set already used); explicit primary and whole-model writes keep replacement semantics. Credited replacement for #162478.

Refs #162478
2026-10-01 15:12:09 -07:00
Peter Steinberger
5cdd8fe320
refactor(gateway): register worker-environment operations (#162522)
* refactor(state): register worker operations once per domain

Infer shared-state worker command contracts from lazy per-domain handler tables. Migrate Web Push, APNs, worktree registry operations, and fleet registry while preserving the existing broker and transaction owners.

* refactor(gateway): register worker-environment operations

Derive 54 shared-state operations from domain handler tables and load each domain through the existing typed registry. Remove duplicated guards, contracts, and dispatch branches while preserving transaction admission, receipts, and worker execution.

Internal plumbing only: no user-visible, schema, stored-state, or update behavior changes.

* fix(gateway): separate registry worker type dependencies

Keep shared records and receipts in leaf type modules and derived worker contracts downstream. Separate native reservation and lease helpers from host acquisition and maintenance imports without changing admission, transactions, or stored state.

Validated architecture and type import cycles, 550 focused tests, core types, lint, worker ratchet, and P2 autoreview. The combined registry lane remains net-negative in production lines.

* fix(tooling): extract moved workspace journal guards

The worker registry cutover moved the runtime journal guards into their
leaf types module. Point the trusted wrapper inventory at that owner so
extracted wrapper leases and cold worktree provisioners can import it.

CI run 36842397524 exposed this in eager-import-closure and worktree
provisioning. The focused local run passed all 17 eager-import cases and
15 provisioning cases; one Linux-only case was skipped. The additional
macOS cold/warm sparse composition timed out at its existing 120s limit
(145.38s observed), so accelerated composition proof remains incomplete.
No assertions, timeouts, or test scenarios changed. Scoped autoreview
through P2 found no actionable findings.

Refs #162522

* fix(gateway): name workspace reservation query export

Use workspaceReservationQuery at the native kernel and its callers so the export-name collision guard passes without an exception.

Validated focused domain tests, Madge, worker ratchet, core types, lint, and P2 autoreview. Retain the local macOS composition timeout investigation in the PR; no timeout or assertion changes.
2026-10-01 14:51:55 -07:00
Vincent Koc
32dc6c861d
fix(ci): cap Testbox concurrency and idle spend (#162678)
* fix(ci): cap Testbox concurrency and idle spend

* test(ci): align workflow guards with Testbox admission

* fix(ci): declare optional Testbox admission inputs

* fix(ci): narrow Testbox CLI rejection errors

* test(ci): verify admitted Testbox workflow behavior

* fix(ci): reserve large Testboxes for memory-heavy proof

* fix(ci): default routine Testboxes to one hour

* docs(ci): clarify Testbox profiles and total job deadlines

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-10-02 02:16:05 +07:00
Peter Steinberger
4e4e315729
perf(gateway): reduce session publication allocations and repeated redaction scans (#162810)
Reduce repeated session-publication allocations and redaction prefilter scans at their lifecycle owners, preserving live recipient authority and byte-identical redaction.

Validated with Node 24 and fork Bun tests, authority negative controls, fixture differential checks, pinned AWS kernel and three-round load benchmarks, a clean post-rebase spot quartet, and green exact-head CI.
2026-10-01 17:24:35 +00:00
Peter Steinberger
d188233947
fix(talk): preserve inherited realtime settings on upgrade (#162644)
* fix(talk): persist inherited realtime settings in Doctor

* fix(talk): normalize inherited realtime input without assertions

* fix(tooling): include Talk normalizer in trusted wrapper sources
2026-10-01 16:58:58 +00:00
Peter Steinberger
6dbca39af1
fix(text): keep grapheme lookups on cluster boundaries under Bun (#162749)
Fix Bun message chunking and terminal truncation selecting the preceding grapheme when JSC containing() probes an emoji high surrogate. Route all seven lookups through normalization-core, normalize numeric indexes before the offset, and retain the new eager dependency in the native PR wrapper inventory. Upstream engine fix: oven-sh/WebKit#753.

Node 24 and fork Bun each pass 586 tests (one skipped) across the requested 39 files. Node matches native containing() for all 1,236 corpus lookups. Changed-file checks, import-cycle validation, wrapper closure checks, and independent P2 reviews pass.

The remaining CI cron copy-fault and Discord skills-watcher teardown failures reproduce on clean main and use the authorized native pre-existing-failure exception. The original wrapper inventory regression was fixed.
2026-10-01 09:24:26 -07:00
Jason (Json)
9a0146355c
fix: share unchanged SQLite pages across update recovery files (#162466)
* fix: share unchanged SQLite pages across update recovery files

* fix(update): include SQLite copy owner in PR wrapper

* test(sqlite): inject native copy inspection failures

* fix(sqlite): retain exact copied file identities

* fix(update): preserve online acquisition for active WAL snapshots
2026-10-01 06:35:57 -06:00
Peter Steinberger
72a976e273
fix(windows): recognize gateways with literal native arguments (#160680)
* fix(windows): recognize gateways with literal native arguments

* test(windows): keep native fixture callback void

* fix(windows): complete native process inspection boundaries

* test(windows): keep native process proof in its owning suite

* fix(windows): preserve updater arguments in native census

* test: inventory captured keyboard shortcut intrinsics
2026-10-01 03:07:34 -07:00
Peter Steinberger
37ffe3ce94
feat: back up to external disks and Cloudflare R2 with storage locations (#161913)
Adds named storage locations as a generic, pluggable capability, with backup as its first consumer.

- Core storage owner (src/storage): storage.locations config, a location marker that binds identity (runtime never creates it, so unplugged disks and different disks at the same path are refused), client-side streaming encryption (scrypt key from a SecretRef passphrase, per-object HKDF keys, AES-256-GCM segments), and a built-in filesystem provider for external disks and mounts.
- Plugin SDK: api.registerStorageProvider plus manifest contracts.storageProviders; providers move opaque bytes only.
- Bundled cloudflare plugin: an r2 provider over the S3 API with conditional writes and bounded multipart uploads; auto-enabled when a location uses provider "r2".
- Backups: backup create --to <location> with verified archives, UTC retention, list/verify/restore --from, Gateway-owned offsite schedules (installed Git schedules unchanged), per-installation namespace claims fenced at publication and deletion, backup record for external jobs, backup.status RPC, Doctor/status hints, and a Systems page Backups section.

No config or state migration; the storage section is new and optional. Proof: live R2 and mounted-disk round trips, namespace takeover trace, and a published 2026.9.7 upgrade cell with an existing Git backup schedule.
2026-10-01 02:05:44 -07:00
Peter Steinberger
a3e4005ebc
fix(gateway): keep model metadata available during plugin drains (#162301)
* fix(gateway): keep model metadata available during plugin drains

Keep the active model publication readable while admitted plugin work settles,
then retire it before resource replacement. Preserve execution fencing, auth
revocation, decision cancellation, rollback, and cleanup ownership.

Retain an automatic drain failure only while its original plugin configuration
delta remains unresolved. Allow explicit wait recovery and reversion alongside
changes to a different plugin without retrying unrelated failed work.

Validate on Blacksmith Testbox with real Gateway reader latency proof, 378
focused tests, 145 follow-up tests, negative controls, types, lint, and guards.

* fix(plugins): fence admission while preserving owned cleanup

* test(gateway): preserve plugin record helpers in reload fixture

* test: repair reload mocks and supervised process joins

* test(models): preserve queue receiver in drain observer
2026-10-01 08:38:43 +00:00
Peter Steinberger
d6a09202b1
refactor(config): migrate bare sender policy keys in Doctor (#162427)
* refactor(config): migrate sender policy keys before runtime

* refactor(doctor): keep config analysis helpers private

* chore(config): lower sender policy environment budget

* fix(tooling): include sender migration in wrapper sources
2026-10-01 08:33:50 +00:00
Peter Steinberger
2e5f998331
fix(doctor): retain migrations written by supported releases (#162430)
* fix(doctor): retain migrations for supported config formats

* fix(doctor): retain the typed sandbox scope for reporting

* fix(doctor): include agent policy in wrapper extraction
2026-10-01 01:18:36 -07:00
Abi X Renhart
f8900ae844
fix: session lists stall while the gateway republishes an unchanged config (#155300)
* fix(config): stop a republished snapshot from invalidating session rows

publishRuntimeConfigSnapshot emitted an unconditional all/config session change,
so a reload that resolves to the values already published still invalidated every
projected session row, moved the projection epoch, and started a drain the next
reload abandoned. A watcher that rewrites the same config every few minutes holds
readers on a projection that cannot converge, and concurrent sessions.list calls
join the same pending promise and land together.

Compare the snapshot consumers actually read, plus its authored source, so only a
publication that is not a change reaches subscribers.

* fix(config): guard only the session change, not the publication

Keep every side effect of a runtime config publication and skip the emit alone
when the snapshot resolves to the one already published, so a republishing
watcher no longer invalidates every projected session row.

* refactor(config): move snapshot comparison into its own module

The line-cap ratchet rejected src/config/runtime-snapshot.ts growing from 700 to 703 counted lines, and that file already sits at its cap. Move the byte-stable serializer and the snapshot comparison into runtime-config-snapshot-match.ts so the guard in the publish path costs no growth.

* fix(config): keep invalidating same-object config publications

A same-object publication can follow an in-place edit or a source-only
provenance copy, so identity equality must not withhold the session change.
Only a distinct object that compares equivalent is withheld.

* chore(config): drop an unrelated send.ts assertion-baseline entry

This branch does not touch src/gateway/server-methods/send.ts, and main
carries no baseline entry for it, so the allowance only widened the safety
baseline. Removing it keeps the change to a shrink.

* test(config): pin each boundary the republish guard decides

The guard withholds the session change only for a distinct snapshot whose values and resolution provenance both match the published one. Add a table of cases at the config owner that republishes after the same first publication: a distinct equivalent object is withheld, the published object republished without an edit invalidates, and equal bytes whose provenance changed or was dropped invalidate. Extend the projected-row test so equal bytes with changed provenance and a source-only republish both dirty rows and drain back to clean.

Each boundary is pinned by its own cases: removing the guard fails the two withheld cases, ignoring provenance fails the two provenance cases, and withholding same-object publications fails the same-object and source-only cases.

* fix(config): withhold a source-only republish that changes no row input

A value-identical config.apply only restamps the file's meta, so the gateway takes its effective-config-unchanged branch: the runtime object stays and only its source advances through setRuntimeConfigSourceSnapshotIfCurrent. That republishes the same object, which the guard always invalidates, so every projected session row was still rebuilt on each such apply.

Session rows read only the runtime object, never the source snapshot. A source-only republish can change them only through an in-place edit of the runtime object since its last publication, or through the resolution facts copied onto it. The setter now checks both, comparing the object's hash with the fingerprint recorded at its last publication and the serialized facts before and after the copy, and withholds the session change only when neither moved. Every other same-object publication still invalidates.

The config-owner case advances the source three times: a meta-only rewrite is withheld, while changed provenance and an in-place edit each invalidate. Each of those checks fails when its half of the condition is removed. The projected-row case drives the secrets source-advance path that config.apply takes and fails on the previous head with all four rows dirty.

* docs(gateway): record the source-only republish exception to broad refresh

The session row projection guide says same-object config publications retain broad refresh behavior. The config owner now withholds the session change for one same-object case, a source-only republish that neither follows an in-place edit nor changes resolution provenance, so state that exception and its exact preconditions next to the rule it narrows.

* fix(config): compare a republish against the recorded publication

The guard withheld the session change for a distinct object that configSnapshotsMatch found equal to the previous snapshot. That compared the live previous object, so publishing a mutable config, editing a session-row field such as the default model on it in place, and then publishing a distinct object carrying the edited values matched the already-edited object and emitted nothing, leaving rows built from the earlier publication.

Record the serialized resolution facts at each publication, beside the value fingerprint the metadata already keeps, and withhold only a distinct object whose fingerprint and facts equal that record. The source-only path compares the newer source's facts with the same record, so a provenance change made in place on the published object also refreshes rows.

Tests: two owner table rows (a distinct object matching values, or provenance, changed in place on the published one invalidates), a provenance-changed-in-place step in the source-only case, and a projected-row case for the reviewer's exact sequence, which fails on the previous head with no row dirtied.

* docs(gateway): describe config refresh as validated against the publication record

The guide listed the source-only republish as an exception to broad refresh. It is the same check made a different way: the rule exists to catch an in-place edit or changed provenance, which object identity cannot see and the recorded fingerprint and resolution facts can. State the rule in those terms.

* test(gateway): drop duplicate setRuntimeConfigSnapshot import after main merge

Main now imports setRuntimeConfigSnapshot in the grouped runtime-snapshot import, so the standalone import this branch added became a duplicate identifier (oxlint, tsgo, oxfmt and the line-cap ratchet all failed on it).

* fix(config): classify publication scope from the recorded snapshot

The main merge replaced the unconditional `config` session change with
runtimeSessionChangeScope, which classifies against the live previous object.
When that object was edited in place after it was published, the scope came
back presentation-only, so projected rows built from the pre-edit values were
left stale.

Fall back to the full `config` scope whenever the recorded publication
fingerprint no longer matches the live object, and only otherwise ask
runtimeSessionChangeScope. This restores the PR's separate-object contract for
a config that matches an in-place edit of the published one, while keeping the
narrower presentation and profile scopes for genuine changes.

* fix(config): include resolution provenance in previous-publication drift

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-01 15:54:27 +08:00
Peter Steinberger
867a82ce61
refactor(config): migrate retired context and Copilot keys in Doctor (#162184)
* refactor(config): move runtime legacy normalization into Doctor

* test(doctor): update migration callers and source inventory

* test(doctor): isolate context-budget migration coverage

* test(doctor): assert implicit primary preservation

* test(doctor): align warning fixtures with migration ownership
2026-09-30 23:51:06 -07:00
Vincent Koc
dab8c1513d
fix(pr): reclaim finished materialized wrapper copies (#162340)
* fix(pr): reclaim finished materialized wrapper copies

* test(pr): check materialized anchors before supervised cleanup
2026-10-01 05:17:24 +00:00
Peter Steinberger
6337d159e3
build: generate Kysely declarations at build time (#162288)
* build: generate Kysely declarations at build time

Prepare ignored type-only schema projections through existing install, build, compiler, test, SDK API, and package-boundary entrypoints. Preserve existing import paths and generated bytes, cache unchanged inputs, and cover unbundled SDK declaration consumers. No SQL, data, or runtime migration.

* build: finish Kysely preparation contract integration

Point explicit test roots at the type entrypoints and exercise generation through its production preparation owner without a test-only export.

* build: include Kysely generator in trusted tooling archive
2026-09-30 22:10:05 -07:00
Peter Steinberger
703cbf2fdf
perf(gateway): coalesce observed project discovery (#162016)
Concurrent observed-project lists each ran their own git discovery per
project, so a reconnect burst multiplied git launches by the client count
(879 git spawns in one boot minute on Team with 11 reconnecting clients).

Share one bounded git discovery pass across concurrent callers and let
later requests refresh the facts instead of recomputing them. The
projects.list reply contract is unchanged.

Testbox fixture (80 repositories, 10 concurrent lists): git launches
1,280 -> 128, wall time 3,196 -> 609 ms, handler-thread CPU 2,136 -> 385 ms.
2026-10-01 05:02:32 +00:00
Peter Steinberger
508e2069f8
refactor(core): deslop bounded caches (#162341)
Move the existing private LRU owner to infra and reuse its byte accounting, replacement, and eviction across identity/avatar readers, workspace files, thumbnails, and Gravatar. Preserve all capacities, TTLs, null/undefined plugin entries, and worker/pending lifecycles; peek keeps awaited revalidation from promoting entries early.

Remove 57 net production lines. Current-base changed checks, both zero-cycle checks, SDK API/export checks, six owner tests, native wrapper inventory, 1,153 plugin-contract tests, import boundaries, full build, and independent review passed. The patch-identical pre-rebase consumer suites passed 326 tests. No public configuration, SDK, protocol, or persisted-state change.
2026-10-01 03:58:01 +00:00
Peter Steinberger
55fe1b4889
ci: let canonical PR rerun matrices finish
Disable native Node matrix fail-fast for every openclaw/openclaw PR
attempt. Run 36804915849 attempt 2 cancelled 57 jobs after an inherited
main failure, preventing the remaining green proof needed by the
explicit prior-CI admin landing route.

Keep first-attempt monitoring, runner caps, routing, timeouts, and other
matrices unchanged. Qualify cancellation against each run's tested
workflow: retain historical expressions and accept the new expression
only for PRs in other workflow repositories. Align CI and landing docs.

Local proof: cancellation verifier 41 tests, workflow control 14 tests,
monitor 65 tests, hourly CI 22 tests, focused Node planning 1 test,
runner-cap and workflow-size guards 2 tests. The new regression failed
on the original workflow. Workflow sanity, formatting, and focused lint
passed; ci.yml is 404072 bytes under the 480000-byte budget. Codex P2
review found no actionable findings. No CI dispatch or rerun requested.
2026-09-30 20:41:33 -07:00
Josh Avant
187594c663
fix(cron): prevent duplicate one-shot delivery after restart (#159873)
* fix(cron): prevent duplicate one-shot delivery after restart

* fix(cron): include delivery migration in PR wrapper closure

* fix(cron): reconcile restart tests and delivery execution

* fix(cron): scope completion authority to background commits

* fix(cron): retain synchronous webhook delivery authority
2026-09-30 21:01:08 -05:00
Peter Steinberger
7c8d77bfd4
fix(pr): stop expiring completed ClawSweeper reviews after twelve hours (#162249)
The landing gate treated a completed ClawSweeper review older than twelve hours as missing and forced a fresh bot review before merge-run even when head and findings were unchanged. Review age no longer matters: the gate requires a completed review marker, keeps the future-dated and conflicting-marker checks, and keeps the SHA-mismatch warning.
2026-09-30 18:20:03 -07:00
Peter Steinberger
b3b34beebe
fix(pr): register the maintenance-context module in the wrapper inventory (#162244)
#162200 added src/state/openclaw-state-maintenance-context.ts without a scripts/pr-lib/wrapper-components.txt entry; the PR wrapper provisioner failed with MODULE_NOT_FOUND, surfaced by test/scripts/pr-worktree-provision.test.ts as a private-store assertion. pr-wrapper-source-closure.test.ts fails on main without this entry and passes with it.
2026-09-30 18:12:15 -07:00
Peter Steinberger
8c39234ebf
refactor(doctor): observe serving Gateway ownership off thread (#162021)
* refactor(doctor): observe serving Gateway ownership off thread

* fix(doctor): complete lease reader import dependencies

* test(update): adapt serving lease observation fixture
2026-09-30 14:11:57 -07:00
Peter Steinberger
5381128b68
fix(update): reduce oversized sealed recovery packages (#161919)
* fix(update): keep recovery imports within their owners

Separate fixed public error codes from executable diagnostic catalogs. Move the existing active handoff map, lease reader, and current-process observer together so callers do not import the service launcher to inspect an existing handoff.

Preserve public identifiers, sanitization, store selection, lease validation, and sealed recovery behavior. Guard the production bundle against capturing Doctor and service controllers, with staged repair and retirement coverage.

* fix(tooling): include update codes in native wrapper inventory

* fix(ci): bound isolated Gateway fixture workers

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.
(cherry picked from commit 30e80e790d)

* test(ci): isolate runtime placement pricing fixtures

Control spare compact capacity and the two workload inputs before asserting co-location. Restore the real runtime timing reader so refitted observations still force the overloaded workloads into separate rows.

Validation: 207 owning cases passed; removing the refitted observations fails the after-placement assertion. Restored-case verification, selected checks, and fresh managed review passed.
(cherry picked from commit 450dba2dc6)
2026-09-30 11:25:10 -07:00
Peter Steinberger
ad8327f586
fix(pr): requalify admission when final main objects are missing
Main can advance during prior-CI verification, leaving the final local-only
reread without its newly observed commit. Return that exact tip to bounded
pre-authority qualification instead of requiring another operator attempt.

Require Git's successful raw-object missing result with empty stderr and
readable previous/verified pins. Discard the active authority proof before
materializing, preserve the captured tip as an ancestry lower bound, and
rerun full live verification against the original proof fingerprint. Refuse
after three rounds without intent or dispatch. REST brackets stay unchanged.

Validation: original two regressions fail; all 47 final main-owner cases and both
confirmed cancelled-auto recovery cases pass, including revoked authority/evidence and
retained history. 47 REST sibling cases pass; one unchanged quota scenario returned
143 under its existing 20s fixture limit after merge/audit/comment and branch
deletions. That failed invocation is retained, not counted as full completion;
no deadline was increased. Initial truncated negative runs are also retained.
2026-09-30 10:25:35 -07:00
Peter Steinberger
1f6754a855
fix(pr): qualify real Gateway failures in cancelled UI jobs
A CI job can finish cancelled after its real-Gateway test step has already
failed. Preserve that failed step as an independently attributed root rather
than refusing its audited UI workflow family or treating it as collateral.

Bind the existing failedStep evidence to the exact UI command, private-QA
build, matrix selection, live check-run and ordered source steps. Recognize
only the explicit runner setup/cleanup pair, and retain all source, review,
security and cancellation checks. Cancelled coverage remains unrun.

Validation: both UI admission cases fail on the original owner; 66 combined
UI/Node/production-type cases pass, followed by 21 final UI cases including
cleanup refusals. The real retained job's 17-step sequence matches the
12-step source workflow plus its explicit runner prelude/postlude.
2026-09-30 09:27:54 -07:00
Peter Steinberger
5c8dd21423
fix(pr): identify failed local-only prior-CI commit probes
Report the previous-main, reread-main, or verified-main OID and Git exit
status when the final local-only commit check refuses admission. Sanitize
stderr through the existing redactor before bounded JSON-escaped display,
and use the selected trusted wrapper's loader configuration.

Keep probe ordering, no-lazy-fetch enforcement, authority checks, and merge
refusal unchanged. Cover all three roles, unavailable commits, unsupported
Git, oversized diagnostics, and an invalid caller checkout configuration.

Validation: original six diagnostic cases fail before the repair; final six
pass. Both prior-CI main-drift and REST owner suites passed (84 tests) before
the failure-only loader pin; the focused cases cover that final correction.
2026-09-30 08:41:27 -07:00