* docs(automation): rename scheduled-tasks feature wording to Automations
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhJ8EiMXue6ADLmHfb7FL6
* docs: regenerate docs map and add Automations glossary entries
* docs(templates): follow renamed automations-vs-heartbeat anchor
* docs(automation): fix markdown formatting drift
* docs(automation): teach the canonical automations tool and sync the copied heartbeat default
Review follow-ups: normal instructions use the automations tool with cron as
an explicit compatibility alias; every verbatim copy of the default heartbeat
prompt matches the new shipped text from the strings PR.
---------
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(ui): rename the Memory Palace browser to Memory Wiki and document it
* refactor(memory-wiki): drop the old memory-palace module files
* docs: refresh generated docs map
* test(ui): align dream-diary hub-tab assertion with the wiki sub-tab id
* docs: describe memory wiki clustering behavior accurately
* docs(memory-wiki): record the wiki.overview rename decision at the registration site
* test(ui): query the Agents channels hub tab by tab role after the hub-tabs refactor
* feat(gateway): add loopback locality controls
* fix(gateway): keep loopback auth delays enforced under concurrency
The pending-timer cap let an attacker park cheap failures in every slot and then guess without penalty. Delays now key off a per-key deadline, so parallel guesses wait out the same escalating penalty and are still bounded by the max delay.
* fix(gateway): share one loopback penalty timer per key
Concurrent failures on a key now share a single timer and deadline instead of allocating one per in-flight request. Also corrects the security doc: the delay raises the cost of repeated guessing from one source, but credentials are compared before the failure response is delayed, so it is not a defense against parallel fan-out.
* docs(gateway): record why loopback delay stays post-verification
* docs: refresh generated docs map
* docs: refresh plugin SDK API baseline
* test: update loopback locality CI expectations
* fix(codex): restore connected apps for token-authenticated runs
* fix(codex): keep app inventory protocol types private
* fix(codex): align native runtime with Codex 0.146.0
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): clean up latest app-server integration
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): keep internal protocol types private
* fix(ci): repair current main Codex landing gates
* fix(ci): format inherited code mode matrix
* fix(codex): reconcile native app-server contracts with main
Prepare a verified GitHub-hosted mainline merge while preserving the reviewed Codex 0.146.0 fixes and canonical OpenAI authentication.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): keep QA evidence in its owning plugin
Resolve the current-main Code Mode test rename without resurrecting the retired core test path.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): enforce canonical OpenAI app-server auth
Reject retired provider aliases without runtime compatibility, direct operators to the doctor migration, and remove the redundant OpenAI API-key predicate.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* chore(codex): reconcile latest main dependency graph
Preserve current main dependency changes while preparing the original Codex PR for an ancestry-preserving signed mainline merge.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): unify bundled Codex 0.146 runtimes
Keep the ACP adapter on the same 0.146.0 Codex release as the managed runtime, remove obsolete 0.145.0 platform artifacts and unused semver compatibility, and preserve the latest main dependency upgrades.
Co-authored-by: Steven Lee <stevenlee@openai.com>
---------
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* docs: add local speech TTS setup
* docs: clarify local HTTP release requirement
* docs: require Speech Swift v0.0.23
* docs: use released speech-core Windows package
* docs: use current TTS config in local recipes
Co-authored-by: ivan-digital <root@ivan.digital>
---------
Co-authored-by: ivan-digital <root@ivan.digital>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(channels): make channel health reflect inbound ingress, not just the transport
`connected` is a transport signal, so a channel holding a healthy socket while its
durable ingress queue is unavailable evaluated as `health: healthy` and admitted
nothing. On a production gateway that hid 26+ hours of completely dead inbound Slack
behind `connected, bot:config, app:config, health:healthy`; outbound kept working,
which is what kept the transport looking fine.
Add inbound admission as its own health dimension rather than overloading `connected`
(deliberately tri-state since 30fda068aa, and 17 of 27 channel plugins depend on
absent meaning "no transport signal"). The shared ingress monitor now rethrows a
typed ChannelIngressUnavailableError when it cannot open its durable queue, the
channel supervisor records that as `ingressUnavailable` on the account, and
`evaluateChannelHealth` reports `ingress-unavailable` ahead of every lifecycle
window. Absence stays "unknown", never "fine", so socketless and simply quiet
channels are untouched; no traffic-staleness heuristic is introduced.
The health monitor deliberately does not restart such an account. A denied or
unusable ingress queue is a capability/config failure that a restart cannot fix, and
the channel's own bounded backoff ladder already tried. Today that case instead loops
at the 10-restarts-per-hour cap forever, so this removes a restart treadmill rather
than adding one.
* fix(channels): keep automatic recovery for a dead-ingress account
The health-monitor skip latched a transient queue-open failure into a permanent
inbound outage: ingressUnavailable is only cleared by a later start, and skipping
the restart meant that start never happened. Report the dimension and name the
restart reason instead of suppressing recovery.
* fix(channels): scope the ingress dimension to running accounts
Shadowing not-running would have made readiness flap during the supervisor's
documented restart-backoff grace. The blind spot the dimension exists for is a
running channel with a live transport and dead inbound, so evaluate it there and
leave stopped accounts on their lifecycle reason. Also applies oxfmt.
* fix(channels): keep the ingress reason and give readiness its own backoff grace
Two review cycles pulled in opposite directions on the same bounded window: the
health policy must keep the ingress cause in the not-running state a failed start
actually lands in, while readiness must not flap during restart backoff. Put each
in its owner -- the policy states the truth, and readiness extends its existing
restart-handoff grace to the ingress reason. Once the ladder stops setting
restartPending, the account stays red instead of hiding dead inbound.
* style: reshape the readiness backoff predicate for oxfmt
* fix(ci): regenerate the docs map and drop an unused ingress export
The new health.md section needs docs/docs_map.md regenerated, and knip flagged
CHANNEL_INGRESS_UNAVAILABLE_CODE as an unused production export -- it only has
callers inside its own module.
* feat(plugins): catch code-mode drift between catalogs sharing one model
Adds a contract test that groups bundled catalog rows by shared upstream
model and requires every row in a group to declare compat.codeMode once any
sibling does. Rows sharing a model id group automatically; rows under
different ids opt in with the new manifest-only `upstreamModel` marker.
Moves the kimi catalog into its manifest so the scan can see it, and records
the tier reseller catalogs were silently missing as explicit "capable".
* docs: regenerate docs map for the shared-model code-mode section
* feat(memory): add provenance and recall metadata to the memory index
* feat(memory): provenance-gated promotion and capture hygiene
* feat(dreaming): LLM consolidation with deterministic gates, on by default
* feat(active-memory): deterministic recall lane with escalation default
* feat(memory): user model file and standing intents
* docs(memory): document the memory architecture
* fix(memory): live-QA fixes — metadata writers, provenance classes, intent scope, claim accumulation
* feat(plugins): deliver sessions.changed to plugin services
* docs: regenerate docs map
* refactor(clickclack): split reconcile scheduler and history formatting out of the discussion service
* style: format discussion service
* feat(plugins): mirror local coding sessions to a remote Beam receiver
* fix(plugins): satisfy static gates for the Beam mirror seam
* fix(plugins): import the config type from the narrow contracts subpath
* fix(plugins): require catalog consent and loopback-only plaintext for the Beam mirror
* refactor(memory-core): remove orphaned shadow trials
* refactor(qqbot): migrate direct voice upload formats
Release note: QQBot configs using voiceDirectUploadFormats now migrate through openclaw doctor --fix to audioFormatPolicy.uploadDirectFormats at root and account scope. Existing nested uploadDirectFormats values win conflicts, and runtime reads only the nested policy.
* refactor(feishu): migrate tools base alias
Release note: Feishu configs using tools.base now migrate through openclaw doctor --fix to tools.bitable at root and account scope. Existing bitable values win conflicts, and runtime accepts only the canonical key.
* refactor(extensions): remove dead runtime state
* chore(config): refresh bundled channel metadata
* refactor(codex): keep realtime fallback type private
* test(ci): align QA compatibility scenario count
* feat(tools): per-model code-mode capability flags and auto master-switch tier
* feat(anthropic): flag claude-sonnet-4-6 as code-mode preferred
* revert(anthropic): drop claude-sonnet-4-6 from the code-mode preferred set
* test(anthropic): type the manifest compat field in the catalog contract test
* fix(anthropic): carry catalog compat onto hand-built forward-compat model rows
* refactor(slack): retire inline interactive directives
Release note: Slack configs using channels.slack.capabilities.interactiveReplies, including per-account settings, are removed by openclaw doctor --fix. Slack-only [[slack_buttons:...]] and [[slack_select:...]] markup is no longer parsed; emit typed presentation buttons and selects instead.
* docs: refresh Slack docs map