* fix(plugin-sdk): make the API baseline hash path-free and surface-reachable
Manifest hashes now cover only surface-reachable, path-independent facts.
Rewrite closure from whole-file/path-keyed traversal to declaration-granular reachability with fail-toward-recall fallbacks and taint-tracked cycles.
Exclude source paths from the committed hash and split declaration printing into api-baseline-declaration-print.ts.
* fix(plugin-sdk): close side-effect and namespace-import gaps in baseline closure
Address ClawSweeper findings:
- Traverse side-effect imports before collecting globals.
- Normalize repo-owned namespace import types.
* refactor(plugin-sdk): rebase precision closure onto the JSONL contract
* fix(codex): report harness context window as session contextTokens
Codex app-server reports model_context_window per turn. Carry it through the projector into the run result meta so session rows show the real window instead of the catalog's standard-tier input cap (272k vs 1M for gpt-5.6 models).
* improve(ui): compact chat context popover
Inline stat rows replace boxed tiles; zero-value cost rows and the whole cost section when empty are omitted; provider/model provenance lines are removed because the footer already shows the model; and the popover is narrowed to 300px.
* refactor(codex): split attempt-result assembly out of event projector
* fix(codex): seed attempt context window from startup binding
App-server v2 turn/started omits the core model_context_window, so thread/tokenUsage/updated is the only live carrier. Seed usage-less attempts from the retained startup binding rollout/session window so session metadata cannot regress to the catalog fallback.
* fix(codex): prefer native startup context window
Persisted session contextTokens has no source provenance and may contain the catalog fallback. Keep the minimum window for the conservative rotation fuse, but seed the projector from the native rollout when it is available.
* chore(plugin-sdk): regenerate api baseline (new format)
* revert(gateway): "prevent restart replay after final delivery" (broke 5 CI jobs)
Record channel delivery custody before recipient-visible sends so restart recovery cannot duplicate accepted finals.
Ambiguous legacy markers now fail closed with a visible interruption instead of blind replay.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* refactor(sessions): collapse session accessor aliases
Declaration ownership moved to defining modules; no name or signature changed.
* test(auto-reply): remove stale session hint import
* feat(skills): repair used skills in turn
* fix(skills): bind repair to used skill receipt
* fix(skills): preserve explicit repair review
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Teach the semantic reviewer to improve skills the agent actually used, keep review input provider-bound, and preserve bounded deterministic retries.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(workers): persist placement terminal failures
* fix(workers): refresh placement protocol clients
* refactor(workers): isolate error formatting
* fix: integrate cloud terminal state with current main
* chore(plugin-sdk): refresh API baseline
* refactor(ui): inline one-use cloud terminal-reason banner helper
Keeps the Control UI startup JS bundle inside its 317 KiB gzip budget
(the helper + type-only import tipped it by 16 bytes).
* refactor(ui): trim terminal-reason lookup to type-erased optional access
Recovers the last gzip byte of the Control UI startup budget
(324609 B vs the 324608 B limit).
* feat(ui): add people session sorting
Offer People sorting in the Control UI session sidebar when the Gateway reports multiple session-sharing identities.
* fix(ui): restore sidebar translation dependency
* fix(ui): preserve session sort ordering contracts
Fold the writer-claim fence into the four sync write ops at their
definition sites, collapse the logical-layer fence wrappers to plain
re-exports, delete the session-accessor.sqlite middle barrel (the only
unfenced escape hatch), and retarget its 26 importers to the focused
defining modules. replaceSessionEntrySync intentionally stays unfenced:
its two production callers own their freshness guards and its return
carries no rebound signal. Net -106 production LOC, behavior-neutral.
Part 1 of the session-accessor dual-layer collapse.
* fix(security): unify secret-redaction and SSRF policy ownership
Memory-host errors now redact through the canonical redactor (payment/card/CVV
coverage included) via the existing core facade instead of a stale local
pattern table; ACP error redaction is wired through a single barrel so the
injected canonical redactor no longer depends on module load order, and the
acp-core fallback table shrinks to the minimal standalone set (structured
auth-header patterns proven load-bearing stay). The memory-host SsrFPolicy
structural copy is deleted in favor of the canonical src/infra/net/ssrf.ts
type re-exported through the network facade.
* fix(build): keep memory-core doctor closure execa-free
Import the canonical redactor directly from src/logging/redact.js instead of
the openclaw-runtime-io facade (which reaches execa through the full runtime
graph), and regenerate the plugin SDK API baseline for the intentional
canonical-SsrFPolicy surface change.
* fix(security): merge operator redact patterns with defaults in injected redactors
ClawSweeper found that ACP injected the general redactor, where nonempty logging.redactPatterns replace the built-in provider-token patterns. Use the tool-payload redactor for ACP and memory-host error formatting so operator patterns extend defaults and redaction remains forced for these security boundaries.
* refactor(channels): flatten channel turn dispatch naming
* docs(plugin-sdk): narrow inbound reply compat guidance
* docs(channels): point stale references at turn defining modules
* fix(channels): preserve dispatch contracts after flattening
* chore(plugin-sdk): ratchet surface budgets after flattening
* chore(channels): ratchet removed export collisions
* fix(plugin-sdk): restore inbound reply compat exports
Restore eight still-existing legacy callable re-exports from canonical SDK seams and cover the deprecated package subpath with a table-driven compatibility test.
Raise the public export, callable export, and deprecated export budgets by exactly eight; the three maintainer-authorized zero-consumer symbols remain removed.
* test(channels): split channel turn kernel coverage
Replace the oversized kernel test with independently mocked delivery, pipeline, and finalize suites, preserving all 51 tests while removing the max-lines suppression and stale ratchet entry.
* chore(plugin-sdk): refresh inbound reply API hash
* fix(ci): align channel turn review fixes
Restore the test-local DeliveryResult type removed during the split.
Ratchet the public export, callable export, and deprecated export budgets by exactly seven: six channel-inbound plus one channel-outbound legacy re-export.
* fix(openai): describe personality as the canonical GPT-5 style toggle
The shipped config-schema description told operators and models to prefer
agents.defaults.promptOverlays.gpt5.personality, a retired key that config
validation rejects and doctor deletes. plugins.entries.openai.config.personality
is the only live reader (src/agents/gpt5-prompt-overlay.ts).
* docs: align prompt-overlay, truncation-notice, and pruning docs with shipped behavior
- teach plugins.entries.openai.config.personality as canonical; retired
agents.defaults.promptOverlays noted as rejected/migrated
- replace nonexistent agents.defaults.bootstrapPromptTruncationWarning with
prose describing the built-in always-on notice
- reword session-pruning internal constants as built-in behavior, name the
real contextPruning config surface
- delete stale/orphan pages (path3 harness for a never-committed script,
superseded swarms plan, landed path3 artifact-family scoping note)
- fix dead paths in reference/test.md and concepts/typebox.md
* docs: describe the embedded truncation notice as compact
The embedded runtime injects buildBootstrapPromptWarningNotice, which
deliberately omits file names and sizes; per-file diagnostics stay in
/context, status, and logs. Addresses ClawSweeper P2 on #121324.
* docs: doctor migrates the retired personality key instead of removing it
Main landed #121346 mid-flight: doctor --fix now moves
agents.defaults.promptOverlays.gpt5.personality into
plugins.entries.openai.config.personality when unset.
Telegram now treats disabled tool progress as authoritative even when /verbose is enabled. Enabled progress and durable/final messages retain existing behavior.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Jason O'Neal <jason.allen.oneal@gmail.com>
Co-authored-by: 徐金城0668000897 <xu.jincheng@xydigit.com>
Gate reuse on the watcher-owned snapshot version and persisted entry manifest, while keeping safe paths process-owned and reconciling only changed skills.
Cache config fingerprints by object identity and reset them at the applied-config lifecycle owner.
* perf(sessions): avoid full-store single patches
Single-session non-label patches no longer materialize the whole session store. Label uniqueness remains store-wide, and stale aliases created while queued are still rejected.
* fix(build): refresh plugin SDK API baseline
Current main's generated manifest lagged merged Plugin SDK surface changes; canonical refresh restores the baseline check.
Use a manifest-first inventory with independent coverage for manifest-only bundled capabilities.
Retire the undocumented thread-ownership plugin while Doctor removes stale references.
Document Talk voice and persist only provider-scoped voice selection.
Closes#121353