Commit Graph

1470 Commits

Author SHA1 Message Date
Peter Steinberger 2d887acba3 fix(slack): drop the tool-call receipt from finished progress cards (#123851)
The Block Kit session card terminalized into a '🛠️ N tool calls · ⏱️ Ns'
footer, leaving a per-turn receipt in the Slack transcript on the default
progress path. PR #122976 deleted the same receipt from the native progress
surface but left this sibling rendering it.

Finished cards now keep only the durable diff stat and the session link;
tool-call and elapsed counters stay live working state. Also corrects the
documented channels.slack.streaming.mode default, stale since #122552.
2026-08-16 14:58:23 -07:00
Peter Steinberger eab2b8fdca refactor(slack): mark approval headers with typed block ids (#124841) 2026-08-16 14:53:26 -07:00
Peter Steinberger 568b920b21 feat(lint): enforce import ordering and deduplication (#124730)
* refactor(imports): dedupe and hoist imports

* feat(lint): enforce import/no-duplicates and import/first
2026-08-16 11:44:52 -07:00
Peter Steinberger 63401b730b fix: keep doctor security conditions as single findings (#124666)
* fix(doctor): record security finding severity

* refactor(security): keep audit severity internal

* fix(security): preserve channel finding severity
2026-08-16 10:24:40 -07:00
Peter Steinberger a118bfbf30 fix(slack): stop sniffing the NO_REPLY product token in the transport (#124561)
sendMessageSlack special-cased core's silent-reply token before any API
call, returning a fabricated 'suppressed' messageId. Silent-reply
stripping is owned by core auto-reply normalization before payloads
reach outbound — no sibling channel transport has this check, so a
literal NO_REPLY sent through the message tool delivered everywhere
except Slack. The check predates the extension extraction (it moved
verbatim in 8746362f5e) and is duplicate policy.

Delete the check, its sentinel mint (the only one in the repo), and the
receipt filter for it; tests now pin sibling-parity delivery instead of
the suppression.
2026-08-16 05:56:41 -07:00
Peter Steinberger f43544f752 refactor: remove vestigial runtime indirection (#124554)
* refactor: remove vestigial indirection

* test: update Slack runtime API guard
2026-08-16 05:31:36 -07:00
Peter Steinberger 78ca5fcfb6 perf(test): fast-forward Slack probe retry window (#124428) 2026-08-15 22:18:20 -07:00
Peter Steinberger e4aaef4660 perf(test): shorten Slack startup auth regression (#124404) 2026-08-15 21:16:31 -07:00
Sarah Fortune dbc2356abc feat(slack): make presence event guidance configurable (#123875)
* feat(slack): make presence event guidance configurable

* chore(config): regenerate channel metadata

* fix(slack): keep presence prompt SDK compatible

* chore(config): refresh config baseline

* fix(slack): cap presence event prompts

* chore(config): refresh Slack prompt metadata

* fix(slack): bound queued presence wake prompts

* fix(slack): inherit presence prompt for named accounts

* fix(slack): keep prompt limit at config boundary

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-15 12:02:19 -07:00
Peter Steinberger c0824d284e test(extensions): remove type-only probe contracts (#124190) 2026-08-15 08:02:07 -07:00
Ilya Kuprov f21d34d71d fix(slack): upload-file silently drops a caption (#121047)
The Slack `upload-file` action accepts `media` as an alias for `filePath`, so
a caller can reach it with the same vocabulary used for a media `send`. That
vocabulary carries its accompanying text in `caption`, but the upload path
read only `initialComment` and `message`, so the text was dropped and the file
arrived in the channel with no comment at all.

Accept `caption` as the lowest-precedence alias. Explicit `initialComment`
still wins, `message` still comes next, and an explicitly empty
higher-precedence value stays empty.
2026-08-15 10:58:55 +03:00
Sarah Fortune f2e5d2054d feat(slack): include observed away duration in presence events (#123805)
* feat(slack): include observed away duration in presence events

* style(slack): format presence observation type

* test(slack): type presence enqueue mock

* fix(slack): preserve presence event prompting

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-14 22:46:00 +00:00
Peter Steinberger 2bc1699a37 fix(slack): preserve structured payload dispatch custody (#123710) 2026-08-14 09:01:05 -07:00
Dallin Romney 83d53044a4 fix(channels): route commentary through one progress owner (#121009)
* fix(slack): keep commentary progress on draft lane

* fix(channels): route commentary through one progress owner

Keep non-verbose commentary in Slack and Discord draft lanes while preserving one durable commentary payload when verbose progress makes those drafts yield. Freeze that owner decision for the turn so session changes apply on the next turn.

Co-authored-by: Dallin Romney <dallinromney@gmail.com>

Punchcard-Session: amber-workshop-workshop-36

* fix(channels): refresh queued commentary owner

Recompute the frozen draft-versus-durable commentary owner for every queued follow-up turn and carry that decision into final payload projection.

Punchcard-Session: amber-workshop-workshop-36

* fix(channels): clarify commentary owner opt-in

* fix(channels): preserve queued draft preambles

* fix(channels): require explicit queued progress ownership

* refactor(channels): record commentary progress owner

* fix(telegram): tolerate unscoped queued updates

* test(discord): use canonical draft fixture after rebase

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-14 22:15:53 +08:00
Josh Avant 97a53a9b35 feat: audit admitted channel participant identity (#122863)
* feat: audit admitted channel participant identity

* fix: preserve Telegram identity through thread recovery

* fix: signal held gateway process groups

* fix: keep audit evidence passive in collect routing

* fix: validate copied channel participant evidence

* fix: bind channel participant evidence to host ingress

* fix: honor Telegram proof credential roles

* fix: restart held Telegram proof through gateway

* fix: repair channel identity CI regressions

* test(matrix): bind thread routing owner

* fix: preserve direct DM SDK compatibility

* fix: bind channel provenance at host runtime

* test(feishu): provide channel context builder

* fix: defer record-bound channel runtime resolution

* fix: keep channel admission evidence core-private

* fix(audit): bind channel admission to plugin lifecycle

* fix(audit): bind ingress provenance to final context

* refactor(audit): split admission scope keys

* test(queue): cover combined metadata carriers

* refactor(audit): keep lifecycle helpers private

* fix(queue): preserve combined turn authority

* test(channels): provide ingress context builders

* test(channels): align integrated CI fixtures

* test(clickclack): resolve model-loop ingress

* docs: preserve channel participant evidence invariant
2026-08-14 08:57:01 -05:00
Kimi Yu d3ff5583d3 fix(slack): keep cached monitor identity and allowlists live (#123403)
* fix(slack): keep cached monitor context state live

* test(slack): type cached monitor context mock
2026-08-13 19:15:38 -07:00
Kimi Yu 358eecf8cb fix(slack): apply updated global settings to new messages (#123373) 2026-08-13 17:55:26 -07:00
Peter Steinberger 902eddf16b fix: keep global channel events agent-scoped (#123316)
Slack and Discord routed system events now retain route ownership when they enter literal-global queues, so sibling agents cannot consume them. Genuinely unbound routing remains an explicit error instead of falling back to a default agent.
2026-08-13 14:45:19 -07:00
Peter Steinberger faa6202412 fix(slack): keep thread freshness on routed agent (#123202) 2026-08-13 13:17:36 -07:00
Peter Steinberger 11b3bf374c feat(slack): unify the native progress turn into one streamed message (#122976)
* feat(slack): unify the native progress turn into one streamed message

Native progress mode now streams the whole turn into a single Slack message:
narration flows as markdown_text chunks interleaved with plan/task chunks,
task rows carry file-path details and +N/-N output, the terminal task links
the session via url_source, and the final answer lands through stopStream in
the same message. Media/oversized/error finals keep their normal-delivery
fallbacks.

Deletes the finished-card receipt collapse (the '\u{1F6E0} N tool calls · ⏱ Ns' edit)
outright: the card now stays as its finished self.

Live-verified on a real workspace: exactly one bot message per turn.

* fix(slack): serialize native stream updates and keep append-only rendered text monotonic

Overlapping progress updates (compositor render, narration payload, final)
computed their narration delta before awaiting the network and committed
state only afterwards, so concurrent updates re-appended identical
narration into the streamed message (each status line landed 3x live).
A single ordering chain now makes each update's compute -> append -> commit
atomic.

applyAppendOnlyStreamUpdate also replaced the accumulated rendered text
with the incoming cumulative partial once an appended chunk had diverged
rendered from source, dropping content the sink already displayed; rendered
now only ever extends.

* fix(slack): stop refreshing thread status once a turn has visible output

Slack clears the assistant thread status as soon as the app puts anything
in the thread, and renders its own rotating agent-working row ("Generating
response...", "Finding answers...") for every status write after that -- it
ignores the app-supplied string. The typing keepalive re-set the status
every 3s for up to 60s, so each turn painted a duplicate status row under
the streamed card or progress message.

The status write is now gated on the turn having visible output, which the
dispatcher already tracks (delivered reply, committed preview, or posted
draft message). The first status still fires before any output, so slow
turns keep their indicator, and the typing reaction is tracked separately
so a suppressed status write still cleans up its reaction.

* fix(slack): let the plan card own the status line instead of echoing it

The status headline and plan explanation fed both the streamed narration
markdown and the plan card title, so every headline rendered twice: once as
static text and once in the card that keeps updating it in place. Narration
now carries only authored commentary and reasoning, and a preamble payload
whose text the card title already shows is not streamed again.

* feat(slack): make the native agent card the default progress surface

Slack's native plan/task card was opt-in behind streaming.progress
.nativeTaskCards while the Block Kit session card shipped as the default.
The native surface is the better product on every axis we can measure --
one streamed message instead of three artifacts, live task rows with file
paths and diff counts, and Slack's own agent chrome -- so it becomes the
default and an explicit false selects the Block Kit card instead.

The session link is now emitted only when it can actually work: the
operator set gateway.publicOrigin and left the Control UI enabled.
Installations with no externally reachable Gateway get no link rather than
a dead one.

The progress card still only appears for turns that do real work; the
existing compositor start gate keeps plain question-and-answer turns
card-free.

* fix(slack): finish the final inside a buffered native stream

A short narration leaves the SDK session un-flushed, so `delivered` stays
false until `stop` makes its first network call. Requiring delivery before
finishing in-stream sent the final through normal delivery and then
finalized the stream anyway, producing exactly the second message this path
exists to prevent. Stop-time rejection already falls back via
SlackStreamNotDeliveredError, so a live session is enough.

Addresses the ClawSweeper P1/P2 finding on this PR.

* refactor(slack): collapse duplicate streaming surfaces and drop dead code

Cleanup pass over the progress/streaming neighborhood, all verified unused
by exhaustive reference search:

- Deleted buildSlackProgressStreamStartChunks/UpdateChunks: byte-identical
  pass-throughs to the same builder, plus the render-module branch that
  chose between them. One exported builder now.
- Collapsed slackStreaming.draftMode, a lossless restatement of the mode it
  was derived from, and its outbound mapper; nine comparisons now read the
  mode directly. Inbound legacy parsing stays for doctor migration.
- Dropped stopSlackStream's text parameter, the draft stream's stop() member
  and onMessageSent hook, a redundant nativeStreaming argument, four dead
  members on the progress runtime, and two single-expression wrappers.
- Deduped the native card title, which was computed twice per render.

Production LOC for the whole PR drops from +216 to +114.

* chore(config): regenerate bundled channel metadata for the Slack card default

The generated metadata still carried the old opt-in help text and
default-false description for streaming.progress.nativeTaskCards, so
config UI and diagnostics would publish stale guidance.

* fix(slack): un-export the now-internal legacy draft-mode type

Collapsing draftMode removed the type's only external consumer, so knip
flagged it as an unused export. Doctor migration still parses these legacy
values inbound, so the type stays module-local.
2026-08-13 11:19:32 -07:00
Sarah Fortune 3f731db90c fix(slack): accept org-wide user IDs in Enterprise Grid policies (#122934)
* test(slack): accept org-wide enterprise users

* fix(slack): allow org-wide enterprise users

* style(slack): format enterprise user policy

* test(slack): preserve enterprise user identity scope

* fix(slack): preserve enterprise user identity scope

* fix(slack): import workspace identity normalizer

* fix(slack): normalize enterprise owner ids

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-12 21:01:05 -07:00
Peter Steinberger 4d54c3f1a1 refactor(config): retire dead streaming.progress.render key (#122927)
* refactor(config): retire dead streaming.progress.render key

The key had zero runtime consumers after #122552. Core doctor now strips it via stripRetiredTuningKnobs, and production LOC is net -13.

* fix(tooling): pin plugin SDK surface counts to the reduced export set

The retired progress-draft render reader counted twice via channel-outbound and channel-message's wildcard re-export.
2026-08-12 20:36:40 -07:00
Peter Steinberger 08f9c3a5cb test(extensions): remove duplicate runtime replays (#122949) 2026-08-12 19:58:04 -07:00
Vincent Koc dabf55727b fix(ci): prevent channel add command test timeout (#122879)
* test(channels): isolate add env setup contracts

* test(channels): cover adapter env setup
2026-08-12 19:24:31 -07:00
Calin Laurentiu Ilie 95bbd117ef fix(slack): prevent duplicate Socket Mode connections after reconnect errors (#122624)
* fix(codex): read canonical transcript session targets (#1)

* test(slack): reproduce reconnect timer surviving shutdown

* fix(slack): keep reconnects within one socket lifecycle

* test(slack): exercise native reconnect over loopback

* test(slack): satisfy reconnect integration checks
2026-08-12 18:57:04 -07:00
Kimi Yu f9316c4697 fix(slack): stop repeated outage notices in active threads (#122782) 2026-08-12 14:41:41 -07:00
Peter Steinberger c58dbaff22 fix(slack): session card stuck on Working after concurrent mentions (#122816)
* fix(slack): terminalize a progress card detached by a concurrent mention

Rapid mentions in one Slack conversation fire the draft-message boundary
notifier, which calls forceNewMessage and clears the draft stream's message
identity so later output lands below the human message. The already-posted
Working card survives in Slack but becomes unreachable: finalize(), clear(),
and the drop-on-failed-finalize fallback all key on the stream's current
identity, so the card stays at Working forever.

Retain messages the draft stream abandons while un-finalized, expose
dropDetachedMessages(), and drain it from the card's finalize path so final
delivery, error closeout, and turn rotation all terminalize. Also implement
onQueuedFollowupSettled so a queued turn draining after its dispatch already
returned cannot leave a card in Working state. Both cleanups are gated on the
session-card mode: partial/append previews hold streamed assistant text the
human already replied to and must stay visible.

* fix(slack): drain detached cards appended during an in-flight delete

The detached-card drain snapshotted its queue, so a human message routed
synchronously through the conversation boundary during an awaited delete
appended a card the same drain would never remove. The silent-turn closeout
also dropped before its clear(), leaving that window unowned.

Drain until the queue is stable and make the drain the last act on the silent
exit path, so a card detached mid-cleanup still reaches removal.
2026-08-12 14:31:46 -07:00
sunlit-deng 120a75da51 fix(slack): surface unavailable forwarded images (#122108)
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-12 16:07:18 -05:00
Peter Steinberger b4ffa3106f refactor(extensions): remove orphan test exports (#122784) 2026-08-12 12:45:33 -07:00
Peter Steinberger 508dd471b0 feat(slack): live session cards as the default progress mode (#122552)
* feat(slack): render live session cards as the default Slack progress mode

Slack streaming.mode default flips partial->progress.
Progress mode renders one live Block Kit session card with a status header, narration, plan, activity, diff stat, and elapsed time; it is edited in place and finalized to success or error with an Open in OpenClaw button when gateway.publicOrigin is set.
Final assistant text always delivers separately.
The shared progress compositor gains a success-only additive per-turn diffStat mirroring the task ledger fold.
resolveGatewayPublicOrigin is exported through the plugin SDK.
The diffs viewer URL falls back to publicOrigin.
The old rich/text progress render fork is deleted.
Native task cards remain unchanged and opt-in.

* chore(config): regenerate bundled channel config metadata

* refactor(slack): keep session card state type internal

* refactor(slack): split session-card and diff-stat owners under lint ceilings

* refactor(channels): reuse diff-stat type from its owner module

Import ChannelProgressDraftDiffStat from progress-draft-diffstat instead of
redeclaring it in the compositor, resolving the all-exports deadcode scan.

* chore(plugin-sdk): regenerate api baselines for channel barrels

Baselines drifted after the rebase reconciled them against main; regenerate to
match the branch's actual channel-message/channel-outbound surface.

* fix(slack): drop a session card that cannot terminalize after final delivery

If the final reply is delivered but the terminal card edit fails, the caller
now clears the stale card instead of leaving it stuck in its Working state
(mirrors the pre-card preview cleanup). Adds a transport-failure regression and
corrects three tests that asserted the prior ignore-the-result behavior.

Documents resolveGatewayPublicOrigin as a dependency-light runtime helper on the
config-contracts SDK subpath, which previously described a type-only surface.

Addresses ClawSweeper P2 (unfinalized card) and P1 (runtime SDK contract).

* fix(slack): suppress default tool messages under the default progress card

resolveChannelStreamingSuppressDefaultToolProgressMessages re-derived the stream
mode from config with an "off" default, unlike its sibling resolvers which take
a caller-resolved mode override. After this branch made progress the Slack
default, a default-config channel turn saw mode "off" and left a stray
"Using tool: X" plain message posting alongside the session card. Thread the
caller-resolved mode through (compositor passes params.mode; Slack dispatch passes
slackStreaming.mode), matching resolveChannelStreamingPreviewToolProgress.

Retarget the progress-session-card delivery-trace golden at an EMPTY Slack config
so it proves the real default path; the regenerated golden is byte-identical,
confirming defaults now yield the clean card sequence (one card post, separate
final text, one terminal update with the Open in OpenClaw button, no stray tool
message). Switch the dispatch delivery-mode mock to the real resolver so the card
tests exercise the true channel default (automatic), not a hand-rolled one.

* chore(plugin-sdk): regenerate api baselines for the streaming mode param

resolveChannelStreamingSuppressDefaultToolProgressMessages gained an optional
mode override; the changed signature reflows the surface hash of every barrel
that re-exports it, so regenerate the affected baselines.

* chore(config): regenerate config baselines
2026-08-12 10:38:31 -07:00
Peter Steinberger 99d662473c fix(channels): fail-fast headless channel setup with plugin-declared env contracts (#122530)
* fix(channels): validate headless channel setup

* docs(channels): document headless provisioning

* fix(channels): repair setup metadata typing

* chore(channels): regenerate official channel catalog for env metadata

* fix(slack): keep mode-conditional env contract plugin-owned

Static --use-env declaration keeps only the unconditional SLACK_BOT_TOKEN;
socket-vs-HTTP conditional requirements (app token, signing secret) stay in
Slack's own setup validation so HTTP mode no longer demands an irrelevant
SLACK_APP_TOKEN.

* chore(sdk): regenerate api baselines and catalog after rebase

* fix(slack): align manifest env declaration with runtime contract

* chore(sdk): regenerate api baselines after rebase

* chore(sdk): regenerate api baselines after rebase

* chore(sdk): regenerate api baselines after rebase
2026-08-12 17:12:15 +00:00
Sarah Fortune bea0e398fa fix(slack): expose channel reaction events to thread turns (#122363)
* test: cover routed Slack system events

* fix: deliver route events to thread turns

* style: format routed event test

* fix: scope parent event routing to Slack

* test: isolate routed event admission proof

* fix(slack): keep reaction route handoff internal

* fix(slack): preserve channel turn public types

* fix(slack): hide reaction route carrier from sdk

* style: keep channel lifecycle within lint budget

* style: trim channel lifecycle carrier setup

* test: preserve route events on busy admission

* fix(reply): defer system event drain until admission

* test: prove deferred system event drain

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-12 10:04:57 -07:00
Peter Steinberger c23d66e3b5 refactor: consolidate coercion ownership (#122692)
* refactor: consolidate coercion ownership

* test: align shard check with weighted planning

* chore: refresh plugin SDK API baseline
2026-08-12 09:25:28 -07:00
Vincent Koc 9e8995384b fix(slack): retry transient member auth lookups (#122356) 2026-08-12 23:38:43 +08:00
Vincent Koc d5f995c388 fix(slack): preserve original bytes for forced media (#122667)
Punchcard-Session: crisp-valley-brook-8r
2026-08-12 23:32:32 +08:00
Vincent Koc 3a9e461912 test(slack): restore enterprise auth fixture identity (#122639) 2026-08-12 22:26:46 +08:00
Vincent Koc beb576c2ad test(slack): restore tool result reaction state (#122592) 2026-08-12 20:54:06 +08:00
Vincent Koc c702bf2796 fix(ci): repair Slack enterprise fixture routing (#122589) 2026-08-12 20:32:41 +08:00
Peter Steinberger 432ccac74b fix(channels): honor terminal reaction holds (#122544)
Serialize done and error holds before restoring initial reactions, and restore Slack error reactions through the shared lifecycle.
2026-08-12 01:36:54 -07:00
Peter Steinberger 08142099da refactor(plugins): remove test-only facades and adapter (#122532)
* refactor(plugins): trim test-only facades

* refactor(whatsapp): remove legacy outbound adapter
2026-08-12 01:20:09 -07:00
Peter Steinberger b080dd1e76 refactor: consolidate coercion contracts (#122458)
* refactor: consolidate coercion contracts

Centralize exact string, record, numeric, date, Boolean, argument, and structured-error coercions while preserving call-site semantics.

Migrate canonical-name collisions and deprecated internal SDK bypasses, deleting 55 net production/tooling lines. Expand declaration ownership enforcement to 101 allowed helpers and add a narrow export-completeness audit.

* fix: preserve standalone script coercions

Keep copied Control UI tooling self-contained and retain the trusted release harness module-relative source seam when the harness runs against an old target cwd.
2026-08-11 23:26:37 -07:00
Sarah Fortune 00fc1bd123 fix(slack): scope enterprise channel and user policies by workspace (#122346)
* fix(slack): scope channel policies by workspace

* fix(slack): scope user policies by workspace

* fix(slack): preserve workspace policies at ingress

* test(slack): use canonical workspace ids

* chore(slack): remove stale allowlist import

* fix(slack): require workspace-scoped grid policies

* test(slack): scope enterprise policy fixtures

* style(slack): format workspace policy changes

* fix(slack): preserve workspace policy wildcards

* fix(slack): retain workspace system-event policies

* fix(slack): scope bot policy identities

* fix(slack): retain workspace in group policy

* fix(slack): preserve workspace DM allowlists

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-11 22:09:46 -07:00
Peter Steinberger 964c8c84c1 refactor: consolidate coercion ownership (#122299)
* refactor: consolidate coercion ownership

Centralize four canonical coercion helpers, migrate exact core and plugin duplicates through narrow Plugin SDK facades, and enforce declaration and plugin-normalization ownership boundaries.

The sweep adds eight focused SDK exports while deleting more production and tooling code than it adds. User-visible behavior is unchanged except for safer equivalent object and UI parsing at existing boundaries.

* fix: guard integer option ownership

Register resolveIntegerOption with the canonical function owner and extend the declaration-guard fixture so future local duplicates fail validation.

* fix: keep integer helpers on numeric facade

Remove the unshipped duplicate string-coerce exports and route every affected plugin consumer through the existing number-runtime contract.

* fix: point numeric coercion to number runtime

Make boundary and declaration diagnostics recommend the canonical numeric facade, with failing-before coverage for both guidance paths.
2026-08-11 17:14:53 -07:00
Peter Steinberger b350f76484 fix(channels): preserve failed agent run reactions (#122009) 2026-08-11 15:26:44 -07:00
Kevin Lin 2d0c30fd65 fix(slack): keep previously joined threads active beyond 24 hours (#121708)
* fix(slack): keep participated threads active beyond 24 hours

* fix(plugin-state): reject transient TTLs after durable migration

* fix(slack): keep channel entrypoint on narrow plugin API

* chore(sdk): refresh sharded durable-state API baselines

* fix(slack): preserve existing thread expiration without migration

* fix(slack): preserve hydrated legacy thread expiration

---------

Co-authored-by: kevinlin-openai <kevinlin@openai.com>
2026-08-11 11:31:07 -07:00
Peter Steinberger 86bc5aa726 test(plugins): remove stale test plumbing (#122175) 2026-08-11 11:01:05 -07:00
Peter Steinberger cad77fb39c refactor: consolidate remaining coercion helpers (#122020) 2026-08-11 10:22:01 -07:00
Peter Steinberger fa03d9b913 refactor: consolidate coercion helpers (#121366)
* refactor: consolidate coercion helpers

* fix: remove duplicate coercion imports

* fix: preserve serialized coercion guard

* chore: ratchet coercion helper carve-outs

* fix(test): keep gauntlet subprocess startup lean

* fix: preserve imported session timestamp semantics

* fix: preserve catalog timestamp string semantics

* chore: align plugin SDK surface ratchet

* fix: preserve trajectory and SDK string contracts

* fix(test): preserve QA record assertion semantics

* fix: complete standalone record guard rename

* refactor(cron): use canonical string coercion

* fix(acpx): preserve Pi timestamp parsing

* test(channels): adapt custody test harnesses

* test(telegram): classify media harness as test support

* test(acpx): split timestamp contract coverage

* test(channels): support generated custody contracts

* chore: ban the full coercion helper name set

Extends the declaration guard to all eleven consolidated helper names and
renames the cron schedule-identity readNumber wrapper to readScheduleInteger
so the banned generic name cannot regrow.

* fix(scripts): repair release-validation guard drift and lint cause

Restores the renamed isJsonRecord guard in assertTrustedWorkflowHarness after
main added isRecord call sites in parallel, and attaches the caught YAML error
as the thrown error cause (preserve-caught-error was red on main).

* fix: preserve Claude timestamp string semantics

* fix: preserve persisted timestamp string semantics

* fix: preserve date-first timestamp contracts

* fix(openai): harden delegation failure formatting

* chore: close coercion helper guard gaps

* test(openai): model non-error delegation rejection

* chore: refresh plugin SDK API contract

* fix(tasks): use canonical string field reader

* fix(ai): use canonical provider error field coercion

* fix(browser): migrate native bootstrap coercion

* docs(plugin-sdk): clarify text record export compatibility

* fix(gateway): normalize approval execution identity

* test(outbound): isolate message action poll harness
2026-08-11 00:02:18 -07:00
Peter Steinberger d6f70a96cb fix(plugins): native commands execute the selected plugin (#121544)
* fix(plugins): preserve selected command identity

* test(telegram): use scoped command registries

* test(telegram): isolate command runtime fixtures

* test(telegram): warm native command runtime

* refactor(plugins): keep command metadata private

* fix(plugins): accept synchronous command handlers

* fix(plugins): scope command drain bypass to live execution

* test(telegram): use scoped command registry fixtures

* test(telegram): isolate native menu runtime fixtures

* test(telegram): isolate login session store

* test(telegram): surface login flow failures

* test(telegram): preload native login module

* test(telegram): scope native command registries

* fix(plugins): complete command dispatch contracts

* fix(plugins): break command dispatch import cycles

* fix(plugins): stabilize command dispatch contracts

* fix(channels): keep plugin dispatch options internal

* fix(plugins): keep command dispatch carrier opaque

* test(channels): align delivery adapter fixtures

* test(delivery): align custody ownership coverage

* test(delivery): align latest queue reconciliation

* test(channels): drop obsolete delivery wrappers

* fix(plugins): rebind channel reload starts

* fix(plugins): scope command catalog reloads

* fix(ci): align current runtime contracts

* chore(plugin-sdk): refresh API baseline
2026-08-10 19:30:47 -07:00
Ayaan Zaidi 9935ca3b30 fix(approvals): bind native requests to channel accounts (#121673)
Native approval delivery and resolution now stay bound to the originating or explicitly targeted channel account. Unbound requests fail closed across multiple eligible accounts; trusted reviewer-less SDK callers remain compatible.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 01:42:41 +05:30