Keep cron delivery help and automation docs explicit that --channel selects a channel plugin, not a per-conversation channel identifier.
Fixes#124646
Punchcard-Session: clear-timber-orchard-n1
* fix(cron): honor failure alert thresholds
Per-run Gateway announcements bypassed threshold, cooldown, and opt-out policy. Make the scheduler the sole owner of failure notification decisions.
* fix(cron): preserve safe failure details
Keep trusted failure detail proof on the scheduler-authorized transport and remove the obsolete Gateway event-context handoff after the ownership consolidation.
* test(cron): assert alternate failure route isolation
* fix(gateway): harden hook admission and shutdown
Flush structured 413 and 408 hook responses before closing oversized or timed-out request sockets, and reject deferred wake requests that target an explicit session.
Direct Gateway close now marks startup and readiness as draining immediately and attempts every HTTP listener shutdown before reporting an incomplete close.
* test(gateway): model request destruction in fuzzing
Give the HTTP request fuzz double the IncomingMessage destroy contract exercised after 413 and 408 responses finish.
* fix(gateway): preserve response and shutdown bounds
Route installed webhook body-limit failures through the shared response-first close owner and require complete Feishu 413/408 responses before terminal connection closure.
Retain the current-main grace bound for agent-harness disposal so one stuck harness cannot block listener teardown.
* test(telegram): model response-close request cleanup
Keep the slow-body request alive through response finish, then assert cleanup when the mock response transport closes.
* feat(cron): enable automation triggers by default
Condition watchers, script payloads, and stream schedules were gated behind
cron.triggers.enabled=false, so the capability shipped dark and the automations
tool told the model to call it unsupported.
The gate did not buy what its warning implied. cronJobUsesToolRuntime treats
agentTurn, script, and trigger.script identically for tool policy, and jobs are
capped to the creating agent's allowlist via creatorToolAllowlist -- but an
agentTurn cron job was never gated, so unattended recurring exec with that same
creator-capped authority was already reachable. The gated paths are strictly
tighter: a condition gate gets 30s, 5 tool calls, 16KB state and a 30s minimum
interval, where an agentTurn has no such budget. Sandboxing already applies to
trigger scripts, which resolve sandbox context and redirect the workspace when
access is not rw.
Absent config now means enabled; an explicit cron.triggers.enabled: false still
disables every surface it disabled before, and the error text names the opt-out
instead of telling operators to turn something on. No new config key, no
migration.
Docs: reword the trigger warning for default-on while keeping the unattended
execution note, and record the new default in the configuration reference.
* test(cron): refresh prompt snapshots for default-on triggers
Trigger, stream-schedule, and script-payload surfaces are now advertised in the
automations tool description by default, so the committed fixtures drift.
This also records the cost: dynamicToolsJson grows 49,477 -> 52,541 chars and
the snapshot total 76,861 -> 79,925 (~766 rough tokens per prompt). That is the
price of no longer dark-shipping the capability.
* test(mcp): expect trigger surfaces by default in the tools bridge
The MCP tools bridge mirrors the scheduler gate, so an absent cron.triggers
config now advertises the trigger surface. Explicit false still narrows it and
explicit true still widens it; both assertions are unchanged.
The cron model picker help and the automations docs now say what
operators otherwise learn by surprise on the bill: summaries, triage,
and classification jobs run well on a lighter model, and --fallbacks
covers escalation. Copy-only change; pnpm ui:i18n:verify green, no
baseline drift.
Skill and hook status now preserve OS incompatibility when `always` bypasses runtime requirements, matching existing loader behavior and clarified documentation.
Refs #122271 and #122331.
* fix(agents): remove stale media completion reply mechanics
Make generated image, music, and video completion wakes follow the current tool-agnostic visible-reply contract, preserving every structured attachment without NO_REPLY or transport-specific instructions.
Refs #121933.
* test(agents): remove stale media helper
Delete the unused assertion helper left behind by the table-driven generated-media completion coverage.\n\nRefs #121933.
* test(tooling): wait for profiler descendant pid
Require the PID file to contain a valid positive process ID before asserting profiler descendant cleanup, closing the create-before-write CI race.\n\nRefs #121971.
Keep raw commands, paths, and provider errors out of ordinary chat while preserving explicit raw diagnostics and structured admin history.
Default command progress is status-only; `/verbose full` and `commandText: "raw"` retain diagnostic detail.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* [AI] fix(plugins): warn when registerHook uses a typed hook event name
api.registerHook registers into the legacy internal-hook path, while typed
lifecycle events (before_tool_call, message_received, ...) are dispatched
exclusively by the typed hook runner. Registrations under typed names
silently never fired since #117372 moved the write to legacyInternalHooks.
Emit a registration diagnostic pointing to the public api.on(...) API so
plugin authors see the no-op at load time instead of trusting a false
"loaded".
Related to #116965
Co-Authored-By: deepseek-v4-flash <noreply@anthropic.com>
* [AI] fix(plugins): point registerHook comment at public api.on API
Condense the inline comment in createToolHookRegistrars and replace the
internal registerTypedHook migration reference with the public api.on(...)
API, matching the emitted warning and hooks docs. Behavior and tests
unchanged.
---------
Co-authored-by: deepseek-v4-flash <noreply@anthropic.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
* 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>
* feat(cron): bind agent turns to current sessions
* feat(commands): add loop chat command
* test(cron): cover session defaults and loop commands
* docs(cron): document current defaults and loops
* fix(commands): scope /loop status and stop by conversation name tag
* fix(commands): widen /loop conversation tag to 48 bits
* fix(commands): include disabled jobs in /loop status and stop
* docs(cron): regenerate docs map
* test(cron): split session-target default tests to satisfy max-lines
* docs: correct retired cron/audit config keys, cron failure-alert default, memory recall default, and tool-search telemetry claims
- configuration-reference: cron block documented cron.webhook and cron.failureDestination, both retired by the config-surface reduction tranches (58452de711, edecdbd05e); the cron schema is strict so a copied snippet is rejected. Document only the live keys and note the doctor --fix migrations.
- configuration-reference: root-level audit block is retired; canonical path is logging.audit (src/config/zod-schema.root-shape.ts).
- configuration-reference: cron.failureAlert.after default is 2, not 3 (src/cron/service/failure-alerts.ts).
- memory-config: rememberAcrossConversations defaults on for personal installs (packages/memory-host-sdk/src/host/config-utils.ts), matching the canonical table earlier in the page.
- tool-search: telemetry records catalogSize, per-source counts, and search/describe/call counts, and only on tool_search_code results. No byte accounting exists in the runtime.
* docs: retire remaining references to removed cron, audit, and logging config keys
Sweep follow-up to the previous commit, covering the same bug class in the pages that still contradicted it.
- cron-jobs/cli-cron: global cron.failureDestination is retired; the destination fields now live on cron.failureAlert (src/config/zod-schema.root-shape.ts, merged by legacy-config-migrations.runtime.retired.ts:379). Per-job delivery.failureDestination bullets left intact.
- gateway/audit, cli/audit, gateway/protocol: root-level audit.* is retired; canonical path is logging.audit.*.
- logging: logging.redactSensitive is retired (dead-config-keys.test.ts:198; removed by legacy-config-migrations.runtime.tier-eval.ts:12). resolveConfigRedaction hardcodes DEFAULT_REDACT_MODE = tools, so redaction is unconditional. Also documented that redactPatterns replaces the defaults on the log path (redact.ts:419) while tool payloads always merge them.
- logging: consoleStyle accepts only pretty|json (zod-schema.root-shape.ts:106); compact remains the automatic non-TTY rendering style (logging/console.ts:40) but is no longer settable, and doctor maps a stored one to pretty.
- security: security --fix no longer touches redaction and the logging.redact_off audit check is retired (src/security/audit-loopback-logging.test.ts asserts it never fires).
* chore(docs): regenerate docs map after retired-key cleanup
The runtime retirement already shipped: busy deferral is automatic,
reasoning payloads stay internal, the HEARTBEAT_OK ack budget is fixed at
300 chars, the Heartbeats prompt section follows cadence, and tool-error
warnings are always on. Docs still advertised skipWhenBusy, ackMaxChars,
includeReasoning, includeSystemPromptSection, and suppressToolErrorWarnings
as live options; this aligns seven pages with the fixed policies and the
strict heartbeat field list, locks the claw-profile skipWhenBusy rejection
diagnostic with a dedicated test, renames includeReasoning-era test/comments,
and canonicalizes claw add-plan workspace path assertions (macOS realpath).