Commit Graph

11256 Commits

Author SHA1 Message Date
Peter Steinberger b68d13a0f0 fix(memory): bound LanceDB prompts and reload embedding config (#125567)
* fix(memory): bound LanceDB recall and reload embeddings

* fix(memory): preserve LanceDB index identity
2026-08-17 22:55:20 -07:00
Peter Steinberger 23bcaef0c1 fix: tools report terminal no-delivery outcomes (#125607)
* fix(tools): report terminal non-delivery outcomes

* fix(agents): prefer authoritative terminal replies

* fix(agents): short-circuit authoritative replies
2026-08-17 22:51:44 -07:00
Peter Steinberger 5d098cd36f fix: prefer representation-first progress cards (#125613) 2026-08-17 22:33:15 -07:00
Peter Steinberger db92131fe9 fix(gateway): allow write-scoped worktree creation (#125598) 2026-08-17 22:24:50 -07:00
Peter Steinberger 7fc3371eac fix(codex): enforce hosted search domains for web fetch (#125574)
* fix(codex): apply hosted search domains to web fetch

* fix(net): preserve allowlist error wording

* fix(codex): enforce search domains in side questions
2026-08-17 21:49:35 -07:00
Josh Avant 916aca13f3 feat: record subagent execution lineage (#122015)
* feat(audit): record subagent execution lineage

* fix(audit): type-check spawn lineage validation

* docs: preserve spawned-run lineage invariants

* fix(audit): preserve lineage for worker spawns

* fix(audit): bind worker lineage to live authority

* fix(audit): keep lineage carrier private

* fix(sessions): preserve ACP participant recording

* fix(audit): keep lineage out of runtime bearer

* fix(audit): keep lineage type private

* test(audit): match current worker claim shape

* test(audit): preserve readonly lineage result

* fix(audit): redeem spawn lineage privately

* fix(audit): preserve lineage redemption on copy

* test(audit): prove nested worker spawn lineage

* fix(audit): restore execution identity CI gates
2026-08-17 21:41:30 -07:00
Peter Steinberger 9ba8671296 refactor(agents): unify exec approval routing (#125587)
* refactor(agents): unify exec approval routing

* docs(plan): record approval route cleanup
2026-08-17 21:40:31 -07:00
Peter Steinberger 3ab27a2900 fix(cli): exit non-zero when an agent turn fails (#125557)
The gateway-routed path already mapped terminal run status to an exit code,
but the local embedded path did not, so a failed turn exited 0 while its own
JSON envelope reported status "error". Route both through the canonical
agent-run terminal outcome, and fail closed on an unrecognized status since
the gateway response carries an open string.
2026-08-17 21:31:25 -07:00
Peter Steinberger 9de3ca5fc9 test(upgrade): add high-volume SQLite survivor (#125571)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 21:19:24 -07:00
Peter Steinberger 30af09b8e3 fix(models): reject unknown providers when setting a default model (#125558)
* fix(models): reject unknown providers when setting a default model

`openclaw models set` validated only the provider/model syntax, so a
nonexistent provider was written to config with a success message while
config validate, doctor, models status and gateway startup all stayed silent.
An unknown provider now fails without changing config; an unknown model under
a known provider still saves with a warning, since the local catalog can lag a
newly released or self-hosted model. Doctor reports refs already in config.

* fix(models): avoid shadowing the repair warning and the map spread
2026-08-17 21:15:45 -07:00
Peter Steinberger b7ccf62fbd fix(voice-call): keep Funnel off occupied HTTPS ports (#125552)
* fix(voice-call): support alternate Tailscale HTTPS ports

* refactor(voice-call): keep Tailscale DNS lookup private

* fix(voice-call): preserve config normalization contract
2026-08-17 21:04:17 -07:00
Peter Steinberger 1acabe40a9 feat(voice-call): let realtime agents end calls (#125525) 2026-08-17 20:39:13 -07:00
Peter Steinberger 4ed01969e8 refactor(agents): unify exec approval wait outcomes (#125524)
* refactor(agents): unify exec approval wait outcomes

* docs(plan): record approval wait cleanup
2026-08-17 20:23:10 -07:00
Shakker aa8be5acf9 fix: correct setup provider drift diagnostics (#125523)
Stop reporting metadata-only setup provider descriptors as missing runtime registrations while preserving genuine provider, CLI, loading, and registration diagnostics.

Fixes #125506.
2026-08-18 03:54:47 +01:00
Peter Steinberger b485f0c627 refactor(agents): unify exec approval decisions (#125503)
* refactor(agents): unify exec approval decisions

* docs(plan): update runner deletion status
2026-08-17 19:06:28 -07:00
Peter Steinberger 3d00611793 fix(config): keep missing env references unavailable without rejecting literals (#125455)
* fix(config): record unresolved env references as facts

Preserve missing-substitution provenance through config snapshots and runtime activation so unresolved credentials remain unavailable without misclassifying intentional literal placeholder text.

* fix(gateway): preserve config facts across credential clones
2026-08-17 19:05:29 -07:00
Peter Steinberger 75fcaba919 fix(voice-call): survive gateway in-process restart and stop CLI dead-ends (#125458)
* fix(voice-call): survive gateway in-process restart and stop CLI dead-ends

The gateway's in-process restart (SIGUSR1 config reload) reuses the cached
plugin registry, so service stop/start run on the same retained voice-call
registration. Generation fencing from #120289 treated that restart as a stale
actor: stop retired the generation forever, the next start silently bailed,
and every voicecall.* RPC answered UNAVAILABLE "runtime generation is
retired" while the webhook never rebound.

- Registrations now hold a replaceable generation: service start after stop
  mints a fresh generation, takes over a running slot owned by a retired
  predecessor, and reports start failures to service health instead of
  silently returning.
- The voicecall CLI classifies gateway failures with typed guards instead of
  message substrings: standalone/store fallback only when the gateway is
  genuinely absent; reachable-but-failed (request errors, auth, timeout)
  exits with actionable text; a standalone webhook port collision explains
  that a running Gateway probably owns the port instead of raw EADDRINUSE.
- Plugin SDK gateway-runtime exports structural isGatewayTransportError /
  isGatewayClientRequestError guards (+2 documented surface budget).
- Regression coverage: same-registration stop/start restart, retired-owner
  takeover, typed CLI fallback classification, and a real token-auth gateway
  server routing voicecall.status through callGatewayFromCli.

* refactor(voice-call): split CLI modules and dedupe gateway fallbacks

Collapse the four duplicated gateway-or-runtime command blocks (speak, dtmf,
end, continue fallback) into one generic runGatewayManagerCommand helper —
the continue command owns its legacy-method fallback and operation polling
via a gatewayCall closure, so the helper carries no per-command policy.
Smoke reuses the shared initiateVoiceCall path instead of a bespoke
fallback.

Split the 988-line cli.ts into concept modules (cli-gateway-call,
cli-call-log, cli-command-io) and drop its grandfathered max-lines
suppression plus the now-stale max-lines and assertion-safety baseline
entries (shrink-only ratchet maintenance).

Behavior-frozen: stdout/exit semantics unchanged; net -2 production LOC.

* fix(voice-call): redact gateway URLs in CLI operational errors

ClawSweeper P1: the operational-error formatter interpolated the raw
connectionDetails.url, so a configured gateway URL with userinfo or query
tokens would print credentials into terminal output. Redact the composed
message once with the canonical net-policy redactor (also covers
remote-controlled close-reason text), exported through the plugin SDK
gateway-runtime subpath (+1 documented surface budget). Regression test
covers a credential-bearing URL in both the URL and message fields.
2026-08-17 18:59:19 -07:00
Peter Steinberger b5b17c654b fix: keep Workboard visible in the sidebar (#125473)
* fix(ui): keep workboard in sidebar navigation

* test(ui): align workboard navigation ownership

* fix(ui): preserve saved workboard sidebar slots

* test(ui): shrink assertion safety baseline

* fix(plugins): bind native routes to bundled owners

* refactor(plugins): isolate native route policy
2026-08-17 18:44:39 -07:00
Peter Steinberger 49cdd54259 feat(control-ui): move the Ask OpenClaw toggle to the sidebar footer (#125486)
* feat(control-ui): move the Ask OpenClaw toggle to the sidebar footer

The sidebar bottom now mirrors its top: big agent selector with inline
chevron + small new-session square above, big account identity card with
inline chevron + small lobster toggle below. The account chevron moves
from the row's far right to directly after the name, matching the top
header treatment; the freed edge hosts the toggle. The old top-left
shell-chrome placement is removed along with its four-button width
reservation (which read-scoped clients paid for without seeing the
button). Scope gating, palette entry, and panel wiring are unchanged;
gating regressions moved to the sidebar cases.

* fix(control-ui): keep Ask OpenClaw reachable while the nav is collapsed

Address the ClawSweeper P1: desktop collapse hides the sidebar entirely
(display:none, no rail), which would have removed the toggle's only
persistent surface. The lobster now joins the chrome strip exactly while
the nav is collapsed — the footer stays its home — and the strip's
collapsed width reserves four controls for that state. Regression covers
collapsed-present/expanded-absent/read-scope-absent.
2026-08-17 18:26:53 -07:00
Peter Steinberger bb1ce58514 refactor(gateway): remove obsolete reverse worker tunnel (#125465)
* refactor(gateway): remove reverse worker tunnel

* test(gateway): align worker transport expectations

* docs(gateway): clarify cloud worker ingress
2026-08-17 18:19:52 -07:00
Peter Steinberger 1ca4103fe9 fix(voice-call): expose realtime/streaming stream paths through tailscale serve/funnel (#125468)
* fix(voice-call): expose realtime/streaming stream paths through tailscale serve/funnel

Tailscale serve/funnel now auto-exposes the realtime and streaming WebSocket stream paths when those audio modes are enabled; previously Twilio <Connect><Stream> could not reach wss://<ts-host><streamPath> and realtime calls dropped after ~1s with no log.

Also: CLI voicecall expose mounts/clears stream paths symmetrically, partial tailscale mounts roll back on failure, and a warning now fires when a call's stream WebSocket never arrives within the token TTL. Reported/observed live by Peter Steinberger.

* fix(voice-call): make tailscale stream exposure atomic

Preserve configured public Tailscale prefixes when mapping realtime and streaming routes, and roll back the full route set when any mount fails. The CLI now uses the same transactional setup path and reports failure instead of accepting a partial exposure.

* fix(voice-call): expose Twilio's configured streaming path

Keep realtime routes under the public webhook prefix they advertise, while mounting streaming.streamPath exactly as Twilio emits it. This preserves the canonical public-to-local route list without expanding the provider API outside the scoped repair.
2026-08-17 18:10:45 -07:00
Peter Steinberger fab7fa9910 improve(ui): rebuild agent GitHub identity panel on settings primitives (#125472)
The panel from #125199 rendered raw wire enums in code tags, used
form-grid/field markup whose styles the agents page never loads (bare
unstyled inputs outside the card), referenced non-existent avatar
classes, and put callouts inside the settings group. Rebuild it on the
canonical settings primitives: status rows with dot status and friendly
source/evidence labels, a System/This Agent segmented scope control,
the settings secret input (gains a disabled prop), a danger status row
for errors, and a quiet-inherit + primary-save action row. Retitle to
"GitHub Identity" and move it below Tool Access and Available Right
Now. Add a .settings-account primitive for the 20px round avatar.

Live-tested on an isolated dev gateway: native-credential verify via
the GitHub API, segmented scope switching, and the empty-token error
row. Controller behavior unchanged.
2026-08-17 18:09:22 -07:00
Josh Avant aea7ee7088 fix(matrix): keep user ID authorization case-sensitive (#125432)
* fix(matrix): preserve case-sensitive user IDs

* docs(matrix): clarify exact user ID casing

* fix(matrix): preserve exact IDs during resolution

* docs(matrix): clarify approval target casing
2026-08-17 18:08:25 -07:00
Peter Steinberger 6b72d65ffe feat(ui): preserve composer drafts across restarts (#125332)
* feat(ui): preserve composer drafts across restarts

Persist draft text and attachment Blobs in browser-local IndexedDB, scoped to Gateway credentials and session or New Session targets. Clean up durable data after successful send or creation, attachment removal, and session deletion.

* fix(ui): preserve text when draft attachments exceed cap

preserve text-only durable fallback for oversized attachments; serialize visible Incognito transition with its storage fence; document retention and disposal.

* test(ui): make draft retirement proof isolate-safe

The shared isolate:false UI suite exposed an order-dependent module mock; exercise and settle the real IndexedDB boundary instead.

* style(ui): format session mutation imports

* fix(ui): keep incognito drafts memory-only

* perf(ui): lazy-load durable draft storage

* fix(ui): sequence durable draft transitions

* fix(ui): restore text-only new session drafts

Programmatic draft restoration must not advance the user-mutation generation; real user input continues through setMessage.

Move navigation transition ownership into the existing handoff module as a behavior-neutral extraction that keeps the submission owner within max-lines.

* fix(ui): restore text-only drafts without import cycles

Complete the text-only restore fix by moving started-session route transitions into a leaf module. This keeps max-lines ownership clean without reintroducing the Madge cycle.

* fix(ui): reconcile attachment handoffs with durable drafts

Restore programmatic attachment handoffs without recording a user mutation. Cover stale navigation state losing to newer durable drafts across two pages and a fresh page.

* fix(ui): start durable attachment writes before teardown

Start each CAS IndexedDB write and retirement immediately so text and attachment transactions register before page teardown. IndexedDB readwrite ordering and draft revisions keep snapshots serialized.

* fix(ui): persist New Session drafts before teardown

Accept the committed predecessor or a known in-flight local write ID atomically so New Session writes can start before teardown without spurious local-lineage conflicts.

Reset cached lineage when authoritative storage is missing and re-snapshot the still-current edit.
2026-08-17 17:56:20 -07:00
Peter Steinberger 720da745d9 fix(voice-call): keep realtime calls alive through brief stream reconnects (#125469)
* fix(voice-call): grace realtime stream disconnects

Share reconnect grace by CallSid and stream ID across classic and realtime streams while cleaning realtime bridge resources immediately.

Log terminal call reasons and document Twilio inbound voice and status callback setup.

* test(voice-call): align reconnect grace after rebase

Preserve the newly landed realtime generation and inactivity coverage while updating its terminal expectations for shared delayed finalization.

Remove the redundant replacement cross-product case so the lifecycle suite remains below the max-lines limit.
2026-08-17 17:51:46 -07:00
Peter Steinberger 85336be36d fix(cli): honor automation gateway port options (#125474) 2026-08-17 17:39:39 -07:00
Peter Steinberger 5028ce87b0 fix(code-mode): show the final tool surface in debug logs (#124934)
* fix(code-mode): isolate and harden diagnostics

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

* fix(code-mode): share payload diagnostics across wrappers

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

* fix(code-mode): preserve transport debug behavior

* refactor(code-mode): simplify tool observer carrier

* refactor(code-mode): keep spread-safe observer metadata

* test(qa-lab): allow elapsed cron wait budget

* docs(code-mode): preserve transport debug contract

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 17:32:14 -07:00
Peter Steinberger b295ae1625 docs(onboard): match classic setup order (#125454)
* docs(onboard): match classic setup order

* docs(onboard): align first-run setup order
2026-08-17 17:19:31 -07:00
Peter Steinberger e3de722971 refactor(tooling): consolidate baseline ratchets (#125459) 2026-08-17 17:17:49 -07:00
Peter Steinberger 244712f69a fix(voice-call): tear down realtime calls on stream close and media inactivity (#125463)
Realtime call teardown previously depended on an object-identity guard
that silently skipped ending the call record when bridge instances were
replaced, and had no transport-liveness backstop: a WS close that never
propagated left an answered call running forever. Bindings are now
socket-bound with current-generation terminal ownership, predecessor
audio is retired on successor admission (the overlapping-voices bug),
a 30s media-inactivity watchdog with 2s grace ends calls whose
transport dies silently, and every realtime call end is logged with
its cause.
2026-08-17 17:17:47 -07:00
Peter Steinberger a996ea25d9 fix(update): support npm before lifecycle allowlists (#125452) 2026-08-17 17:01:23 -07:00
Peter Steinberger b228c83bfc feat(dashboard): add session:progress board tile rendering the live progress card (#125438)
* feat(dashboard): add session:progress board tile rendering the live progress card

Advertise the core-owned widget kind via hello controlUiWidgetKinds at operator.read.
Render it inline without an iframe from the session-progress-cards store.
Pin it with dashboard tool widget_put using pluginKind session:progress and optional props.sessionKey.
Follow up the progress-card unification from #125125.

* fix(dashboard): surface session progress load failures

Record protected progress-card read failures in the shared per-session store.
Render an actionable board-tile error with retry instead of indefinite loading.
Cover the rejected-read and successful-retry flow at the widget boundary.

* fix(dashboard): honor progress tile access and activity

Avoid progress-card reads while a retained board is inactive.
Distinguish sharing denial from transient load failures and show the correct remedy.
Qualify cross-session pinning docs and cover activation plus denial behavior.
2026-08-17 16:56:23 -07:00
Peter Steinberger aeee426180 feat(control-ui): persistent Ask OpenClaw companion with global toggle (#125107)
* feat(control-ui): persistent Ask OpenClaw companion with global toggle

The custodian surface now behaves like the persistent machine-wide agent it
already is on the Gateway: the session id persists in localStorage so a
reopened surface rebinds to the live engine (wizard and approval state
survive close/reopen), the durable transcript is refetched when a surface
opens or the gateway reconnects (idle-gated so active question/wizard cards
are never clobbered), and the panel toggles from anywhere via the shared
panel-toggle contract, a command-palette action, and an admin-gated lobster
chrome button.

One server-side line: the openclaw.chat owner-mismatch rejection now carries
the existing structured session-invalidated details so persisted clients
re-mint their id from a closed code instead of matching error prose.

No gateway events, no protocol schema changes, no polling. Splits
(session-identity/variant modules, session-lifecycle and panel-toggle test
files) keep the touched files under the max-lines ratchet.

* fix(control-ui): coerce custodian toggle detail without a type assertion

The assertion-safety ratchet holds custodian-panel.ts at zero uncommented
assertions; parse the toggle CustomEvent detail through the canonical
record-coerce guard and literal narrowing instead of casting.

* fix(control-ui): delete unused CustodianPanelToggleDetail export

The record-coerce toggle parsing left the exported type without a
production consumer; the deadcode gate rightly flags it. The palette test
keeps a local shape.

* test(control-ui): select the palette custodian item via keyboard

Async session-search results can reflow the palette list mid-click on slow
CI runners, silently dropping the positional click; keyboard selection of
the asserted-active item is atomic against reflow. Also stage the reopen
wait (panel section, then text) for sharper failure localization.

* fix(control-ui): project live wizard state on rejoin and scope-gate the toggles

Address both ClawSweeper P1 findings. The welcome-only rejoin of an
existing session now routes through engine.decorateRejoinReply (the
existing ChatWizardHost projection), so a reconnecting client re-renders
the live wizard/question controls the session still awaits; the stale
welcome question only fills in when no interaction is live. The chrome
button, palette action, and deferred panel loading now use the
scope-aware canCallGatewayMethod gate (operator.admin) that the session
store already used, so advertised-but-read-scoped clients see nothing.

* test(control-ui): fix the cloud-workers e2e flake at both roots

The mocked config.get stayed frozen at the empty initial config while
patch responses advanced, so a config-store reconciliation refetch could
flap the snapshot to empty and saveProfile silently dropped the next
save; the mock now stays consistent before each patch resolution. Also
give waitForRequest an opt-in after-cursor: it is satisfied by any prior
same-method request and returns the latest match, so a second wait could
assert against the stale earlier request; the cloud-workers waits pin it
(15x green locally, previously failing 1-in-3).

* fix(ci): cover rejoin projection in sibling engine mocks; bump startup baseline

The greeting-welcome and session-ownership suites' engine mocks now
export decorateRejoinReply like the handler requires. The Control UI
startup-JS baseline moves 337511 -> 338920 B via the documented update
command: the shell chrome toggle, palette action, and scope-aware gating
are genuine startup surface (~1.4 KiB gzip, within the committed
ceiling).

* fix(control-ui): settle interrupted structured replies and racing turns on rejoin

Address both ClawSweeper reconnect P1s. A submitted question/wizard reply
with an unknown outcome now triggers a full session rejoin on reconnect
instead of being blocked by its own uncertainty flag: the Gateway projects
whether the answer was consumed and which control is live. A restored
persisted id also arms a one-shot rejoin barrier: the welcome-only request
queues behind any in-flight turn on the Gateway's per-session queue, so a
post-response history refresh deterministically surfaces rows a racing
turn persisted after the initial fetch. The open-agent handoff moved to
custodian-navigation (its owner) to keep the store under the size cap.
Live-Gateway proof (isolated state dir, real gpt-5.6-luna turns): video
and screenshots on the PR.

* test(control-ui): reopen via the chrome toggle in the custodian e2e

The palette click-through composition proved timing-flaky on loaded CI
runners in three different ways while adding no coverage: the palette
action's dispatch is pinned by the palette unit test and the event-opens-
panel path by the chrome-toggle step. Keep the gated palette entry
assertion + screenshot; reopen through the chrome path.

* fix(control-ui): keep the agent-handoff path helper module-local

The store now routes through performCustodianAgentHandoff, leaving the
path builder without external callers; the deadcode gate rightly flags
the export.

* fix(control-ui): run the rejoin barrier even when a live control projects

The racing-history refresh happens before the reply/control message is
appended, so skipping it for projected wizard/question rejoins had no
purpose and lost rows a turn persisted while the page was closed mid-
wizard. Regression covers the live-step rejoin reconciling racing rows.
2026-08-17 16:28:43 -07:00
Peter Steinberger 44e8b6f12b fix(onboarding): stop printing gateway token URLs (#124687)
* fix(onboarding): stop printing gateway token URLs

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(onboarding): finish token-free handoff cleanup

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 16:23:16 -07:00
Josh Avant beebeac11d fix(gateway): restore external Tailscale Serve and Funnel proxies (#125412)
* fix(gateway): allow trusted external Tailscale routes

* fix(gateway): require auth for external Funnel

* docs(gateway): clarify external Funnel probe behavior
2026-08-17 16:01:35 -07:00
Peter Steinberger 6e458d84bf feat(agents): configure per-agent GitHub identities (#125199)
* feat(agents): add managed GitHub identities

* fix(agents): use opaque GitHub setup handles

* style(codex): format managed shell environment call

* refactor(agents): own managed GitHub process identity

* chore(config): refresh baseline after rebase

* fix(ci): satisfy managed GitHub identity gates

* fix(ci): repair managed GitHub identity checks

* test(agents): align GitHub identity CI coverage

* fix(codex): scope login shell isolation

* fix(agents): let managed gh profiles authenticate

* fix(agents): harden GitHub identity setup

* test(gateway): align method suffix counts

* fix(ui): serialize GitHub identity mutations

* fix(protocol): generate GitHub configure requests

* test(ui): restore timers after identity tests

* fix(ui): preserve GitHub identity mutation ownership

* fix(agents): preserve native GitHub CLI auth
2026-08-17 15:54:03 -07:00
Peter Steinberger 2fc85bdc1b refactor(workers): make worker turns node-only (#125384)
* refactor(workers): bind placement modes to transports

* refactor(workers): split provider reconciliation

* Revert "refactor(workers): split provider reconciliation"

This reverts commit 0a1f97399b23eca81e99af45dd9ea616e266de54.

* refactor(workers): split lifecycle options

* test(workers): align SSH fixture with remote exec

* refactor(workers): encode one placement mode

* fix(workers): fence persisted transport mismatches

* style(workers): keep persisted lease note concise

* test(workers): declare node access fixture modes

* test(agents): match exec notifications by receipt
2026-08-17 15:46:59 -07:00
Peter Steinberger 57e862980b feat(gateway): carry machine class through session moves (#125292)
* feat(gateway): carry machine class through session moves

Profile move targets accept an optional machineClass with new-session
parity: validated in the protocol, persisted on the durable move intent
(bare nullable column, lazy same-version ALTER), replayed exactly by
restart recovery, and selectable from the Control UI move dialog.
Moving to the current profile with a different class resizes the
session's worker.

* fix(gateway): project placement facts on chat startup

chat.startup and chat.history built sessionInfo without the placement
projection sessions.list applies, so clients merging that row erased a
live worker placement and its move intent — the Runs on Cloud chip
disappeared after any turn until a full reload.

Reuse the canonical ensureColumn helper for the move table's additive
column instead of a hand-rolled PRAGMA read.
2026-08-17 14:25:13 -07:00
Peter Steinberger 6938026f20 fix(agents): honor system owner for unscoped reads (#125318)
* fix(agents): honor system owner for unscoped reads

* fix(gateway): resolve empty auth status owner
2026-08-17 14:07:56 -07:00
Peter Steinberger 7f3b65e783 fix(plugins): expose background service failures in health (#125366)
* fix(plugins): surface service runtime failures

* chore: leave changelog to release tooling
2026-08-17 12:18:50 -07:00
Peter Steinberger 3a7df7a788 fix(hooks): honor explicit ingress targets and reject conflicts (#125351)
* fix(hooks): honor explicit ingress targets

* fix(hooks): reject blank direct agent ids
2026-08-17 11:52:45 -07:00
Peter Steinberger 45e6784338 feat(gateway): run disposable cloud workers through node transport (#125288)
* feat(gateway): converge cloud workers onto nodes

* fix(gateway): honor public URL for cloud enrollment

* fix(crabbox): execute cloud bootstrap package binary

* fix(gateway): bind cloud nodes in pairing transaction

* fix(crabbox): prefer exact installed cloud bootstrap

* fix(gateway): complete cloud node bootstrap

* fix(gateway): enforce cloud worker capability boundaries

* fix(gateway): complete cloud node migration

* fix(gateway): preserve paired node roles on teardown
2026-08-17 11:49:06 -07:00
Jacqueline Henriksen 03f43ee21c fix(ui): edit queued messages in place (#124298)
* fix(ui): restore cancelled queued message drafts

* fix(ui): edit queued messages in place

* fix(ui): isolate composer sends from row edits

* fix(ui): isolate queued edit submission guard

* fix(ui): preserve reply context for queued edits

* fix(ui): fence steer during queued edits

* fix(ui): abort stale queued edit submissions

* fix(ui): fence queued edits across panes

* fix(ui): fence peer-pane queued steers

* fix(ui): fence command-like queued edits

* fix(ui): fence removal of edited queue rows

* docs(proof): record queued edit live verification

* docs(proof): attach queued edit browser evidence

* fix(ui): fence queued row reordering during edits

* fix(ui): fence peer edits during queue reordering

* fix(ui): report cross-pane reorder conflicts

* test(ui): exercise rejected inline edit submit

* fix(ui): surface reorder conflicts in chat state

* docs(proof): record real queued-edit behavior

* docs(proof): record exact-head queue behavior

* fix(chat): fence retry during queued-row edits

* fix(chat): fence stop aliases in queued edits

* fix(chat): surface peer steer conflicts

* fix(chat): fence draft changes during history load

* fix(chat): fence annotated queue edits

* test(chat): record exact-head queue proof

* Revert "test(chat): record exact-head queue proof"

This reverts commit d7278ad9082fae40e28e6b98ca5a74e855817e6c.

* fix(chat): clear stale queued edit tokens

* fix(chat): fence stale queued edit versions

* fix(chat): invalidate rejected queued edits

* fix(ui): clarify queued edit conflict guidance

* fix(ui): report peer-edited queue reorder conflicts

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-17 10:00:00 -07:00
Peter Steinberger b834477565 fix(cli): refuse live state reset and uninstall (#125253)
* fix(cli): guard live state cleanup

* fix(cli): preserve linked paths on cleanup failure

* fix(cli): retain gateway ownership through cleanup

* fix(cli): keep cleanup planning read-only

* fix(cli): skip mutating bootstrap for cleanup

* fix(apple): keep identity locks sandbox-writable

* docs(apple): clarify identity lock domains
2026-08-17 09:44:31 -07:00
Peter Steinberger 7170a6231a feat(agents): unify agent status into a durable progress_card (#125125)
* feat(agents): unify agent status into a durable progress_card

Replace the write-only update_plan to-do tool and the fragmented plan
rendering with one durable status artifact per session: progress_card
({plan?, markdown?}, replace-on-write, 8 KiB markdown / 50-step caps).
Cards persist in a lazy-additive session_progress_cards table in the
per-agent DB (no schema-version bump), broadcast progressCard.changed,
and render from the store with exactly one live placement per view
(session rail when visible, else the composer-adjacent bar); transcripts
collapse to one-line receipts, and the sidebar hovercard shows other
sessions' cards inline (markdown + <progress>, DOMPurify allowlist, no
iframes). The three stream-derived plan renderers and their dedup
heuristics are deleted.

Codex runs disable the native plan tool per thread
(tools.update_plan.enabled=false) and receive progress_card via the
dynamic-tool bridge; compaction restore now reinjects the card (steps +
bounded markdown). Card writes still emit the legacy plan stream event so
native apps and channels keep working until their per-platform
migrations. Policy names map update_plan -> progress_card; the shipped
tools.updatePlan=false kill switch is honored.

Net -277 production LOC; -480 test LOC.

* test(agents): regenerate Codex prompt snapshots for update_plan thread-config disable

* chore(protocol): allowlist progressCard.changed for native apps pending card migration

* fix(ci): repair progress card integration checks

* fix(codex): canonicalize native progress cards

* test(gateway): reconcile progress card method order

* test(codex): stabilize native approval fixture
2026-08-17 09:44:04 -07:00
Peter Steinberger 98d7b38d48 docs: document three-layer session ownership (#125334)
* docs: document three-layer session ownership

User documentation for the session-ownership feature landed in #125057:
the immutable creator / assignable owner / participant-history model, the
Assign-to-me and Assign-to session menu actions, the sessions tool
assign_owner action, the sidebar Owners facet with Involving-me, the
pair-stack owner avatar, and agent-spawned session receipts (sessionUrl +
owner acknowledgement). Adds the sessions.assignOwner method and ownership
row projections to the protocol reference and a zh-CN glossary entry for
the new link label.

* docs: drop nonexistent header facepile overflow count

The chat header receives the already 4-capped participant projection and no
total count, so its overflow branch cannot render. Describe up to four
avatars instead (ClawSweeper P2).
2026-08-17 09:35:07 -07:00
Ayaan Zaidi d90dcc2111 feat(plugin-sdk): export saveMediaSource from media-store (#125278)
Plugins holding a remote URL had no non-deprecated Plugin SDK path to turn it into managed media; saveMediaSource was only reachable through the deprecated media-runtime barrel while docs pointed at media-store. Re-export it from the focused subpath and move the bundled qa-channel plugin off the deprecated barrel. Maintainer decision: full saveMediaSource (local path + HTTP(S)) is the supported media-store contract.

Fixes #125259
2026-08-17 12:54:52 +00:00
Peter Steinberger 4b0d573437 feat: session permission modes with worktree-scoped defaults (#124909)
* feat(gateway): add session permission modes

* feat(agents): enforce session permission policies

* test: cover session permission modes

* docs: explain session permission modes

* fix(agents): preserve apply patch default root

* feat(codex): map session permission modes

* feat(ui): add session permission controls

* test: cover session permission surfaces

* fix(agents): enforce session permissions from entry

* fix(codex): pass params object to requirements reader

* fix(codex): honor session permission modes

* fix(codex): preserve exec approval floors

* chore: revert changelog edit (release-owned)

* test: align full-mode promotion with upstream semantics

* chore(protocol): regenerate session permission models

* docs: register session permission modes

* fix(ui): use shared permission dropdown

* fix(sessions): restore permission mode contracts

* fix(ci): record session permission startup JS growth in the budget baseline

* refactor(agents): prepare session exec mode at dispatch

Host dispatch owns permissionMode→exec override preparation; the codex
plugin consumes prepared facts and the SDK barrel export is removed,
keeping the plugin-sdk surface at its recorded budget.

* test: type exec mode fixtures as ExecMode

* fix(codex): require admin scope for yolo permissions

* test: isolate codex permission command state

* ci: refresh PR checks against current main

* ci: refresh checks after gateway test repair

* test: fix main-fallout CI suites

* chore: refresh CI merge ref

* fix(worker): fence permission-mode cloud placements

* fix(sessions): clear worktree policy on detach

* chore(protocol): generate session permission mode enum

* test(gateway): type dispatch fixtures from session entries

* fix(ui): allow clearing session permission mode

* chore: refresh CI merge ref

* fix(ci): record permission picker startup growth in the budget baseline

* fix(gateway): gate session root projections
2026-08-17 04:37:35 -07:00
Ayaan Zaidi 75c5d9e208 fix(agents): show waiting reply when sessions_yield pauses a turn (#125106)
Show an explicit waiting acknowledgment when sessions_yield ends an otherwise-silent interactive turn, while keeping private resume context out of channel delivery and preserving existing visible replies.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-17 17:01:48 +05:30
Peter Steinberger 7810edca33 docs(completion): document ZDOTDIR profile path (#125247)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 04:31:21 -07:00