2558 Commits
Author SHA1 Message Date
Josh Avant 877ea98750 fix(cron): report unknown delivery when webhook responses time out (#159840)
* fix(cron): preserve unknown webhook delivery outcomes

* test(cron): complete webhook outcome job fixture

* chore(cron): satisfy webhook change lint guards

* fix(cron): surface unknown delivery in CLI status
2026-09-27 15:36:15 -05:00
Peter Steinberger 1b5ac171f6 fix(pairing): device join codes ignore gateway.publicOrigin behind public ingress (#159465)
* fix(pairing): honor gateway.publicOrigin for device join codes

A loopback Gateway behind public HTTPS ingress sets gateway.publicOrigin, and
cloud node enrollment already used it, but device join codes, the device-pair
plugin, and Doctor's node-hosting check each resolved the pairing endpoint on
their own and ignored it, failing with advice that omitted publicOrigin.
Make src/pairing/setup-code.ts the single owner (device-pair publicUrl
override, then gateway.publicOrigin, then existing discovery), expose it to
the device-pair plugin through plugin-sdk/device-bootstrap, remove the
plugin's duplicate resolver and enrollment's private fallback, and share one
loopback error that names gateway.publicOrigin.

* fix(pairing): preserve explicit remote endpoint selection

Honor preferRemoteUrl before gateway.publicOrigin so qr --remote keeps
its selected endpoint aligned with remote credentials. Retain publicOrigin
as this Gateway's ingress ahead of automatic Tailscale, remote, and bind
discovery, with the pairing-specific override taking precedence.

Cover configurations with both URLs at the resolver and QR CLI boundaries,
and correct the CLI, cloud-worker, and SDK precedence documentation.

Validation: 221 focused tests passed; scoped core, extension, script, and
test typechecks passed; independent review found no actionable P0-P2 issues.

* fix(pairing): preserve device routes with explicit cloud ingress preference

Keep existing device join-code, QR, and /pair discovery order. Use
publicOrigin only at the loopback fallback, while cloud enrollment asks the
same resolver to prefer public ingress at both preparation and issuance.

Use the canonical lazy runtime binder for the SDK export so the collision
guard recognizes one implementation without loading setup code at startup.
Document the two call-site intents and cover Tailscale, LAN, loopback, and
cloud enrollment behavior.

Validation: export-name collision and SDK surface guards passed; 222
focused tests and scoped typechecks passed; independent review was clean.

* chore(device-pair): drop the max-lines suppression the smaller plugin no longer needs

* fix(device-pair): preserve origin-only setup URLs

Retain the plugin command URL mapping through the shared pairing resolver while preserving context paths for join codes and cloud enrollment. Clarify public-origin fallback and remote QR prerequisites.
2026-09-27 12:07:50 -07:00
Peter Steinberger be36d55a70 fix: keep gateway startup retryable after failed reads (#159598)
* fix: keep gateway startup retryable after failed reads

* fix: retain terminal agent ownership refusals

* fix: preserve confirmed startup refusal causes

* fix(gateway): preserve startup refusal evidence across reads

Keep unavailable config, backup and SQLite reads retryable while preserving
confirmed config, schema, ownership and maintenance refusals as exit 78.
Carry failure causes through existing admission owners without changing
public refusal data, persistent schemas or migration policy.

Resolve the main integration and retain its identity-store ownership.
Include exact upstream test-call corrections needed by the current helper API.

* test(gateway): narrow startup failure fixture variants

* test(state): expect typed schema refusal on committed reads

* fix(state): classify expired schema read scopes for actor retirement

Reuse the established read-admission invalidation type when a managed schema scope ends. Preserve original scope rejection and the worker owner’s relocation and active-callback fences while allowing idle old actors to retire for valid replacement callers. Integrate current main and prove ordinary and same-path managed replacements with native workers.

* test(media): use valid PNG in Windows file URL fixture

* chore: reconcile startup read repair with main

Take the upstream schema-scope production correction unchanged. Preserve complementary fresh managed-scope and retained prepared-reader coverage with the upstream typed refusal assertion, and retain the main iterative include scan beside the reviewed config read helpers.

* fix(subagents): preserve resident source admission failures

Use canonical cache absence semantics in both snapshot identity getters. Remove catches that translated expired current read scopes into missing cache facts; preserve full-row publication handling and same-file source renewal. The unchanged scope regression fails before this correction and the registry, lifecycle and projection suites pass afterward.

* Merge main to retain its Windows media fixture repair

* Merge main while preserving its worker-lifecycle reverts

* fix(state): retain complete typed startup refusal reports

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 11:08:30 -07:00
Peter Steinberger 6652f7eac8 refactor: remove Tasks and TaskFlow runtime (#159179)
Remove Tasks and TaskFlow runtime, APIs, CLI, SDK surfaces and panels after the Cron, session, native execution and media completion ownership cutovers. Preserve stored rows and import provable legacy native assignments through Doctor; ambiguous ownership stays untouched with a warning.

Follows #158221, #158217, #158225, #158222, #158702 and #158776. Related: #156532. Task-specific public APIs retire immediately; retained responsibilities use their existing owners.

Maintainer-authorized administrative landing after full CI run 36312986498 attempt 2 passed on 274595e2, with subsequent actual conflicts reviewed and focused checks passing. Current PR CI preflight hits the 64 KiB changed-path metadata limit before tests (run 36335042695); its duplicate security-review status mirrors that planning failure. Review and scoped proof are recorded in the PR. Published 9.4 native import is proven; remaining native completion and 9.4 rollback witnesses are explicitly unproven.
2026-09-27 10:40:29 -07:00
Peter Steinberger a23b5382c6 fix(cli): report invalid cron timezones accurately (#159756)
Distinguish invalid timezones from invalid datetimes at the zoned parser owner, and preserve the scheduler caller's existing failure behavior. Share timezone validation across cron add/edit schedules so valid timestamps are no longer blamed for invalid --tz input.

Add registered add/edit regressions and retain invalid-calendar and DST-gap controls. Blacksmith proof captured seven failing CLI cases before the fix, 79 passing CLI tests and 75 passing parser tests after it, 624 passing focused tests, and a passing check-changed gate. No local test, build, install, or formatting commands were run.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 10:07:36 -07:00
Peter Steinberger 574927f256 fix(cli): emit JSON errors for invalid config output flags (#159760)
Use the shared CLI failure envelope for config unset and patch usage errors when JSON output was requested. Preserve config set's parse-only JSON alias and existing dry-run results.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 09:18:06 -07:00
Peter Steinberger f42352b195 fix(cli): fail sessions tail for missing or blank explicit keys (#159704)
* fix(sessions): fail tail for missing explicit keys

Report an actionable error and exit nonzero when sessions tail cannot find
an explicitly selected session. Keep an empty implicit selection a
successful no-op, including follow mode.

Add command-owner regressions for explicit missing keys with and without
follow, plus preservation of the implicit empty-selection behavior.
Document the distinction in the CLI guide.

Blacksmith Testbox proof: the unchanged owner fails exactly the two new
missing-key assertions (26 pass); the fixed owner passes all 28 tests and
the registered CLI sibling passes all 53 tests. Independent review is clean.
Changed checks reach the unrelated provider-lifecycle.ts TS2322 already
fixed upstream by a241b3bf6e.

* fix(cli): reject blank session keys in sessions tail

* test(sessions): avoid shadowed session key in tail regression

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 09:06:18 -07:00
Peter Steinberger dd5171c609 fix(cli): stop advising retries for declined conditional config writes (#159708)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 08:38:31 -07:00
Peter Steinberger c1e06c290b fix(cli): reject cron timeouts on system-event jobs (#159716)
Reject unsupported timeouts before creating system-event jobs instead of silently dropping the option. Share payload timeout support validation with edit while retaining script guidance and system-owned job protection.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 08:33:09 -07:00
Peter Steinberger 87f2e6371b fix(plugins): stop deleting sources after cleanup is revoked (#159563)
* fix(plugins): keep cleanup under source ownership

* test(plugins): model managed config activation during cleanup
2026-09-27 10:42:55 +00:00
Peter Steinberger e394e1e0e9 fix(update): keep waiting while candidate startup progresses (#159504)
* fix(update): keep waiting while candidate startup progresses

Renew the existing size-based canary allowance from completed CLI and Gateway milestones. Preserve recorded warnings, reject stalled candidates, and observe process exit without waiting for inherited pipes.

Refs #157332. The published 2026.9.4 parent deadline is unchanged; Linux proof found private schema migrations and did not reproduce the reported old-reader mismatch.

* fix(update): bound candidate startup validation
2026-09-27 03:41:55 -07:00
Peter Steinberger 244d441972 fix(daemon): inspect registered Gateway services accurately (#151608)
* fix(daemon): inspect registered Gateway services accurately

Read strict Windows service commands from registered actions and preserve
supported launcher encodings without treating dynamic CMD expansion as a
verified command. Retain exact task identity and bound systemd selection.

Use one platform inventory collector for the existing full and diagnostic
projections. Report incomplete inspection through Doctor while preserving
status JSON and the existing managed-service filters. Keep load-state
inspection behind a leaf capability instead of reverse facade imports.

Refs #151608, #151463.

* fix(daemon): classify service commands by position

Share runtime and root-option parsing so Node display names and profile values
cannot classify a Node service as a Gateway. Preserve literal shell, env and
generated launchd wrappers, and honor the executable selected by launchd.

Read systemd's single-quoted arguments through the existing parser and preserve
literal apostrophes when rendering. Keep strict Windows command rejection
separate from lenient diagnostics, and align the native-boundary fixtures with
that contract without weakening ownership or source-preservation assertions.

* fix(daemon): inspect direct registered task actions

Read literal executable actions from their registered Scheduled Task and
revalidate the action before returning command facts. Strict runtime inspection
uses the same registered command instead of a default launcher.

Keep executable paths out of managed launcher provenance. Direct actions remain
outside automatic update service management when no restorable CMD/VBS launcher
exists, preserving the prior stop and definition ownership boundary.

* test(windows): prove installed service upgrade paths

Extend the existing native Scheduled Task proof with verified immutable package
handoff and fixed fresh, published 2026.9.3, and published 2026.9.4 CLI cells.
Require live version/build identity, selected PID replacement, peer continuity,
strict registered-action inspection, and settled cleanup before evidence
publication and disposable installation retirement.

Keep source-only and repair modes, permissions, deadlines, and native lifecycle
owners intact. Direct executable fixtures remain disabled and preserve the
updater's unsupported-mutation boundary. Native execution remains pending.

* test(doctor): retain managed Windows launcher provenance

Keep the generated CMD path on the existing managed-service fixture before
and after reinstall so Doctor admission sees the installation it models.
Preserve all stop, install, restart, rollback, and direct-action refusal
expectations without changing production behavior.

* test(windows): exercise native autostart ownership boundaries

Extend the existing published-updater cell with its stopped, task-owned
Scheduled Task. Capture real admission, exercise native enable/disable,
and preserve the definition and files after foreign-owner refusal.

Test retained admission separately from restoration so legitimate same-root
refresh remains supported. Restore the original XML through the existing
fixture lifetime; do not broaden product control or workflow permissions.

Modeled owner tests, selected source checks, and independent review pass.
Actual Windows execution remains required before a native proof claim.

* test(windows): retain sanitized installed command failures

Keep unexpected command stdout and stderr in bounded failure diagnostics so
JSON-mode CLI errors survive native proof failures. Reuse the existing
terminal and support redaction owners before clipping; withhold incomplete
captures while preserving the existing truncation failure.

Move the existing command runner into its own test-support module and update
both consumers without changing timeout, exit, signal, or cleanup semantics.
Real-child regressions reproduce both privacy defects and pass with the
correction. The original installed Gateway failure remains undiagnosed.

* fix(daemon): preserve Windows probe budgets and Doctor cleanup eligibility

Use the existing cold PowerShell startup budget for Task Scheduler queries
without an explicit deadline. Keep periodic activation checks bounded and
preserve unknown results rather than treating timeouts as task absence.
The native probe test now exercises the production default.

Share Doctor's existing legacy cleanup classification with its registered
preview. Keep unsupported platforms, scopes and unrecognized Linux unit
names as findings without advertising removal or invoking unrelated cleanup.
Extract the classifier and complete cleanup test group without dropping
assertions or changing native mutation ownership.

Retain the failed installed Windows runs and their source identities;
new package and native upgrade qualification remain separate requirements.

* chore(daemon): retire stale Doctor size baseline

The split Doctor service module no longer needs a max-lines suppression.
Remove only its stale baseline entry so the shrink-only ratchet matches
actual source. Product, dependency, workflow and fixture bytes are unchanged.

* test(windows): retain sanitized service proof observations

Record bounded install and status facts before semantic assertions so a
successful CLI exit cannot hide the native inspection reason. Exclude
free-form stderr and private response fields, and preserve existing
execution, deadline, and cleanup assertions.

* fix(windows): preserve native status inspection defaults

Keep the CLI RPC default distinct from an explicit timeout so Windows
service inspection can use its existing cold-start budget. Forward
explicit load-query deadlines through the Task Scheduler owner while
preserving lifecycle defaults and timeout diagnostics.

* fix(models): retain discovered models after refresh failures

Record successful legacy catalog results at the producer boundary so unavailable refreshes retain the accepted inventory. Preserve explicit outcomes, advisory SDK fallback behavior, and first-discovery starter policy.

* fix(models): preserve skipped catalog outcome semantics

Mark bundled static, configured, and advisory catalog projections with
explicit empty outcomes so legacy success inference cannot promote them
to observed account inventory. Preserve live outcomes and helper types.

Keep exact auth provenance histories and move existing fixture/policy
code into focused owners where required by the line-cap ratchet.

Validation: 447 producer and sibling cases, 56 shared self-hosted cases,
95 auth/policy cases, causal missing-outcome failures, maintained checks,
and independent review.

* test(plugin-sdk): keep discovery loader types acyclic

Move the shared loader type into a leaf consumed by both discovery
contract helpers. Preserve its public provider-test-contracts export
without a child-to-parent type import cycle.

Validation: maintained Madge check reports zero cycles; core, all core
test graphs, extension test types, lint, formatting and independent
review pass. Runtime behavior and previous catalog proof are unchanged.

* fix(plugin-sdk): mark generated static catalogs explicitly

Keep the generated non-live, non-strict catalog adapter from claiming
successful acquisition for manifest or configured rows. Preserve null,
errors, strict and custom callbacks, static catalogs, and public types.

Validation: three existing controls fail before the correction; all49
owner and sibling cases pass afterward, with types, lint, line caps and
fresh independent review clean.

* test(windows): handle omitted scheduled task settings

* test(windows): preserve native context and failure evidence

* test(daemon): wait for installed gateway readiness before inspection

* test(daemon): stop installed fixtures through their profiled CLI

* fix(daemon): inspect extra Windows services before removal

Keep verified Node and legacy diagnostics visible while offering read-only
Scheduled Task inspection in Doctor and deep status. Preserve the existing
service cleanup owners and diagnostic JSON shape.

Carry the canonical SQLite fixture host-context and dependency-selection
repairs from #158209 and #158409 for the inherited CI collection failure.

* fix: restore asynchronous harness task completion

Complete the shared task-content projection cutover for asynchronous finalization and delivery. Preserve the captured Incognito policy and exact task-assignment fences.

The unchanged worker suite reproduced six ReferenceError failures before the fix and passes all seven cases afterward; the sibling SDK runtime suite passes all 30 cases. Independent review is clean through P2.

* test(windows): budget installed service phases and retain progress

* test(windows): retain failed installed update progress

Read failed published-updater progress through the existing asynchronous SQLite owner before native cleanup. Retain only safe phase, status and step timings; preserve all command, body and teardown deadlines.

Validation: five installed-fixture tests, services types, targeted changed checks and independent review through P2 passed. Shared diagnostic implementation qualified in the Windows fixture owner.

* fix(daemon): bound aggregate Windows service inventory

Carry one monotonic deadline through Scheduler discovery, launcher reads, registration revalidation, and missing-launcher metadata. Preserve completed findings and report incomplete inventory when the shared budget is exhausted.

* fix(daemon): classify registered helpers without profile admission

Let read-only registered inventory classify faithfully revalidated commands
without requiring an OpenClaw profile. Keep selected-service profile
admission strict and preserve launcher, Task, script and deadline checks.

Native disabled-discovery exposed a false warning for a static node --version
helper. The actual collector regression fails before this fix and passes
with all 206 owner and sibling cases afterward.

* fix(daemon): recognize released waiting task launchers

Recognize the exact waiting VBS wrapper shipped by 2026.9.3 during
owned service reconciliation. Keep custom launcher behavior unknown and
preserve all command, root, Task and authority checks.

The real audit entry point rejected this released form as TaskLauncher
unknown-edit before repair. The causal regression and edited-launcher
control pass with 55 audit and 140 backup/rewrite sibling cases.

* test(daemon): cover retained Task ownership refusal

* test(windows): preserve XML bytes around enabled export lines
2026-09-27 02:55:51 -07:00
Peter Steinberger b8fecb10a0 fix(doctor): recover indexless history and preserve import sources (#159561) 2026-09-27 09:29:09 +00:00
Peter Steinberger 1ea49e6030 refactor(update): consolidate package and candidate update helpers (#159397)
* refactor(update): reuse npm retry arguments and trim dead package checks

* refactor(update): derive plugin tree types from the plan schema

* refactor(update): reuse mutation authority for package retirement

* fix(update): classify candidate cleanliness before reporting completion

Reuse the clean-check owner and inline single-use Git update helpers. Preserve selected-commit validation and failed-checkout rollback.

* refactor(update): drop cyclic plugin-tree type consolidation

Restore both original type shapes for B1. Sharing the plan schema without a static import cycle requires a wider owner change, outside this cleanup scope.

* test(update): align npm retry argument expectation
2026-09-27 02:05:39 -07:00
Peter Steinberger a66d75f967 perf(update): defer duplicate advisory Doctor inspections in rehearsal (#159443)
* perf(update): defer advisory Doctor inspections in copied rehearsal

* perf(update): preserve repair warnings when deferring inspections
2026-09-27 01:06:44 -07:00
Peter Steinberger 702de400b4 refactor(plugins): deslop workboard, voice-call, reef and line second pass (#158847)
* refactor(plugins): deslop workboard, voice-call, reef and line second pass

Consolidate private projections and lifecycle plumbing, remove unreachable helpers, and derive Swabble CLI dispatch from its command tree. Preserve plugin, media, webhook and persisted-state contracts.

Fix Workboard Doctor migration aborting on a null legacy attachment; retain malformed source records while migrating valid attachments. Regression fails on the original null dereference and passes on the repaired owner.

* refactor(workboard): preserve generated browser asset identity

* test(signal): reuse container transport fixtures

* fix(reef): keep update rehearsals from migrating live files

Declare Reef migration resources and defer whole plugin state migrations when
their declared files lie outside the copied rehearsal state. Preserve pending
and required migration facts, configuration repair, and normal live Doctor.
Use one resource owner for inventory and execution, rechecking selected paths
before writes, and retire the superseded private collection wrappers.

Registered-runner regressions reproduce live-file mutation on the original
code and cover direct, automatic, and post-session repair paths.

* refactor(doctor): simplify rehearsal resource projection

* ci: refresh merge validation after upstream suppression repair

Revalidate the PR merge context after main e6fae68631 repaired the plugin suppression inventory. The reviewed source tree and runtime proof inputs are unchanged.
2026-09-26 23:06:12 -07:00
Peter Steinberger 4ec35b53b7 fix(doctor): resume schema repair after interrupted migration (#159345)
Record process identity for schema/media migration leases and reclaim only demonstrably dead process owners. Preserve expiry for work that can outlive its parent, existing snapshots, and transactional migration recovery.

Refs #158114. Linux SIGKILL recovery and three focused passes passed; 91 dependent files and changed checks passed; P1 autoreview clean.
2026-09-27 04:02:19 +00:00
Kevin f6974fb355 fix(node): reconnect after fallback pairing code expires (#159360) 2026-09-26 20:39:25 -07:00
Peter Steinberger 61ff44690e fix(doctor): restore retained artifacts after APFS remounts (#159176)
Verify historical archive receipts with device tolerance for normal restores and interrupted publications, then bind strict publication checks to the captured live identity. Preserve recorded receipts and reject changed originals.

Blacksmith proof: both unchanged-artifact regressions fail before the fix and pass afterward; 63 focused tests pass with 2 platform-specific skips. check-changed and isolated review pass. Existing receipt formats and updater behavior remain unchanged.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 19:20:05 -07:00
Peter Steinberger 063b1971ec fix(cli): fail reset when cleanup is incomplete (#159250)
Report nonzero completion when config, credential, session-directory, state, or workspace cleanup fails. Preserve best-effort cleanup and show the onboarding hint only after complete success.

Live QA reproduced a locked config removal reporting EPERM with exit 0. Blacksmith regression proof: 7 expected failures before the fix, 45 reset and sibling tests passing after it, changed-file checks passing, and independent Codex review clean.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 18:26:19 -07:00
Peter Steinberger 44465b4472 fix(channels): include runtime namespaces in channel logs (#159244)
Match channels/<channel> logger roots and their descendants so runtime startup and provider errors appear in filtered text and JSON logs. Preserve exact channel boundaries and the existing documented namespaces.

Regression proof: both new namespace cases fail before the fix. All 72 scoped command and CLI tests and the changed-file checks pass on Blacksmith Testbox. Independent review found no actionable P0-P2 findings.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 17:47:31 -07:00
Peter Steinberger 389cee4cb1 fix(channels): keep disabled plugins in installed inventory (#159242)
Read channel installation facts from the prepared metadata snapshot with disabled owners included. Keep setup activation decisions unchanged and preserve absent catalog channels as installable.

Add a command-boundary regression for text and JSON. Both cases failed before the fix; 22 channel-list tests and the changed-file gate passed on Blacksmith Testbox. Clarify that disabling a plugin does not uninstall it.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 17:29:46 -07:00
Peter Steinberger 204b00bf08 fix(cli): preserve channel status gateway rejections (#159243)
Return authoritative Gateway request errors through the normal CLI failure path instead of reporting the Gateway unreachable with exit 0. Keep connection failures on the existing config-only fallback.\n\nReproduced unknown channel status on built main 71ca294e23 through an isolated lane CLI. Blacksmith Testbox regression: both new cases fail before; 31 tests pass after. Remote check-changed passes; independent review has no actionable findings.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 17:27:56 -07:00
Peter Steinberger e682334c52 fix(cli): never fall back to local state when a remote Gateway is unreachable (#159223)
* fix(sessions): preserve remote cleanup destination on connection failure

Restrict automatic offline cleanup to the configured local Gateway. Pin the resolved RPC destination while preserving its authentication selection, so remote configurations and environment URL overrides cannot silently clean local stores when their connection fails.

Regression: two refused-loopback-tunnel cases fail on the original code and pass with the fix. Blacksmith validation passed 191 focused tests and check-changed. The changed command suite took 18.684s wall with one worker. Independent review found no actionable issues through P2.

* fix(agents): preserve remote deletion targets on pre-connect failure

Share the pre-dispatch fallback decision with sessions cleanup under the Gateway call owner. Pin agent deletion to the classified config and URL; remote transport and credential failures now leave local agent state intact and explain how to restore the connection or run on the Gateway host. Preserve local credential fallback with skipped cron cleanup and keep ambiguous transport errors unchanged.

Four remote-target regression cases failed before the fix against the agents-delete implementation identical to origin/main. Blacksmith Testbox passed all 227 tests across the agents deletion, sessions cleanup, and Gateway call suites (41.36s total), plus check-changed. The new regression cases took 0.5-0.7s each. Isolated review was clean through P2 after replacing an expired reviewer login with the existing Testbox API credential. Local hooks were skipped to honor the remote-only check requirement.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 17:22:51 -07:00
Peter Steinberger 74469f58f3 fix(gateway): classify unknown model providers as invalid requests (#159237)
Reject unknown models.list provider filters with INVALID_REQUEST instead of letting a generic exception become UNAVAILABLE. Name the rejected provider and point callers to openclaw models list --all. Preserve valid provider filtering and genuine availability errors.

Move existing provider-filter coverage to the registered handler and verify CLI message propagation and exit code 1. Update CLI and RPC documentation.

Validation on Blacksmith Testbox tbx_01m3ftahjxpg1pz589w82vtz6f: baseline regression failed with the generic provider error (1 failed, 14 passed); repaired handler, model/session, and CLI suites passed (109 tests). Full check-changed and independent P0-P3 review passed. Local hooks disabled because all checks were required to run remotely.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 16:39:46 -07:00
Peter Steinberger 1e7ec6a4f6 fix(cli): reject invalid root options before bare launch (#159213)
Use the shared root argument parser to distinguish valid bare launches from unknown or incomplete options. Leave invalid input to Commander so a typo reports an option error instead of opening onboarding or the TUI. Preserve the terminator and valid root-selector behavior; cover fresh and configured entrypoints with real Commander parsing.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 15:51:25 -07:00
Peter Steinberger 19c6ef8d9e fix(proxy): keep capture persistence off the main thread (#158848)
* fix(proxy): keep capture persistence off the main thread

Move bundled capture writes, payload compression, and inspection through the canonical SQLite workers. Preserve shipped synchronous SDK compatibility and exact database, maintenance, and accepted-callback ownership.

Drain accepted capture before shutdown, release partial proxy startup, and charge queued payload preparation through the existing broker. Preserve schemas, stored bytes, and retention. Related: #148336.

* chore(proxy): reconcile capture activation with current main

* chore(proxy): preserve current SDK surface counts

* refactor(proxy): isolate async capture store contract

* fix(proxy): include worker dependencies in PR wrapper

* chore(proxy): compose capture migration with current main

* test(proxy): finish database worker lane routing

* test(proxy): retain Node coverage after worker lane migration

* fix(proxy): drain active captures before signal exit

* fix(proxy): preserve legacy capture cleanup in mixed sessions

* fix(proxy): preserve capture metadata and composed worker routes

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-26 13:45:36 -07:00
Peter Steinberger 8bb8609f59 fix(update): prevent reporting errors from rolling back verified updates (#159072) 2026-09-26 11:53:13 -07:00
Shakker 31445e843a fix: retain updater runtime with retired workspace links (#159035)
Retain the updater and its dependencies when source movement leaves manifest-less workspace links.

Fixes #159034.
2026-09-26 19:17:39 +01:00
Peter Steinberger 605cc417c0 fix(plugins): load current plugins while update rollback trees are retained (#159052)
* fix(plugins): load current plugins while update rollback trees are retained

* fix: preserve plugin capture dependencies in PR wrapper extraction
2026-09-26 18:02:34 +00:00
Peter Steinberger a026d54233 fix(update): carry the run id into managed-helper candidate inspection (#159010)
Use the inherited update run ID when candidate inspection has no explicit
run context, then retain the existing live handoff lease verification.
Preserve refusal for missing run IDs, stale leases, and genuine Gateway
children. Correct the documented service boundary for systemd scopes.

Real systemd update.run now replaces the package and restarts the Gateway
successfully; focused regression coverage passes three times.
2026-09-26 09:48:33 -07:00
Leon-SK668andPeter Steinberger b1c68b936f fix(doctor): tolerate APFS device changes for retained artifacts (#158842)
* fix(doctor): tolerate APFS device changes for retained artifacts

* style: format retained-artifact regression test

* fix(doctor): complete retained artifact remount verification

Verify historical registries and transcripts against remount-tolerant receipts, then keep publication strict against the captured live identity. Preserve receipt bytes and current SQLite state.

Isolate update CLI fixture checkouts so source artifact admission cannot contend for the shared repository lock. Keep executable helper and plugin discovery rooted in the source checkout.

Co-authored-by: Leon-SK668 <0668001470@xydigit.com>

* style(doctor): return completed cleanup identity explicitly

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Leon-SK668 <0668001470@xydigit.com>
2026-09-26 08:47:19 -07:00
Shakker c1245de88a fix: rebuild incomplete Git runtimes when source is current (#158931)
Rebuild source-current Git installs when required runtime artifacts are incomplete and report verified artifact readiness with the built version.
2026-09-26 16:06:56 +01:00
Vito CappelloandVACInc f4ec0ff4dc fix: let setup chat remove configuration overrides (#158873)
* fix: let setup chat remove configuration overrides

* test(cli): isolate updater fixture checkouts

* fix: keep config deletion out of remote rescue

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-09-26 14:44:03 +00:00
Shakker e8b43f875b feat: expose preferred Git release targets in update status (#158926)
Expose the native preferred stable or beta Git release commit in JSON update status after fresh private target inspection.
2026-09-26 15:26:55 +01:00
Peter Steinberger 10453a8d8b fix(doctor): migrate every agent database before repairs open it (#158584)
* fix(doctor): migrate every agent database before repairs open it

Complete configured session-store targets before media/schema repair.
Recognize intact pre-journal v1 state without releasing lost-history holds,
and fail explicit Doctor repair when those holds remain unresolved.

Refs #158359.

* fix(tooling): include journal admission in wrapper inventory

* fix(doctor): admit pre-journal v1 stores with writer metadata

Treat app_version as optional writer metadata rather than evidence that a
schema-v1 store had a deletion journal. Keep the schema, ownership, newer-table,
journal-receipt, and recovery-hold guards intact.

Register the agent database ordering regression with the runtime-build
prerequisite owner so it runs in a clean checkout. The two CI runtime-inventory
expectation updates add exactly this newly registered test input; they preserve
exact equality, runtime preparation, ownership, and worker-bound checks.

Refs #158359.

* test(state): require initialized journal after v1 admission

The accepted production behavior intentionally initializes the canonical
agent_deletion_journal when admitting a valid pre-journal v1 store. Update the
v2026.7.1-2 fixture contract to require the complete canonical schema and assert
that the deletion-history owner reports known-empty history.

This expectation changes because journal initialization changed intentionally
in production, not to silence the check. Preserve the full schema comparison,
frozen fixture hashes, retained-data checks, and modern lost-history assertions.

Refs #158359.
2026-09-26 13:38:18 +00:00
Peter Steinberger bc3fdea248 fix(doctor): retire legacy transcripts that SQLite already supersedes (#158857)
Verify legacy event containment in the shared comparator, import only missing suffixes, and preserve conflicting originals with named event diagnostics. Record superseded transcript counts in existing archive receipts and keep clean recovery out of support reports. Preserve malformed-tail warning and protected-archive behavior.
2026-09-26 11:47:12 +00:00
Ayaan Zaidi 8fd72da7f2 feat(agents): let owners hand keys, config, and skill edits to their agent in chat (#158120)
## What Problem This Solves

Fixes: owners who ask their agent in chat to change a key, a config value, or one of their own skills get refused, sent to a dashboard, or told to file a Workshop proposal. Examples: "you can't post API keys here", switching the embeddings provider routed to the web-search wizard, only proposals for handwritten skills.

## User Impact

An owner can hand the agent an API key or token in chat, ask it to change config such as the embeddings provider, and have it edit skills they own. Session permission modes are unchanged: Full Access applies, restricted sessions ask.

- **Keys from chat.** Masked setup flows still keep keys out of model context and remain the default. If the user already pasted a key or token, the agent stores it in the shared secret store and points the config key at it with a `store` SecretRef instead of refusing. It never echoes the value back. The pasted message already reached the model provider and transcript; redaction covers later logs and output only, and the docs say so.
- **Existing store entries are never touched.** Each save inserts a new entry named after the config key plus a random suffix (`GATEWAY_REMOTE_TOKEN_9B139B5E231299BC`). Nothing is overwritten, revived, or deleted, and a new name can never match anything already pointing into the store, including a stale reference to a removed and purged entry. Replacing a key leaves its previous entry for `openclaw secrets store rm`. Rotating a key keeps its configured store provider alias, and the audit records the alias actually used.
- **Embeddings.** The agent now treats the memory embeddings provider, model, and key as `memory.search.*` config, not the web-search setup wizard.
- **Skills.** When the user asks, the agent edits skills they own directly: repository skill source, workspace `skills/`, project `.agents/skills/`, and configured extra skill directories. Bundled, ClawHub-installed, and plugin-provided skills are replaced by their owners' updates. For those, the agent says so and offers to capture the change as a Workshop skill.
- **Tone.** The "never request / paste credentials in chat" lines are gone from the `openclaw` tools and system-agent prompts. "Never echo secret values" stays, and so do factual pointers for flows that genuinely need a UI: channel sign-in, provider OAuth/accounts, and model onboarding.

No config option, schema, or protocol change. The Full Access permission-policy floor from the first revision moved to #158142 for its own security review.

## Why This Change Was Made

After #149870, approved config writes may target any path. What still blocked owners was model-facing text telling the agent to refuse credentials, plus the missing ability to store a chat-provided value anywhere but plaintext config.

`config_set_ref` gains an optional `secret` argument (read without trimming; only emptiness is checked). With it, the system agent:

1. registers the value for redaction when the proposal is built;
2. keeps the key's existing store provider alias when it has one;
3. sends one `secrets.writeForConfigRef` command to the SQLite state worker with the requester's live-authority guard. The host re-checks that guard at the worker's transaction and commit admission (`createSqliteWorkerWriteAdmission`), so a run stopped while the command is queued writes nothing. The transaction inserts a new row under a freshly minted `NAME_<16 random hex>`;
4. writes the ref through the existing config writer, which re-checks authority. If that write fails (before or after the writer commits), OpenClaw rereads the config and the error says the key was saved as `<NAME>` and whether the config key points at it. There is no automatic delete: another consumer may have linked the fresh entry, or the writer may have committed before failing;
5. the normal config reload picks up the new ref, since its id always changes.

Nothing new runs SQLite on the Gateway main thread.

<details>
<summary>Out of scope / follow-ups</summary>

- Found while proving this: in Full Access, after a delegated change applies, the next agent turn in the same chat fails with `SQLite database already belongs to another worker backend`. It reproduces on unmodified `origin/main` (`71bb516`) with a `logging.level` change followed by one more message. This PR does not fix it.
- Built-in provider sign-in and model onboarding stay handoffs; they own live verification of the active inference route.
- Other secret-store set/delete paths remain synchronous migration debt, as `worker-access.md` already records.

</details>

## Evidence

Real Telegram Test Server (Convex-leased userbot, fresh Gateway, QA mock provider, Full Access, tester is owner), first revision:

| | Screenshot |
|---|---|
| Token given in chat, applied with no approval prompt and no refusal (synthetic QA token) | ![User sends a remote Gateway token and asks to save it; the agent replies without refusing or asking for approval](https://github.com/user-attachments/assets/4f68f3db-225c-4047-984d-ed0cff79cd0c) |

### Final effects at this head

qa-channel scenario `system-agent-owner-trust` passes through a real Gateway and state worker. The Gateway is seeded with an unrelated `GATEWAY_REMOTE_TOKEN` entry, then:

1. A command-allowed **non-owner** (`bob`) sends the key. The `openclaw` tool is owner-only.
2. The **owner** (`alice`, Full Access) sends it.

Captured step details (redacted by the Gateway; the store ref id prints as `__OPENCLAW_REDACTED__`):

```json
{
  "nonOwnerEntryNames": ["GATEWAY_REMOTE_TOKEN"],
  "storedRef": { "source": "store", "provider": "default", "id": "__OPENCLAW_REDACTED__" },
  "storeEntryNames": ["GATEWAY_REMOTE_TOKEN", "GATEWAY_REMOTE_TOKEN_9B139B5E231299BC"]
}
```

- After the non-owner turn: only the seeded entry exists and `gateway.remote.token` is unset.
- After the owner turn: `gateway.remote.token` is a `store` SecretRef, the token is in its own minted entry (`GATEWAY_REMOTE_TOKEN_9B139B5E231299BC`), and the seeded entry's `updatedAt`/`updatedBy` are unchanged. No approval prompt was posted, and the token is absent from chat, config, and the store listing.

**Revoked request**, through the production worker (Node main thread, real broker, `writeSecretStoreEntryForConfigRef`). The requester's guard passes the caller's check, then reports the run stopped:

```text
seeded: [ 'GATEWAY_REMOTE_TOKEN (cli)' ]
revoked request rejected: requesting run is no longer active
after revoked request: [ 'GATEWAY_REMOTE_TOKEN (cli)' ]
owner request saved as: GATEWAY_REMOTE_TOKEN_F1657B971F691824
after owner request: [ 'GATEWAY_REMOTE_TOKEN (cli)', 'GATEWAY_REMOTE_TOKEN_F1657B971F691824 (openclaw)' ]
seeded value intact: true
```

Tests (each fails without the behavior it covers):
- production worker path (`secret-store-config-ref.worker.test.ts`, forked database-worker lane with the real broker): a chat secret gets its own minted entry beside a live `GATEWAY_REMOTE_TOKEN` without touching it; a requester revoked after the caller's check writes nothing;
- store kernel: a refusal at commit admission rolls the transaction back; each save mints a new `NAME_<hex>` and leaves the key's previous entry unchanged; a stale name whose entry was removed and purged still resolves to nothing after a chat save;
- operations: stored and referenced with no value in output or audit; authority gone before the store write writes nothing; a failed config write names the saved entry and leaves it in place; rotating a key keeps its configured store provider alias, and the audit records it;
- tool: proposes a store write without repeating the key, preserving leading and trailing whitespace.

Measured single-worker wall time per new or materially changed test file at this head (`node scripts/run-vitest.mjs run <file>`, local M-series; vitest Duration includes import and setup):

| File | Tests | Wall | Vitest duration |
|---|---:|---:|---:|
| `src/secrets/store/secret-store-config-ref.worker.test.ts` (new, database-worker lane) | 2 | 14 s | 2.05 s |
| `src/secrets/store/secret-store.test.ts` | 32 | 16 s | 13.37 s |
| `src/system-agent/operations.test.ts` | 43 | 18 s | 15.30 s |
| `src/agents/tools/system-agent-tool.test.ts` | 36 | 15 s | 12.89 s |

QA scenarios: `system-agent-owner-trust` (mock-openai) runs in about 27 s after build; `skill-owner-direct-edit-live` is live-frontier only and took about 3 min with `claude-cli/claude-sonnet-4-6`.

Wording pins for the removed lecture text were deleted. The focused store, worker, exclusivity, operations, tool, approval, and delegate suites pass. `node scripts/check-changed.mjs` passes every gate except core lint, which fails only on three files this PR does not touch (`server-chat-metadata-lifecycle.integration.test.ts`, `session-companion-ask.ts`, `app-sidebar-session-list-render.ts` over `max-lines` on the base); oxlint on the changed files is clean.

Security decision: a Full Access owner's pasted key goes to the Gateway-wide team store without a separate approval. Maintainer (@obviyus) accepted this in the PR conversation.

**Rotation with a second consumer**, through the production worker (Node main thread, real broker). A second consumer references the key's first entry before the next save lands; value fingerprints only:

```text
owner saves key #1 -> MODELS_PROVIDERS_OPENAI_API_KEY_6D96F6E92B59E935 (sha256:4a5c5a4aa8de)
second consumer now references MODELS_PROVIDERS_OPENAI_API_KEY_6D96F6E92B59E935 (e.g. linked while the next save is queued)
owner saves key #2 -> MODELS_PROVIDERS_OPENAI_API_KEY_4066F18ABAAE6903 (sha256:28bc4e3fe10d)
second consumer's entry MODELS_PROVIDERS_OPENAI_API_KEY_6D96F6E92B59E935 after rotation: sha256:4a5c5a4aa8de
unchanged: true
```

**Config write fails after the save, with a second consumer on the fresh entry**, through the production worker and the system-agent apply path (fingerprints only):

```text
owner result: Saved the secret as GATEWAY_REMOTE_TOKEN_6B68C031E571F81C, but could not point gateway.remote.token at it: config write failed after commit (rollbackStatus: not-restored). Retry, or remove the entry with `openclaw secrets store rm GATEWAY_REMOTE_TOKEN_6B68C031E571F81C`.
config gateway.remote.token: null
second consumer's entry GATEWAY_REMOTE_TOKEN_6B68C031E571F81C: sha256:09ae5b4fd36b
second consumer keeps the credential: true
```

**Stale reference to a removed and purged entry**, production worker for purge and save:

```text
purged rows: 1
stale ref GATEWAY_REMOTE_TOKEN after purge: SECRET_STORE_NOT_FOUND
chat save -> GATEWAY_REMOTE_TOKEN_8F698B5396990ADD resolves (value hidden)
stale ref GATEWAY_REMOTE_TOKEN after chat save: SECRET_STORE_NOT_FOUND
```

**Owned-skill edit with a live model.** New scenario `skill-owner-direct-edit-live` (live-frontier; run with `claude-cli/claude-sonnet-4-6`, subscription auth) passes at this head. It seeds workspace skill `qa-owner-greeting` replying `OWNER-GREETING-V1`, and the owner asks in plain words: "Please change my qa-owner-greeting skill so it replies OWNER-GREETING-V2 instead of OWNER-GREETING-V1." Captured result:

Skill file after the turn:

```markdown
---
name: qa-owner-greeting
description: Greets the owner with a fixed marker
---
When the user asks for the owner greeting, reply with exactly: OWNER-GREETING-V2
```

Agent reply: "Let me find the skill file. Done. The `qa-owner-greeting` skill now replies `OWNER-GREETING-V2` instead of `OWNER-GREETING-V1`."

The model edited the skill file in place and confirmed it; it did not refuse or file a Workshop proposal.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-26 16:20:43 +05:30
Vincent Koc 275d0d497b fix(setup): honor baseline skip-bootstrap (#115945)
* fix(setup): preserve baseline skip-bootstrap intent

Persist the existing skip-bootstrap option before initial workspace creation and keep explicit local defaults out of shared include files. Preserve configured values, user-authored files and include ownership on later baseline runs.

Related: https://github.com/openclaw/openclaw/pull/115945

* fix(core): preserve setup and subagent model intent

* chore(setup): preserve original PR ancestry after scope split

Keep the reviewed current-main setup reconstruction as the complete candidate tree. Requester inheritance is already supplied by PR149036; the separate model-selection-source proposal remains tracked in issue158760. Retain the original PR commit as a parent instead of rewriting its history.

Related: https://github.com/openclaw/openclaw/pull/115945
Related: https://github.com/openclaw/openclaw/issues/158760
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-09-26 18:15:06 +08:00
Peter Steinberger 9679269757 fix: Bun update repair launches Node maintenance commands (#158195)
* fix: Bun update repair launches Node maintenance commands

* test: satisfy finalizer command assertion lint
2026-09-26 02:03:18 -07:00
Patrick Erichsen 2d5c68187a fix(plugins): allow reloads to wait for long-running work (#158688)
* fix(plugins): allow reloads to wait for long-running work

* test(plugins): await reload drain readiness without polling

* test(sessions): await resource retirement before reopening cleanup fixtures
2026-09-26 08:08:14 +00:00
Peter Steinberger cd8a86e83a refactor(commands): deslop commands (#158487)
* refactor(commands): deslop commands

Consolidate command orchestration, Doctor migration traversal, status projection, and migration selection while preserving CLI contracts. Repair malformed legacy media rows and align inference owner fingerprints with runtime artifact selection.

* fix(commands): handle duplicate session lifecycle keys

Normalize session keys once before describe and mutation so repeated arguments cannot cause false partial failures. Preserve public error formatting and optional auth fields while resolving the final cleanup lint findings.

* fix(plugins): keep artifact identity on lightweight runtime state

Read the existing bound artifact preference through the canonical runtime-state getter so extracted maintainer wrappers do not import runtime preparation and logging. Preserve the current writer, selection policy, and wrapper inventory.
2026-09-26 00:33:06 -07:00
Peter Steinberger c4257984ae fix(cli): defer inference runtimes until command execution (#158624)
* fix(cli): defer inference runtimes until command execution

* test(cli): extract inference command test harness
2026-09-26 03:50:34 +00:00
Peter Steinberger 91b8f103cb refactor: retire the TaskFlow Webhooks plugin (#158225)
* refactor: retire the TaskFlow Webhooks plugin

* fix(doctor): preserve restrictive plugin allowlist retirement

* test(update): prove sole plugin policy survives retirement

* chore(webhooks): remove retired plugin label mapping

* test(plugins): consolidate retired plugin warning cases

* fix(doctor): preserve permitted plugins during retirement

* test(update): verify preserved plugin policy and evidence

* fix(testing): retain upgrade policy publisher dependencies

* test(update): isolate inherited channel discovery state

* ci: refresh Webhooks checks after main QA reference repair
2026-09-25 20:29:15 -07:00
Peter Steinberger d780fdc672 fix(update): back up every database before migrations and restore them on rollback (#158163)
* fix(update): preserve databases across failed migrations

Include unregistered agent databases in consistent backups and retain database
snapshots with package recovery artifacts before Doctor migrations. Restore only
when recorded write fingerprints still match, preserving displaced migrated
files and refusing silent rollback over unaccounted writes.

Keep pre-Doctor install failures on the existing package recovery path.

Closes #157846
Refs #145169 #156917 #157107 #157077

* fix(update): drain captured database aliases before rollback

* fix(update): isolate database write receipts from orchestration

* fix(update): preserve schema-neutral package rollback

* refactor(update): separate candidate validation and inspection cleanup
2026-09-26 02:30:17 +00:00
Josh Lehman 8c29090d0a fix(update): keep runtime transactions out of plugin rehearsal (#158338)
Refs: oc-cbb
2026-09-25 17:17:41 -07:00
Peter Steinberger 31cd888739 fix(update): keep config field details and distinguish read failures from invalid config (#158455)
* fix(update): retain config refusal details and distinguish read failures

* fix(update): retain config path in validation guidance

* test(update): construct config cases without map spreads
2026-09-26 00:13:27 +00:00
Peter Steinberger b31c0ac9e3 fix(update): record terminal failures before offering reports (#158354) 2026-09-25 15:38:09 -07:00
Peter Steinberger 2a1402cd3e fix(startup): keep legacy state repair in Doctor (#151025)
* fix(startup): keep legacy state repair in doctor

Separate current-state startup readiness from explicit Doctor migrations.
Preserve current config recovery, quarantine, device identity checks,
lease fencing and updater completion ownership.

Remove automatic startup migration/checkpoint and node-host import paths.
Keep shipped read-only context and roster projections unchanged.

* test(doctor): align proof callers with repair ownership

Keep survivor fixture setup in caller order and select the shared Doctor
flow separately from the channel-specific proof. Include the complete
isolated diagnostics dependency closure.

Prove ordinary startup preserves legacy directories before explicit
Doctor repair, and await SQLite worker closure before test cleanup.

* test(startup): verify index repair through gateway maintenance

* test(doctor): align cutover fixtures with state owners

Reacquire the database after Doctor retires its generation, retain real session history for startup refusal, and keep pending reads at their actual owners. Distinguish the reused readonly reader from independent snapshot-token children and verify every child settles.

* fix(doctor): preserve image activation and published migration receipts

Run the shared noninteractive Doctor owner before default and Compose Gateway
activation so retained Docker volumes keep their published upgrade path while
ordinary Gateway startup stays readiness-only. Preserve root selectors and
settle interrupted repair before executing the original command.

Retain the path-wide tombstones emitted by the published restart-sentinel
importer, including consumed notices, and validate completed source decisions
before retiring recreated inputs. Add the root-image activation lane and causal
receipt coverage without introducing a schema, option, or second importer.

* test(docker): preserve release state pairs in upgrade proof

Use the existing synthetic v2026.9.2 corpus instead of combining a July shared database with a later agent schema. Preserve its deletion journal, registry, both transcript payloads, paired backups, and unsafe-state controls. Register the two shell-launched helpers with Knip.

* test(docker): normalize persisted schema snapshot rows

Compare node:sqlite schema rows using the same plain-object representation as the saved JSON preimage. Keep strict schema, row, and value-type assertions intact.

* fix(models): retain discovered models after refresh failures

Record successful legacy catalog results at the producer boundary so unavailable refreshes retain the accepted inventory. Preserve explicit outcomes, advisory SDK fallback behavior, and first-discovery starter policy.

* fix(models): preserve skipped catalog outcome semantics

Mark bundled static, configured, and advisory catalog projections with
explicit empty outcomes so legacy success inference cannot promote them
to observed account inventory. Preserve live outcomes and helper types.

Keep exact auth provenance histories and move existing fixture/policy
code into focused owners where required by the line-cap ratchet.

Validation: 447 producer and sibling cases, 56 shared self-hosted cases,
95 auth/policy cases, causal missing-outcome failures, maintained checks,
and independent review.

* test(plugin-sdk): keep discovery loader types acyclic

Move the shared loader type into a leaf consumed by both discovery
contract helpers. Preserve its public provider-test-contracts export
without a child-to-parent type import cycle.

Validation: maintained Madge check reports zero cycles; core, all core
test graphs, extension test types, lint, formatting and independent
review pass. Runtime behavior and previous catalog proof are unchanged.

* fix(plugin-sdk): mark generated static catalogs explicitly

Keep the generated non-live, non-strict catalog adapter from claiming
successful acquisition for manifest or configured rows. Preserve null,
errors, strict and custom callbacks, static catalogs, and public types.

Validation: three existing controls fail before the correction; all49
owner and sibling cases pass afterward, with types, lint, line caps and
fresh independent review clean.

* test(gateway): cover restart import during state retirement

Exercise canonical database close while a legacy notice read is paused. Verify admission rejection, retained canonical and source bytes, no migration receipt, and joined maintenance custody without changing the accepted sidecar-stop drain contract.

* fix(test): drain sharing fixtures before removing state

* test: bind retirement regression to its own worker

* docs(docker): clarify automatic Doctor activation

* test(doctor): keep readiness fixture runtime private

* test: stabilize shared skill watcher fixture roots

(cherry picked from commit 15606be10e)

* perf(tooling): share indexed scope parsing for artifact scans

(cherry picked from commit 6e6eef9f5b)

* fix(team-reports): use source owners in scheduler tests

The source barrel retired in #157819, but the scheduler tests still imported
it, breaking the extension test typecheck on main. Import the Discord and
GitHub owners directly, matching the production caller.

Validated the original TS2307/TS7006 failure, the corrected extension type
graph, all 36 scheduler tests, changed checks, and independent P2 review.

(cherry picked from commit 7c4866c73b)

* test(install): isolate global npm configuration in version fixtures

Use a controlled absent global config inside the fixture home so the
release helper does not query the deliberately narrow npm stub. Keep
predecessor selection, fresh-install behavior, and expected exits intact.

(cherry picked from commit 0a9eefc76c)

* test(docker): verify the complete image activation entrypoint
2026-09-25 13:43:40 -07:00
Peter Steinberger cc1775a6b9 fix(update): report scheduler policy before discovery (#158301) 2026-09-25 20:18:07 +00:00