* fix(infra): guard channel ingress queue parseJson against corrupted JSON
* fix(infra): fix type assertion in ingress queue test
* fix(infra): use tagged parse result and validate payload before claiming
* fix(infra): remove unnecessary non-null assertion in ingress queue test
* fix(infra): scan corrupt ingress rows in claimNext
* test(gateway): avoid typed empty mock call tuple access
* fix(infra): tombstone corrupt ingress rows on duplicate enqueue and stale recovery
Two P1 gaps: enqueue() threw on duplicate when the existing row had corrupt
payload_json, and recoverStaleClaims() silently skipped corrupt claimed rows,
leaving them invisible to recovery. Both paths now tombstone the unrecoverable
row as failed with reason "corrupt_payload" and return a proper result.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(infra): resolve lint shadow and await-thenable in recoverStaleClaims
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(channels): tombstone corrupt ingress rows
* test(channels): use explicit placeholder claim tokens
* refactor(channels): name claim token values
* refactor(channels): keep claim projection direct
* fix(channels): preserve active ingress claims
* fix(channels): make corrupt recovery policy-aware
* refactor(channels): name corrupt claim token
* fix(channels): bound corrupt ingress reconciliation
* fix(channels): paginate pending ingress by key
* refactor(telegram): return live owner check directly
* build(plugin-sdk): refresh public export budget
---------
Co-authored-by: Pick-cat <huang.ting3@xydigit.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
(cherry picked from commit a824078101)
Behavior: a plugin before_agent_finalize hook that never resolves could previously freeze an agent run forever after a successful compaction retry, with no errors and no recovery from a gateway restart; this was the frozen-runner mechanism behind #84777. before_agent_finalize now has the same 15s default budget as sibling modifying hooks and fails open with the original final answer, converting the freeze into a bounded delay.
Surface: plugin hook runner defaults (src/plugins/hooks.ts), docs/plugins/hooks.md.
Refs #84777.
(cherry picked from commit b2baf799b4)
Move Canvas, Discord, Slack, voice-call, and WhatsApp skill docs from the root bundled skill tree into their owning plugin packages, with manifest skills declarations and docs/test path updates.
Validation:
- node --import tsx scripts/sync-plugin-versions.ts --check
- node scripts/run-vitest.mjs src/skills/loading/env-path-guidance.test.ts
- autoreview clean
- Crabbox Azure pnpm check:changed run_59ba76511d57 / lease cbx_cbc6750dad72
- wrapper prepare passed pnpm install --frozen-lockfile, pnpm build, and pnpm check before the oversized full local pnpm test was stopped
Follow-up: #95132 remains as the stacked PR for the rest of the starter-skill/Sherpa/ClawHub work.
The Subagents section of docs/plugins/hooks.md listed subagent_ended
but did not describe its payload. Plugin authors reaching for
agentId (as on subagent_spawned) silently got undefined because
PluginHookSubagentEndedEvent uses targetSessionKey as its identity
field and has no agentId/childSessionKey.
Document all fields from PluginHookSubagentEndedEvent and explicitly
note the missing identity fields so handlers can correlate events
correctly.
Closes#95186
Co-authored-by: MaHaoHao-ch <MaHaoHao-ch@users.noreply.github.com>
Adds stdout and both-mode diagnostics OTEL log export, with focused QA Lab smoke coverage and docs/config updates.
Prepared head SHA: efa2ef07ab
Verification: CI 27808480969 passed for the prepared head.
Reviewed-by: @jesse-merhi
Adds Codex as a selectable hosted web-search provider, routes native Codex search safely across model overrides, and isolates bounded hosted-search workers from configured tools.\n\nVerification: focused post-merge regression suite passed 202/202 tests on exact head 23824af49a.