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
Keep native realtime voice replies complete under UI load by moving playback and output routing off the main actor, retaining generation/cancellation fences, and accepting bounded provider bursts. Install acknowledgment identity before replaying startup output.
Related: #163122. Transcript and confirmation work remain separate.
Verified exact-head CI run 36984563290, including native Swift suites and iOS smoke. Contributor supplied physical-iPhone before/after playback evidence; Bluetooth route changes are not certified.
Landing session: https://team.openclaw.ai/chat/roboclaw/dashboard/060f4613-1c9e-4402-8400-66113d2e4463
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Takhoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Marvinthebored <peter@lindsey.jp>
* fix: keep subagent registration responsive during database contention
* test: isolate npm config in installer version fixtures
* fix(agents): fence registration rollback after supersession
* test(agents): inject registration faults through async writer
* test(agents): adapt spawn lifecycle to async persistence
* fix: separate session metadata maintenance from archive admission
* test: use archive finalization for idle collection fixture
* test: pass maintenance cases the Vitest test context
* test: join native cleanup and forward registry persistence in fixtures
* test: isolate registration rollback cancellation from source revocation
* fix: cancel accepted subagents through the lifecycle owner
* fix(state): preserve registry snapshots on validated reopens
* fix(state): explicitly type worker transcript assertions
* test(gateway): retain directive fixture state through cleanup
* test: assert preserved predecessor metadata independently
* test: use the typed session owner in registration recovery proof
* test: join skill library database cleanup before removing state
* test(sessions): bind archive maintenance to fixture state
* test(gateway): follow catalog completion in privacy fixtures
* test(media): use valid PNG in Windows file URL fixture
* test(acp): align fixture state and cleanup ownership
* test: retain restart fixture state through cleanup
* test: retire SQLite owner generations across test files
* test: synchronize completion and maintenance worker fixtures
* refactor: dispatch archive pruning through its worker owner
* test: align reclamation and cleanup fixtures with their owners
* fix: preserve selected subagent ownership observations
* test: preserve registry acknowledgments in fixtures
* fix(ci): settle memory capacity before runtime placement
* test(subagents): forward requester handoff acknowledgements
* fix(sessions): preserve cleanup environment across SDK calls
* test(subagents): bind registration fixtures to their requested owner
* fix(ci): remove duplicate database worker test entry
Keep one PDF resource-test registration in the existing fork-owned inventory.
The repeated entry prevented compact timing generation before CI tests began.
Preserve the complete unique test set and the duplicate guard.
* test(sessions): fix cold maintenance fixture context and cleanup
* test(subagents): forward acknowledged IDs in requester retirement
Preserve the persistence callback receipt through the watched-session test
adapter and trigger requester retirement only for acknowledged run IDs.
* fix(state): retain explicit transcript assertion bindings
Restore the typed local assertion targets required by the production compiler.
Keep the creation-path simplification and current worker dispatch unchanged.
* test(sessions): verify archival in cold maintenance proof
Assert the existing durable-conversation archive contract and retained session
data while preserving the cold worker, FIFO, host-access and settlement guards.
* test(sessions): run SDK cleanup proof with live database owner
* test(sessions): await native writer before cleanup race mutation
* test: preserve registry acknowledgement ordering in fixtures
* test: run session fork coverage with the host SQLite broker
* fix(state): retire failed shared workers before lease cleanup
Keep cleanup bound to the original database identity and live owner while joining canonical actor retirement. Preserve active-callback refusal and existing-only admission.
Make lifecycle fixtures observe real completion and retain the original assertions and deadlines. Align shutdown proof with the shared maintenance writer and await UI readiness within its existing polling budget.
* test: bind generated SQLite fixtures to physical identities
Pass observed identities into cleanup admission while retaining the real host-broker refusal. Use a physical fixture identity for schema-scope proof instead of mocking away identity checks. Preserve the full cross-file cleanup and retained-lease assertions.
* test(subagents): respect retirement acknowledgement before registration
Observe the successor joining the actual pending write, then hold only the older cleanup continuation after persistence and publication settle. Preserve successor data, current authority, publication revision and hook fencing when that continuation resumes. Join both operations on cancellation without changing deadlines.
* test: run catalog boundary coverage with the host SQLite broker
Classify the existing embedded-attempt catalog suite with the canonical forked-process owner. Keep broker admission guards and all test assertions unchanged.
* test: preserve active runs and order watcher replacement fixtures
* test: align worker inventory with upstream classifications
* fix: retain failed-spawn cleanup and completion authority
* fix: align subagent cleanup checks with worker ownership
Return the existing false completion policy for retired stores before checking
live delivery authority. Eligible delivery still requires current authority at
the outbound boundary.
Route preparation-fixture cleanup through the captured Gateway owner and join
accepted handlers before tearing down parent state. Align session-group fixture
helpers with the catalog's state directory and classify published inbound
maintenance under the existing host broker test project.
Verified 60 focused behavior cases, 481 project-ownership checks, three owning
type graphs, 13 static checks, and two scoped independent reviews. The prior
parent-fork teardown failure did not reproduce in one bounded diagnostic replay;
its cause remains unresolved. All temporary diagnostics were removed.
Move durable pending history and exact-message reads through the history worker and stale interruption through the agent writer. Preserve bounded pages, consumed filtering and live cancelled disposition custody with SQL-free transaction and commit grants; settle acknowledged writes without replay. Keep incognito and unrelated custody operations with their existing owners.
The ownership check added in 4dc04b14f0 skips Git for roots without
checkout metadata. The status fixture used a nonexistent /repo and then
waited for a probe that would never start. Give it a test-owned temporary
.git marker and keep discovery, command results, and config paths on
the same root.
Fail the existing probe-start wait when status settles first, preserving
all cases, output assertions, fake-clock budgets, and test timeouts.
Validation: five complete local runs before rebase (55/55 cases) and
three after rebase (33/33); oxfmt, type-aware file lint, boundary lint,
and P2 review passed. The single-file Testbox exception is authorized
for this one-file, test-only change; full-config and check-changed gates
were omitted under that exception.
Wait for the asynchronous session manager helper before appending the initial worker-turn transcript message. This restores the gateway-other typecheck and exercises the warm second-turn recovery cases without changing production behavior.
Fixes#163518.
The message tool now reports "Message action <action> not supported for channel <id>." for a loaded channel that has no handler for that action, instead of the misleading "plugin not loaded". Absent channels still report "Unknown channel", and channels with actions are unchanged.
Proof: isolated built Gateways with A2A loaded. main returned "plugin not loaded" for a read against A2A; this change returns the unsupported-action error, over both Gateway HTTP and the CLI. A QA Channel read works on both. Live check: real gpt-5-mini called message read against A2A and quoted the corrected error. Regression test fails on main and passes here.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
The catalog-worker deletion test introduced by #159013 expected an idle
WAL reader to keep the surviving agent database locked. That lock is
already absent before deletion on current main.
Verify the actual survivor contract instead: commit a new auth profile
through an independent connection, then read the exact update through
the existing prepared worker. Keep the deleted-database lock-release and
single live-worker assertions.
Validation: five complete local file runs, local and Linux Testbox
check-changed, changed-file and boundary lint, and P2 review passed.
The full infra run was cancelled before completion. Landing uses the
coordinator-approved single-file Testbox exception for this test-only
change; the completed focused and static proof remains valid.
Three additional post-rebase file runs passed.
Share eligibility and terminal receipt finalization between manual and scheduled cron runs. Move watcher retries and deadlines into scheduler scopes, closing admission synchronously and joining callbacks outside their serialized owner queues.
Exact-head CI, original shard-order replays, and focused regressions pass. Published 2026.9.7 update and installed Gateway SIGSTOP catch-up, SIGTERM join, durable receipts, and two-restart duplicate prevention pass on Testbox.
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.
* test(gateway): background the progress refresh barrier
* test(gateway): verify progress-refresh barrier completion
Use the shared fixture receipt channel for readiness, release, and child
exit. Require the barrier command's correlated process result to report
successful completion before accepting the final reply.
Keep external-wait status in Markdown without introducing an unfinished
structured plan. Preserve the model, budgets, active and idle assertions,
and single-launch check.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* 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.
Publish committed provider-review changes through the existing metadata
invalidation owner. A generic store notification discarded resident sharing
identity, so accepting a provider response immediately failed the retained
caller's session-authority check. Bind the publication to the admitted
execution's agent and physical database identity while retaining current
transaction, commit, device, and acknowledgment checks.
Release note: Fix session-changed errors after acknowledging provider review
findings, preserving exact continuation input and viewer/device restrictions.
Remove cron JSON jobs/state and JSONL history imports whose last stable writer predates July 2026. Keep supported quarantine and SQLite migrations with Doctor, and refuse retired live inputs before update activation while preserving the published Gateway and operator data.
Final-head Testbox validation and both published 2026.9.7 update cells pass. The PR records source-qualified CI failures inherited from main and their landed fixes.
Prepare reaction list/set access through the resident membership projection
and existing asynchronous sharing-facts owner. Keep current caller, role,
session, and physical-source checks in the writer and mirror guards without
synchronous sharing reads on the Gateway thread.
Preserve native incognito ownership and leave the remaining sharing caller
cohorts unchanged. Prove the registered reaction boundary performs no
caller-thread SQLite and rejects revocation during asynchronous preparation.
* fix(test): discover UI unit tests with browser in their names
Use the native full-basename selector while preserving the dependency-free planning matcher. Compare registered root and package inventories so browser-import unit tests keep their Node owner.
* fix(test): align project inventory with native discovery
The candidate rehearsal copy lives under the service TMPDIR (for example ~/.openclaw/tmp), so Node module lookup from inside the copy walks up to the home directory; bundled playwright-core requires an undeclared optional chromium-bidi, which resolved from a home-level node_modules and made the outside-copy containment assertion fail the candidate Doctor on every 2026.9.6 to 9.7 attempt. The dependency scan now classifies an undeclared package that resolves only through an ancestor directory as unresolvable inside the temporary update copy (a warning before source capture); declared dependencies that resolve outside the copy and symlink escapes keep the fatal assertion. Auto-update admission pauses after two matching candidate Doctor failures for the same candidate using the existing SQLite update-run records, with a warning that states the recovery steps; a changed candidate or a manual openclaw update clears the pause. Thanks @iJaack for the diagnosis.
Closes#163486
Run one post-removal catalog cleanup, preserving partial-exit cleanup and
compensation. Batch candidate inspection through the shared-state worker and
retain canonical agent mutation workers only for catalogs needing changes.
Serialize catalog publication and cleanup by canonical database path so an
uncommitted replacement cannot escape a no-op inspection.
Preserve OAuth generation ownership, exact credential matching, surviving
accounts, and retry recovery. Move catalog removal tests and its facade into
focused modules without retaining the old export.
Blacksmith Testbox proof: five-run first-test median 5024ms to 702ms;
six-store removal 5171ms to 395ms, mutation-worker calls 12 to 0.
Auth profile selection: 788 tests / 66 files; focused suites: 103 tests.
Build, changed guards, core and all 27 test type graphs, and corrected lint
passed. Independent review is clean through P2.
Assert the credential-write refusal through its structured JSON cause and
concise stderr, mark the update fixture as an in-progress replacement, and
expect the current provider-failure copy in Telegram settlement coverage.
All original side-effect, raw-error suppression, and settlement checks remain.
These three inherited test failures were qualified during #163408. Their
six cases passed in the frozen-main AWS proof with fs-safe 0.22.0; the
independent dependency A/B established the inherited failures with 0.23.0.
Scoped lint, affected typechecks, formatting, and relevant ratchets passed
with installed 0.23.0. Final files match the independently reviewed bytes.
No production behavior changes.
Fixes#145562.
The system-prompt report and `/context` now count only the skills the rendered system prompt actually includes. When neither `read` nor `skills_read` is available the catalog is omitted, so the report shows 0 skills instead of every installed skill. The system prompt itself is unchanged.
Proof: real embedded turns plus Gateway `/context list`. With both readers denied, main reported 20 skills while 0 were rendered; this change reports 0. With either reader allowed, both report 20 and render 20. Captured provider system-prompt bytes are identical between main and this change in all three cases. Live check: a real gpt-5-mini request carried no skills catalog and the report showed zero. Regression tests fail on main and pass here.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* 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.