* refactor(extensions): remove dead QA and utility exports
* refactor(extensions): trim Matrix QA internal exports
* chore(deadcode): refresh extension export baseline
* chore(ci): reconcile deadcode and LOC baselines
* chore(deadcode): refresh baseline after main advance
* chore(deadcode): refresh baseline after main advance
* refactor(plugins): keep channel snapshot type private
* fix(ci): align Linux deadcode baseline
* fix(extensions): make indexed access explicit across channel plugins
Transport-payload-safe burn-down: malformed Telegram/Discord/QQ/LINE
and sibling channel input keeps existing skip paths; no synthesized
fields, no new throws in delivery loops. Zalo escape sentinels preserve
literal matches instead of undefined replacements.
* fix(extensions): make indexed access explicit across provider and memory plugins
Stream and model iteration, tool-block guards, capture guards, and
sparse accumulators; singleton model reads carry named invariants.
* fix(extensions): make indexed access explicit across tooling plugins, flip the extensions lane
Remaining plugins (oc-path, qa-lab, browser, logbook, and siblings) plus
the tsconfig.extensions.json flag flip. Cleanup: logbook sampleFrames
NaN index at max=1, QA retry clamp at non-positive attempts, dead Canvas
probe and OpenShell no-op slice removed, twitch test setup leak excluded
from the prod lane.
* refactor(plugin-sdk): expose expectDefined via a focused SDK subpath
Extensions imported @openclaw/normalization-core directly, crossing the
external-plugin packaging boundary (it only worked because the runtime
builder bundles undeclared workspace helpers). expect-runtime joins the
canonical entrypoints JSON, generated exports, API baseline, docs, and
subpath contract test; all 78 extension imports now use the SDK seam.
Two scanner-shaped locals renamed for review-bundle hygiene.
* chore(plugin-sdk): raise surface budgets for the expect-runtime subpath
One new entrypoint with one callable export, added intentionally as the
packaging-honest seam for extension invariant helpers.
* feat: correlate native search outcomes in audit history
Metadata-only audit ledger for agent runs and tool actions in the shared
state DB: stable event identity, closed action/status/error vocabularies,
one-way-hashed tool-call ids, never-inferred terminal outcomes for native
web-search (explicit completed/failed only; otherwise unknown), bounded
retention, audit.list gateway RPC and openclaw audit CLI. Squashed from
the 82-commit audit stack for replay onto current main.
* feat(audit): add audit.enabled config gate (default on)
The metadata-only audit ledger records by default: an audit trail enabled
only after an incident cannot explain the incident, and the rows are
strictly less sensitive than the transcripts every install already
stores. audit.enabled=false stops new writes at the gateway subscription
seam; audit.list and openclaw audit keep serving existing records until
they expire. Documented in the configuration reference, protocol page,
and CLI reference.
* fix: repair full-matrix CI findings after rebase
- break the dynamic-tools/dynamic-tool-execution import cycle by
extracting resolveCodexToolAbortTerminalReason into a leaf module
- restore main's session-worktree protocol exports lost in the
index.ts auto-merge
- register the audit event writer worker as a knip entry point
- docs table formatting; subagent wait-cancellation test scoped to its
audit intent (outcome + timing) and advanced past main's new
lifecycle-timeout retry grace
* fix(acpx): detect wrapper orphan on any PPID change, not just init reparenting
The codex / claude adapter wrapper's orphan watcher (emitted by
buildAdapterWrapperScript) skipped cleanup when `process.ppid !== 1`,
intending to wait for the kernel to reparent the orphaned wrapper to
PID 1 (init). This only works on bare-metal hosts without an active
user-session manager.
On systemd-managed deployments (EC2 user services, most container
runtimes), an orphaned process is reparented to the user-session
manager or container init — not to init itself. The watcher therefore
never fires, and when the gateway exits, the adapter wrapper survives
and holds its child process group (codex-acp.js + native binary)
running indefinitely.
Real-world symptom: each gateway restart accumulates 3-process trees of
leftover codex adapters. Subsequent ACP spawns then contend with these
orphans, the main event loop is starved by acpx-runtime reap attempts,
and new sessions stall at "waiting for tool execution" for minutes.
Fix: trigger orphan cleanup as soon as PPID changes from the recorded
original, regardless of what the new PPID is. The killChildTree path
already covers process-group cleanup via `kill(-pid, SIGTERM)`, so
once the watcher fires, grandchildren are reaped correctly.
Adds a regression test asserting the wrapper template does not
re-introduce the `process.ppid !== 1` guard.
* test: document maturity ref handoff
---------
Co-authored-by: t2wei <t2wei@me.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
* fix(acpx): consume acpx 0.11.1 model capability errors
* fix(acpx): refresh npm shrinkwrap for 0.11.1
* test: include workflow checks in tooling plan
Move ACPX gateway identity and live process leases into SQLite-backed plugin state. Add doctor migration for legacy runtime state and preserve process cleanup identity checks across the storage move.
Fix live model inference edge cases across provider streaming, model switching, outbound delivery, and gateway tool resolution.
Includes live/provider issue fixes and leaves #89100 explicitly partial for the remaining FM-2 group routing case.
Deliver same-session channel replies directly while preserving stale-reply guards.
The fix bypasses the announce decider only when the requester and target are the same source channel, carries reply baselines into fire-and-forget follow-up delivery, and keeps history reads best-effort so timeout-zero sends still dispatch. It also includes focused regression coverage for delayed same-session replies, stale snapshots, retry timer caps, and the current strict-null/package-boundary blockers fixed while preparing the PR.