Commit Graph

19174 Commits

Author SHA1 Message Date
Peter Steinberger eecbfcc960 fix(infra): unify env-truthiness, missing-path, realpath, and abort-sleep semantics (#120359)
* fix(infra): unify environment truthiness

* fix(infra): unify missing path classification

* refactor(infra): unify realpath fallbacks

* fix(infra): unify abortable sleep errors

* docs(infra): clarify path fallback semantics

* fix(infra): route realpaths through policy wrapper

* fix(infra): ratchet plugin SDK wildcard budget

* fix(agents): preserve zero-delay abort precedence

* fix(infra): preserve fallback and media recovery contracts

* fix(plugins): share quarantine path resolution
2026-08-08 10:58:57 -07:00
Peter Steinberger 33f082b86a test(codex): align completed tool metadata expectation (#120637) 2026-08-08 10:04:26 -07:00
Glucksberg 6318e30077 fix(codex): prevent session-changed errors after /new (#113429)
* test(codex): prove replies after retained session reset

Co-authored-by: Markus <markuscontasul@gmail.com>
Co-authored-by: Josh Lehman <josh@martian.engineering>

* test(codex): verify reset idempotency

* test(codex): prove reset keeps binding writable

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-08-08 08:55:25 -07:00
Vincent Koc b5180b6816 fix(codex): support app-server 0.147.0 (#120594)
* fix(codex): support app-server 0.147.0

* docs(codex): clarify marketplace version provenance
2026-08-08 23:07:05 +08:00
Peter Steinberger 88975f85ea fix: required background completion silently disappears (#120453)
* fix(agents): surface silent required completions

* refactor(agents): simplify completion fallback handling

* fix(agents): require visible completion delivery

* fix(agents): preserve resolved session patches

* fix(agents): bound resolved session patch output

* fix(agents): reject silent automatic completions

* fix(agents): settle committed completion side effects

* fix(agents): retain ultra thinking profile

* fix(agents): require destination-safe completion evidence

* fix(agents): block invisible completion side effects

* fix(agents): preserve outbound no-replay evidence

* fix(agents): preserve resolved session identifiers
2026-08-08 07:52:12 -07:00
licheer-zte a32e81c8e8 fix(model-fallback): treat empty non-GPT completions as failed candidates (#120132) (#120148)
* fix(model-fallback): treat empty non-GPT completions as failed candidates (#120132)

Empty and whitespace-only completions from non-GPT models were counted as
candidate_succeeded, silently dropping the turn on visible channels. Apply
the empty/reasoning-only classification to every model; deliberate silent
replies and committed outbound deliveries remain successful.

* fix(model-fallback): classify mixed reasoning-plus-blank completions as failed (#120148)

A completion like [{ isReasoning: true, text: "thinking" }, { text: " " }]
carries no user-visible reply: reasoning text is invisible to the shared
visibility test (includeReasoningPayloads: false), so counting it as visible
made the run look successful and silently ended visible-channel turns.

Filter reasoning payloads out of the empty/whitespace predicate so mixed
reasoning-plus-blank results classify as empty_result (fallback-worthy),
while mixed reasoning-plus-visible-text results stay successful.

Regression tests: mixed reasoning+blank -> empty_result; mixed
reasoning+visible -> success.

* fix(model-fallback): require deliverable assistant results

Use one owner-boundary deliverability predicate for fallback classification, preserve intentional terminal outcomes, and add a mock-channel Gateway scenario for mixed reasoning-plus-blank recovery.\n\nCo-authored-by: 李琪0668001400 <li.qi16@xydigit.com>

* chore: preserve contributor credit

Co-authored-by: 李琪0668001400 <li.qi16@xydigit.com>

* test(qa): cover default model fallback scenario

Make the mixed reasoning-plus-blank fixture recover through both the catalog default alternate and the explicit proof model.

Co-authored-by: 李琪0668001400 <li.qi16@xydigit.com>

---------

Co-authored-by: licheer-zte <licheer-zte@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-08 07:48:17 -07:00
Peter Steinberger 725fe96bd7 fix(telegram): avoid credential reads in reply policy
Resolve reply mode through Telegram’s config-only account projection so threading policy never reads token files or SecretRefs.
2026-08-08 06:53:37 -07:00
Peter Steinberger f4f5310355 fix(telegram): restore account-scoped reply mode
Resolve reply mode through the selected Telegram account so account overrides and top-level inheritance reach outbound reply context.

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-08 06:53:37 -07:00
wonfong 9fdc266f64 fix(subagents): wake the parent when a follow-up finishes a yielded child (#120187)
* fix(subagents): wake the parent when a follow-up finishes a yielded child

A sub-agent that calls sessions_yield on its own behalf parks its run and
correctly withholds the parent's announce. But a later follow-up to that same
child session registered a sibling registry row instead of continuing the paused
one, so the requester defaulted to the child's own main session and the original
parent — itself idle behind sessions_yield — was never woken. The paused row also
stayed an unsettled descendant, deferring the parent's settle batch forever with
nothing recorded explaining the silence.

Follow-up dispatch now adopts the paused row through the existing post-steer
replacement seam, inheriting the requester identity and carrying the settle-wake
credential forward with its frozen batch membership remapped to the new run id.
A follow-up that names its own requester keeps registering separately, since an
explicit requester is a delivery opt-in that adoption would silently drop.

Also stops frozen-result refill from targeting paused rows: a yield clears the
result on purpose, so refilling from the session would attribute a later turn's
text to the paused run.

Closes #120157

* fix(subagents): select the paused owner past a requester-bound sibling

Adoption looked up the newest run for the child session and adopted it only
when that row was itself paused. A requester-bound follow-up deliberately stays
a sibling, but it registers at a higher generation and becomes that newest row,
so any later default follow-up saw an unpaused newest row, declined adoption,
and registered yet another sibling. The original requester stayed parked behind
a paused row that can never announce -- the same silent stall this fix exists to
remove, reached through a valid mixed-delivery sequence.

The latest-run query now takes an optional predicate applied before the
generation comparison, so a caller that owns a specific row class selects the
newest row of that class. Adoption asks for the newest `sessions_yield` row
directly instead of inferring it from generation order.

Docs now state that continuation applies to default delivery, since a follow-up
carrying its own requester runs as a sibling by design.

* test(qa): prove post-yield follow-up delivery through the gateway boundary

The unit and gateway-method tests for paused-run adoption assert on registry
rows, which proves the bookkeeping but not that an operator ever sees the
result. This adds the boundary proof: a real gateway child, the QA mock channel,
and the mock provider driving a subagent that pauses itself and finishes only on
a later follow-up.

A fixture plugin owns both legs. Its `before_dispatch` hook spawns the child with
`completionDelivery: "current-requester"`, so the announce has the operator turn
as its audience. An HTTP route then dispatches the follow-up to that same paused
session using default delivery -- the path adoption is meant to catch. A
requester-bound follow-up would opt into its own audience and run as a sibling
instead, so the two legs must differ here.

The mock provider gains a child that yields on its own behalf. Both of its turns
match on the current prompt rather than the shared transcript, so the yielded
kickoff cannot make the follow-up turn yield a second time.

The scenario asserts both sides of the invariant: no outbound traffic while the
child is paused, and exactly one announce carrying the follow-up marker once it
ends.

Reverting the adoption call site fails this test in the way that matters: the
child still produces its marker and the run still ends with stopReason=stop, but
nothing reaches the requester and the wait times out. The result is computed and
then silently dropped -- which is the failure this repair exists to remove.

* fix(ci): match QA Lab fixture plugin entries as a group in knip

The all-exports pass listed one fixture entry by name, so every new QA Lab
fixture plugin lands as an unused file and turns check-dependencies red until
someone remembers this file. Nothing imports these entries by design: the
Gateway E2E loads them through plugin config paths.

* docs(subagents): scope yield continuation to plugin runtime follow-ups

Adoption is gated on plugin_subagent task tracking, which only
createGatewaySubagentRuntime().run sets, so api.runtime.subagent.run is the
sole route into it. Writing that as one example implied other follow-up paths
to a paused session continue the run too; they are not tracked as sub-agent
runs and announce nobody.

* fix(subagents): reject undurable paused-run adoption

Fail plugin follow-up admission closed when the paused-run ownership swap cannot be persisted, while retaining the existing restart-recovery return-false contract. Trim duplicate tests and keep boundary coverage for requester routing, wake-batch remapping, repeated yield, and persistence rollback.

Co-authored-by: zhou.huanfeng <woundfongv3@163.com>

* docs(subagents): clarify yielded-run steering

Co-authored-by: zhou.huanfeng <woundfongv3@163.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-08 06:46:19 -07:00
Peter Steinberger 83900e4683 feat(browser): add relay authentication v2 (#120526)
* feat(browser): add relay authentication v2

* fix(browser): cap relay test WebSocket payload

* fix(browser): keep relay E2E inside extension boundary

* fix(browser): isolate relay admission and cleanup auth

* fix(browser): finish relay auth migration hardening

* fix(browser): keep preauth transport bounded through teardown
2026-08-08 05:48:24 -07:00
Vincent Koc 4eec51a276 merge: align Fish Audio extension directory (#120084) 2026-08-08 20:46:55 +08:00
Vincent Koc 6e100ca56a test(codex): remove duplicate session helper 2026-08-08 18:47:18 +08:00
Peter Steinberger 10c7f005be refactor(github-copilot): narrow runtime facade (#120544)
* refactor(github-copilot): narrow runtime facade

* style(github-copilot): format runtime exports
2026-08-08 02:56:12 -07:00
Vincent Koc cdd621eaee test(telegram): use model selection rejection seam 2026-08-08 02:21:34 -07:00
Vincent Koc daca53c985 test(codex): align file-backed session fixtures 2026-08-08 02:21:34 -07:00
Vincent Koc e5f5030570 fix(plugins): align Fish Audio extension directory 2026-08-08 02:21:33 -07:00
Peter Steinberger c5d00cb47d fix(ui): keep task transcripts in the task sidebar (#120463)
* fix(ui): keep task transcripts in the task sidebar

* refactor(ui): split background task rail rendering

* fix(ui): reset stale task rail views

* fix(sessions): honor context usage provenance

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>

* fix(qa): split suite runtime agent process below line cap

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-08 01:45:44 -07:00
Peter Steinberger d9080cfff8 fix(agents): transfer requester wake ownership across yield and deflake survivor registry setup (#120538) 2026-08-08 01:42:33 -07:00
Vincent Koc bf0aadbc40 fix(qa): settle Unix commands after PGID cleanup (#120010)
Punchcard-Session: cobalt-valley-meadow-mg
2026-08-08 15:16:44 +08:00
Peter Steinberger c7b7fe4c32 fix(codex): restore continuity test coverage (#120452)
* test(codex): align run history fixture identity

* test(ci): repair gateway fixture checks
2026-08-07 23:39:26 -07:00
Peter Steinberger fa0fcef9f6 fix(sessions): require provenance for fresh context-size facts (#120497) 2026-08-07 23:06:30 -07:00
Peter Steinberger 947bca5608 fix(browser): harden extension relay authorization (#120390)
* fix(browser): harden extension relay authorization

* fix(browser): validate persisted relay pairing
2026-08-07 21:56:15 -07:00
zengLingbiao 0eeb9db216 fix(voice-call): redact credential material from provider error bodies (#117304) 2026-08-08 11:51:23 +08:00
Alix-007 1575187419 fix(browser): time out Google Docs page exports (#111633) 2026-08-08 11:47:58 +08:00
Alix-007 50ec5570ae fix(synology-chat): prevent duplicate messages after ambiguous failures (#119539)
* fix(synology-chat): avoid ambiguous send replays

* fix(synology-chat): classify aggregate send failures

* test(synology-chat): trim retry loopback proof

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-08 11:46:04 +08:00
Peter Steinberger 80ae3506aa test(clickclack): cover native progress default (#120410) 2026-08-07 19:02:35 -07:00
Peter Steinberger 0463d1bd83 test(qa): derive UX producer aggregate status (#120418) 2026-08-07 18:55:19 -07:00
Peter Steinberger 48639663b0 chore(release): prepare 2026.8.1 (#120375) 2026-08-07 18:44:12 -07:00
Peter Steinberger 5a79d19ba1 fix(codex): preserve warm sessions and approvals across conversations (#120405) 2026-08-07 18:38:09 -07:00
Peter Steinberger 96a75be170 fix(discord): default preview streaming to off (#120376)
Make Discord progress drafts and activity receipts explicit opt-ins while preserving configured streaming modes and legacy explicit progress migrations. Related: #87704.
2026-08-07 17:18:12 -07:00
Peter Steinberger fa9626c4e1 refactor(steering): make active-run admission exact and atomic (#120285)
* refactor(steering): make admission exact and atomic

* fix(steering): bind targets by run identity

* fix(steering): inject before reply dispatch

* fix(steering): preserve backend injection modes

* fix(steering): target session suggestions

* fix(steering): preserve sibling delivery contracts

* style(steering): satisfy exact-head lint

* fix(steering): preserve targetless protocol compatibility

* fix(steering): preserve exact targets through replies
2026-08-07 16:58:04 -07:00
joshavant 5cc2fa6249 fix(agents): defer recovered followups until drain 2026-08-07 18:42:57 -05:00
joshavant 7bcdb5823e test: prove repeated request recovery through gateway 2026-08-07 18:42:57 -05:00
joshavant ceeb02d7e1 Revert "refactor(agents): bind tool policy to exact execution identity"
This reverts commit d863dd5f5e.
2026-08-07 18:40:17 -05:00
joshavant 2751bc8991 Revert "fix(agents): restrict harness tool authority"
This reverts commit aacbcaacc8.
2026-08-07 18:40:17 -05:00
joshavant bc197e1b66 Revert "fix(plugins): inject harness tool authority"
This reverts commit 228478bffe.
2026-08-07 18:40:17 -05:00
joshavant 941f4a3ec6 Revert "fix(agents): satisfy tool authority lint"
This reverts commit 63c6cd9a02.
2026-08-07 18:40:17 -05:00
Peter Steinberger bc0c3fcd63 refactor(providers): shared generated-media download guard and binary-response adoption (#120351)
* fix(agents): cancel rejected provider binary bodies

* refactor(providers): share generated media downloads

* refactor(providers): adopt payload patch stream wrapper

* fix(providers): preserve generated media helper contracts
2026-08-07 15:45:53 -07:00
Peter Steinberger 45b1dbf962 test(qa): add managed-worktrees CLI lifecycle scenario coverage (#120335)
* test(qa): add managed-worktrees CLI lifecycle scenario coverage

Managed worktrees had zero QA scenario-pack coverage despite being a
headline feature. Mint agent-runtime.managed-worktrees-lifecycle in the
taxonomy, add a runtime scenario, and prove the real child CLI through
create with .worktreeinclude provisioning and the .openclaw setup hook,
dirty removal pinning a snapshot ref, restore rebuilding tracked,
untracked, and provisioned files with their modes, and gc preserving
manual worktrees.

* fix(qa): align model-switch catalog assertion with expectedAlternate flow

qa/scenarios/models/model-switch-follow-up.yaml switched to
expectedAlternate.model in 5a795f4dda but the catalog test still greps
for the retired alternate?.model literal; the test is outside the PR
change-classification lanes, so the break only surfaces on direct runs.

* test(qa): narrow managed-worktrees taxonomy description to proven manual-owner gc

ClawSweeper P2 on #120335: the scenario proves manual-owner gc retention
only; session and Workboard cleanup lifecycles are not exercised, so the
coverage description must not claim them.
2026-08-07 14:18:12 -07:00
joshavant 87156bab23 fix(typing): keep long active turns visible 2026-08-07 16:11:52 -05:00
Peter Steinberger 32361e749a fix(voice-call): isolate runtime generations (#120289)
Prevent retained plugin closures from recreating, adopting, or stopping successor runtimes across shutdown and restart.

Add deterministic lifecycle regressions for pending startup, exact-owner stop, retained tools, and generation restart.
2026-08-07 13:56:26 -07:00
Peter Steinberger 10e60fa0ce refactor(plugins): shared legacy-state doctor migration and simple secret contracts (#120346)
* refactor(plugins): share legacy JSON doctor migration

* refactor(discord): share account token inspection cascade

* refactor(plugins): share simple channel secret contracts

* refactor(discord): keep token inspector private
2026-08-07 13:55:31 -07:00
Josh Avant c691f2e41c fix(progress): preserve callback acceptance results (#120171)
* fix(progress): preserve callback acceptance results

* fix(progress): require transport acknowledgements

* fix(progress): preserve direct acceptance outcomes
2026-08-07 14:40:33 -05:00
Peter Steinberger 6543e6f7c9 fix(discord): thread archive/delete closes sessions in each agent's store (#120259)
* fix(discord): thread archive/delete closes sessions in each agent's store

closeDiscordThreadSessions resolved the sessions store with the Discord
account id as agentId ('default' on the default path), which points at a
nonexistent agent's store — archiving or deleting a thread silently closed
nothing. The store now resolves per routed agent via listAgentIds and every
agent's matching sessions are deleted.

* fix(discord): type thread session cleanup across agent stores

* fix(discord): scope thread-session scan per agent and keep it read-only

* test(discord): cover thread deletion across agent stores
2026-08-07 12:08:36 -07:00
Peter Steinberger 5a795f4dda fix(qa): require a fresh reply and real tool use after switching models (#119662)
* fix(qa): require a fresh reply after switching models

* fix(qa): prove successful tool use after model switching

* fix(qa): wait for the new persisted model-switch tool result

* fix(qa): authenticate canonical model-switch attempt evidence

* fix(ai): preserve effective response model evidence

Punchcard-Session: golden-valley-workshop-br

* fix(agent): publish run-owned terminal receipts

Punchcard-Session: golden-valley-workshop-br

* fix(qa): require run-owned model-switch evidence

Punchcard-Session: golden-valley-workshop-br

* fix(agent): record explicit tool completion outcomes

Punchcard-Session: golden-valley-workshop-br

* fix(agent): exclude unavailable approvals from receipts

Punchcard-Session: golden-valley-workshop-br

* fix(agent): derive receipt visibility from terminal reply

Punchcard-Session: golden-valley-workshop-br

* fix(qa): bind model-switch continuity to terminal reply

Punchcard-Session: golden-valley-workshop-br

* fix(qa): project Crabline Telegram visible text

Punchcard-Session: golden-valley-workshop-br

* fix(qa): record run-owned delivery evidence

Punchcard-Session: golden-valley-workshop-br

* fix(qa): bind primary model-switch delivery

Punchcard-Session: golden-valley-workshop-br

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-08 03:05:32 +08:00
Peter Steinberger d448a25a8a refactor(test): compress repetitive fixtures in mega-tests, batch 3 (#120294)
* refactor(test): compress subagent lifecycle fixtures

* refactor(test): compress model resolution fixtures

* refactor(test): compress Telegram bot fixtures

* refactor(test): compress reply-agent e2e fixtures

* refactor(test): compress Matrix SDK fixtures

* refactor(test): compress QMD manager fixtures

* refactor(test): compress gateway chat fixtures

* refactor(test): compress gateway reload fixtures

* fix(test): preserve raw Telegram secret fixture

* fix(test): retain session fixture key type

* fix(test): preserve raw reload secrets fixture

* fix(test): retain gateway fixture parameter types
2026-08-07 11:48:46 -07:00
Peter Steinberger c25671cf27 fix(imessage): stop dropping user text that collides with recent outbound sends (#120260)
* fix(imessage): text echo matching honors message-id conflicts; own sends stop feeding the loop limiter

Two silent-drop paths in the iMessage monitor:
1. The persisted 12h echo cache matched inbound user text against old
outbound text even when the GUIDs conflicted — a user sending 'ok' within
12h of the agent sending 'ok' was dropped as an echo. The text branch now
applies the same hasConflictingMessageIds guard the media branch has;
genuine reconnect echoes still match by id or id-less entries.
2. Every from-me row fed the echo loop rate limiter, so a normal outbound
burst (agent replies, multi-chunk sends, operator phone traffic) could trip
the limiter and silently suppress the next legitimate inbound message.
'from me' is no longer counted as a loop signal, and a tripped limiter now
logs a default-level warning once per conversation instead of verbose-only.

* fix(imessage): preserve delayed echo guards
2026-08-07 11:17:06 -07:00
Peter Steinberger a68ff9961c fix(discord): surface inbound attachment download failures (#120269)
* fix(discord): surface inbound attachment download failures

* fix(discord): carry the media-unavailable notice into the agent text
2026-08-07 11:14:49 -07:00
Peter Steinberger 4188f6892d refactor(test): replace logic-bearing vi.mock factories with boundary fakes, batch 3 (#120291)
* refactor(test): exercise real session rewind policy

* refactor(test): use real Telegram media policy

* refactor(test): exercise real HTTP cancellation lifecycle

* test(gateway): prove mutations clear queued session work
2026-08-07 10:54:58 -07:00
Vincent Koc c549250bfa test(diagnostics): cover OTEL exporter contracts (#120261) 2026-08-07 23:45:32 +08:00