Commit Graph

660 Commits

Author SHA1 Message Date
Josh Lehman e51ad6845e fix(cron): preserve Codex trigger exec authority 2026-08-24 13:51:19 -07:00
Peter Steinberger bea8740981 fix(matrix): show edited messages in replies and thread context (#128763)
* fix(matrix): use edited messages in reply and thread context

* fix(matrix): narrow bundled edit records without assertions
2026-08-24 13:38:57 -07:00
Peter Steinberger a99317ef97 refactor(gateway): unify bounded chat history across transports (#128844) 2026-08-24 13:06:06 -07:00
Peter Steinberger 3c2667ca40 fix(gateway): fill older chat pages without duplicate transcript storage (#128810)
* fix(gateway): page visible chat history without duplicate storage

* chore: keep release changelog owned by release automation
2026-08-24 10:43:59 -07:00
Shakker 59abf3de62 feat: persist stateful transcript display semantics (#126943)
Persist stateful transcript display semantics through one shared reducer for incremental and rebuilt projections.

Refs #126914.
2026-08-24 17:36:21 +01:00
Peter Steinberger 3dec4e3472 refactor(gateway): unify maintenance lifecycle ownership (#128766) 2026-08-24 08:09:33 -07:00
Peter Steinberger ec091478fc refactor(slack): reuse canonical interactive block renderer (#128760) 2026-08-24 07:55:00 -07:00
Peter Steinberger a8722e74ec refactor(agents): remove provider discovery test globals (#128758) 2026-08-24 07:45:27 -07:00
Peter Steinberger 15e9bea3cb refactor(telegram): unify interactive keyboard rendering (#128728)
* refactor(telegram): unify interactive keyboard rendering

* chore(telegram): ratchet removed keyboard assertion
2026-08-24 06:24:36 -07:00
Peter Steinberger 1c0e02ccb0 refactor(gateway): remove unused resident lifecycle registry (#128710)
* refactor(gateway): remove unused resident lifecycle registry

* chore(gateway): prune deleted registry assertion baseline
2026-08-24 05:57:43 -07:00
Peter Steinberger 03658a99a9 fix(browser): stop cancelled downloads from publishing files (#128651)
* fix(browser): cancel in-flight downloads before atomic publication

* fix(browser): type download capture event and deferred fixtures

* fix(browser): ratchet down obsolete download capture assertions
2026-08-24 05:10:48 -07:00
Peter Steinberger 8fe2c1b83c perf(ui): consolidate Control UI boot chunk graph for HTTP/1.1 gateways (#128514)
* perf(ui): consolidate Control UI boot chunk graph for HTTP/1.1 gateways

The Control UI boot flow (app shell + sidebar + chat route) lazily loaded
~124 automatic chunks in one burst after the gateway handshake, which the
gateway's HTTP/1.1 transport serializes into ~24 six-connection round-trips
on high-latency links (Tailscale, remote gateways).

Add a measured boot-module manifest (ui/config/control-ui-boot-modules.json,
regenerated via pnpm ui:boot-manifest:gen) and a control-ui-boot codeSplitting
group that merges exactly that module set into a handful of chunks with
recursive dependency inclusion. Lazy islands (locales, ghostty-web, novnc,
non-default routes) keep their own chunks; stale manifest entries degrade
gracefully back to automatic chunking.

Measured on the built dist with the mocked gateway (chat route, 3 runs):
unique boot JS requests 140 -> 45, raw boot JS 3751 -> 3717 KiB, chat
composer interactive at simulated 50 ms RTT ~1600 ms -> ~575 ms.

Largest-CSS budget rises 45 -> 47 KiB for the merged boot CSS; startup JS
gzip baseline ratchets down (345049 -> 339214 B) as consolidation shrinks
the startup graph.

* chore(ui): refresh boot module manifest after rebase onto current main

* fix(ui): stop the pending lazy shell action replay loop starving boot

When a pending lazy shell action (command palette open, panel toggle)
replayed while the shell was still splash-gated, the dispatched event had
no rendered element to consume it and re-entered requestLazyElement in a
microtask cycle: request -> load -> replay -> dispatch -> request. The
cycle starved tasks (Gateway WebSocket messages included), so the boot
never finished and the recovery e2e froze on the splash screen.

Gate replay on the element actually being rendered: the controller skips
the action after load until the host's render root contains the tag, and
restorePendingLazyAction skips dispatch while a defined element is still
render-gated. The host retries after every completed update, so the replay
fires on the update that first renders the element. Regression test fails
on the pre-fix controller.

* fix(ui): re-anchor the scope-upgrade details popover before opening

wa-popover resolves its `for` target once per property change and never
re-resolves a missing or replaced anchor. The trigger with the shared id
can render after the popover's first update (the header trigger ships with
the lazy chat chunk), leaving the opened popover permanently invisible:
active popup with a native [popover] part stuck at UA display:none because
showPopover() never ran without an anchor. Re-arm the watcher when opening
while the anchor is missing or disconnected.

* test(ui): compare settled layouts in device-scope stability assertions

The 0.5px no-move assertions sampled geometry that later reflowed when the
details surface's first render fetched glyph subsets, reporting sub-pixel
drift the open never caused. Burn in the one-time open per context and
sample the baseline adjacent to the click.

* fix(ui): map the keyboard shortcuts dialog in lazy replay gating

Current main added the keyboard-shortcuts lazy shell event; the replay
gate's exhaustive event-to-element record needs its entry.

* chore(ui): refresh startup budget baseline after rebase onto current main
2026-08-24 03:55:37 -07:00
Peter Steinberger 234df15a6d chore: refresh dependencies after seven-day cooldown (#128414)
* build(deps): refresh dependencies after cooldown

Apply dependency, toolchain, action, image, and exact tool updates released by the inclusive 2026-08-16 seven-day cutoff. Adapt owner boundaries for the resulting CUA, logging, Teams, Markdown, native, and test-harness contract changes while retaining versions blocked by upstream compatibility constraints.

* fix(ui): align markdown renderer env typing

* fix(deps): align postcss and mistral peer contracts

* fix(deps): repair refreshed dependency contracts

* fix(deps): retain tslog startup budget

* fix(ci): verify Android tools with SHA-256

* fix(ci): fence Android SDK cache version
2026-08-24 03:01:54 -07:00
Peter Steinberger 7d5b986a82 fix(gateway): reclaim cloud workers before session recovery (#128597)
* fix(gateway): reclaim cloud workers before recovery

* fix(workers): fence reclaim final effects

* test(workers): track reclaim authority temp dirs
2026-08-24 02:31:44 -07:00
Peter Steinberger 12d0fd2ef8 refactor(anthropic): replace handwritten Claude sessions with Agent SDK (#128131)
* refactor(anthropic): explore official Claude Agent SDK runtime

* refactor(anthropic): replace handwritten Claude sessions with SDK

* refactor(anthropic): collapse SDK live-session ownership

* refactor(anthropic): simplify SDK ownership and preserve live skills

* fix(anthropic): fence cancelled SDK runs before process startup

* fix(anthropic): harden SDK approvals, lifecycle, and packaging

* refactor(anthropic): own SDK process trees and streamline runtime

* fix(anthropic): repair rebased packaging and legacy test fixtures
2026-08-24 01:59:16 -07:00
Peter Steinberger 53dcaaedec feat(gateway): generic operator roles for non-maintainer access (#128548)
* feat(gateway): generic operator roles for non-maintainer access

Adds gateway.roles: named role bundles over a closed capability set —
sessions.others (none/view/suggest/write), an agents allowlist, and an
operator-scope ceiling. Roles are person-level (additive user_profiles.role
column, SQLite stays at v9); users.setRole (admin-only) assigns them. With
no gateway.roles config, behavior is unchanged for solo deployments.

Enforcement is deny-by-default from a host-minted actor identity
(system vs operator+profileId on server-only client.internal, never
accepted from the wire) and covers every entry point: WS RPCs, OpenAI-compat
and Responses HTTP, tools invocation, cron, questions, usage, task
suggestions, session catalog/sharing/reads. The agents allowlist gates both
session creation and run-start on existing sessions. Subagent completion
announce and descendant wake mint explicit system authority so role
boundaries never silently drop parent notifications.

The enforcement surface is expressed through a narrow policy vocabulary
(operatorSessionCap, hasOperatorBoundary, authorizeSessionSharing) rather
than per-handler policy internals.

* fix(gateway): heal PR CI after rebase onto main

- Break import cycles: extract GatewayOperatorRoleActor leaf contract; merge
  session-group-mutation-targets into session-sharing-target-input.
- Split sessions-suggestions.test.ts (max-lines) into a visibility suite.
- Add users.setRole to the 2026.8 train registry test and regenerate the
  Kotlin protocol client.
- Startup UNAVAILABLE gating now precedes session authorization: session
  stores are not loaded during startup, so authorization reads would deny
  with a misleading non-retryable error.
- sessions.assignOwner keeps its documented visibility-authorized contract
  when no operator role caps the caller; view/suggest-capped roles still
  cannot reassign foreign session ownership.
- Test stubs updated for main's socket readyState guard (#128144) and the
  system-authority arg on channel-native resets.

* test(gateway): chat.send pending-profile dispatch carries its required session target

chat.send requires a non-empty sessionKey at the protocol level; the mutation
pipeline now rejects targetless frames before profile-dependent dispatch, so
the pending-profile test must send a realistic frame.
2026-08-24 01:20:03 -07:00
Peter Steinberger ccc4e69052 fix(subagents): hide private commentary from logs and completion announcements (#128584)
* fix(subagents): hide commentary in logs and completion announcements

* refactor(agents): remove obsolete test-only history sanitizer export
2026-08-24 00:57:53 -07:00
Peter Steinberger 68ba1ef641 refactor(xai): share responses tool request transport (#128571)
* refactor(xai): share responses tool request transport

* refactor(xai): remove unused responses body test seam

* test(xai): preserve responses request contracts at fetch boundaries
2026-08-24 00:57:28 -07:00
RoboClaw 4e82e9256b refactor(ui): remove redundant chat reset actions (#128562)
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-23 23:33:21 -07:00
Peter Steinberger f40cb158b1 fix(onboarding): preserve JSON option rejection output (#128542) 2026-08-23 23:22:54 -07:00
Ayaan Zaidi b41d5293b2 refactor(mantis): give Codex open-ended Telegram proof control (#128197)
* refactor(mantis): replace Telegram proof compiler with frozen visible replay

* refactor(mantis): let Codex own Telegram proof scenarios

* fix(mantis): isolate proof publication

* fix(mantis): bind baseline cache to revision

* chore(mantis): remove stale scenario-designer wording

* fix(mantis): align readable worktrees with trusted proof

* fix(mantis): register proof collector tooling

* refactor(mantis): keep collector functions private

* fix(mantis): publish agent-selected Telegram proof

* fix(mantis): trim proof media to final turn

* fix(mantis): fence lanes before evidence collection

* fix(mantis): verify lane termination before unlock
2026-08-24 11:47:26 +05:30
Peter Steinberger 91dc6e102a fix(ui): terminal messages no longer reload the session roster (#128397)
* perf(ui): avoid redundant terminal roster refreshes

* fix(ui): preserve filtered roster refreshes

* fix(ui): defer filtered roster snapshots

* fix(ui): classify roster snapshot eligibility

* fix(ui): fence terminal roster membership
2026-08-23 23:04:23 -07:00
Bek a5c8e00cb6 fix(codex): preserve child hooks across turns (#128485)
* fix(codex): preserve native hook relays across turns

* fix(codex): fail closed on relay renewal loss
2026-08-24 00:31:42 -04:00
Peter Steinberger 8635794d4d fix(embeddings): reject empty vectors from compatible providers (#128480)
* fix(embeddings): reject empty provider vectors

* chore(embeddings): tighten assertion safety baseline
2026-08-23 21:23:01 -07:00
Peter Steinberger 8083d4dd3f fix(memory): enforce canonical SecretRef resolution (#127699)
* fix(memory): enforce canonical SecretRef resolution

Make Gateway runtime snapshots the exclusive owner of memory SecretRef materialization. Bind embedding credentials and headers to provider-owned destinations, and fence per-agent stale reuse by the provider destination/auth contract.

Release note: Memory search resolves secret references through configured provider policy and keeps embedding credentials scoped to their intended destination.

* fix(lmstudio): preserve resolved memory headers

memory remote headers are already materialized by the Gateway snapshot and now bypass SecretRef re-resolution; provider-owned headers retain canonical resolution; final loopback request proof covers literal preservation and precedence.

* fix(memory): bind stale credentials to auth owners

Resolve memory adapter credential owners from snapshot manifest metadata, conservatively fail cold when metadata is absent, and prove Gemini/Google destination changes plus zero-egress unresolved refs.

* fix(memory): scope compatible embedding credentials

Apply destination ownership to the core compatible adapter while preserving destination-owned credentials and intentionally unauthenticated endpoints. Distinguish loopback principals, consolidate duplicate security tests, and verify the final credential boundary through a live isolated Gateway request.

* test(memory): align destination auth precedence

* fix(memory): bind credentials to query identity

Include URL query parameters in embedding destination ownership so provider credentials and headers never cross tenant boundaries.

* fix(memory): preserve query-bound embedding destinations
2026-08-23 20:36:55 -07:00
Vyctor H. Brzezowski 6669872a95 feat(ui): let admins dismiss the sidebar update indicator (#128365)
* feat(ui): let admins dismiss the sidebar update indicator

Refs #128232

* refactor(ui): clean up update dismissal flow

* fix(ui): align update action state

* fix(ui): keep update reconciliation non-actionable

* fix(ui): preserve update reconciliation visibility

* fix: validate update dismissal facts

* fix(ui): resurface active updates

* fix(ui): show applying update campaigns

* fix(gateway): preserve boot identity

* perf(ui): split sidebar update styles

* fix(test): provide captured plugin runtime
2026-08-23 19:21:10 -03:00
Peter Steinberger cee2e7759b refactor(cli): centralize onboarding and setup option ownership (#128349) 2026-08-23 13:30:03 -07:00
SunnyShu a2e4c277c0 fix(compaction): re-compact when last entry is a compaction record but context still exceeds window (#125210)
* fix(compaction): re-compact when last entry is a compaction record but context still exceeds window

prepareCompaction short-circuited to undefined whenever the last session
entry was a compaction record, treating it as a no-op signal. That proxy
does not hold: the retained context (prior summary + kept recent turns +
system prompt + injected files) can still exceed the compaction threshold,
so a session can wedge above 100% of its window while the compactor
reports nothing to do. It only becomes eligible once enough new turns
append that the compaction record is no longer last.

Drop the last-entry-is-compaction-record short-circuit so the existing
re-compaction path stays reachable: prepareCompaction continues to walk
the retained tail, and when there is compactable content the prior
summary flows through previousSummary into UPDATE_SUMMARIZATION_PROMPT.
The empty-branch and last-entry-is-reset no-op guards are preserved, and
the existing messagesToSummarize.length===0 guard still returns undefined
when there is genuinely nothing new to summarize.

Related to #120290

* fix(compaction): harden re-compaction state handling

---------

Co-authored-by: Altay <altay@hey.com>
2026-08-23 22:10:00 +03:00
Peter Steinberger 86d6742da6 fix(cli): honor selected agent when inspecting audio providers (#128292)
* fix(cli): honor parent agent when inspecting audio providers

* fix(ci): ratchet audio cli assertion baseline
2026-08-23 10:07:54 -07:00
Peter Steinberger 1d54ce376e fix(agents): reject notices as terminal fallback and completion replies (#128269) 2026-08-23 09:20:26 -07:00
Vyctor H. Brzezowski f9b5657cbd fix(sessions): preserve concurrent appends across reset (#127842) 2026-08-23 13:15:06 -03:00
Peter Steinberger 7d816a2a06 test: shrink Discord assertion baseline (#128203)
Amp-Thread-ID: https://ampcode.com/threads/T-01a021f5-984a-7628-a30c-491c166ff247

Co-authored-by: Amp <amp@ampcode.com>
2026-08-23 05:16:57 -07:00
Peter Steinberger 1475b67111 fix(discord): deliver embed-only and component-only messages (#128152) 2026-08-23 05:01:17 -07:00
Vincent Koc 4d696fbe0d refactor(plugins): unify synchronous message hooks (#127797) 2026-08-22 22:15:31 -07:00
Vito Cappello 5ddf381eed fix(channels): preserve gateway context for inbound turns (#127962)
* fix(channels): preserve gateway context for inbound turns

* fix(plugin-sdk): type bound channel reply dispatcher

* fix(channels): carry bound reply dispatchers

* fix(channels): keep reply carrier internal

* fix(auto-reply): consolidate dispatcher type imports

* fix(channels): keep reply dispatch typing internal

* fix(channels): derive inbound reply dispatcher types from turn plan

Keep ChannelRuntimeSurface identical to main: adapters read the bound
dispatchReplyFromConfig through the existing PluginRuntime["channel"]
wiring type and derive its type from the public ChannelInboundTurnPlan
contract, so the compatibility surface no longer grows a Gateway-bound
reply member.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(channels): hoist bound channel runtime casts for assertion ratchet

The assertion-safety ratchet collects SAFETY comments with a plain
ts.Scanner pass, which desyncs at the first template literal with a
substitution — comments after that point in a file are invisible, so
deep casts in monitor files cannot be SAFETY-covered. Hoist one shared
cast per call-site scope (absorbing the pre-existing buildContext
casts) and retype Discord's internal channelRuntime chain as
PluginRuntime["channel"] so dispatch reads need no assertion.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(channels): verify gateway dispatcher ownership

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* test(codex): assert sequenced node process notifications

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* docs(changelog): preserve release-owned root changelog

Channel Gateway tools preserve the owning dispatcher for Telegram, Discord, iMessage, Signal, and WhatsApp so terminal tools remain available. Thanks @VACInc.

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* test(codex): avoid shadowing process notification bindings

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-22 13:44:47 -07:00
Vyctor H. Brzezowski 70c2be7e6a fix(ui): size agent menu grid to content (#127969)
* fix(ui): size agent grid to content

* chore(ci): shrink agent menu assertion baseline
2026-08-22 13:50:38 -03:00
Vyctor H. Brzezowski 43710901ae improve(ui): make agent switching faster and more visual (#126968)
* improve(ui): refine agent switching

* test(ui): cover agent switcher behavior

* fix(ui): preserve agent menu keyboard navigation

* fix(ui): keep full agent roster reachable
2026-08-22 12:56:20 -03:00
Peter Steinberger 963fafbb16 perf(whatsapp): reuse inbound message projection (#127958)
Amp-Thread-ID: https://ampcode.com/threads/T-01a021f5-984a-7628-a30c-491c166ff247

Co-authored-by: Amp <amp@ampcode.com>
2026-08-22 07:51:03 -07:00
Ayaan Zaidi 71b5de4061 fix(agents): resolve pdf tool models through the canonical resolver (#127952)
Inside gateway runs the prepared model runtime is a static snapshot whose
ModelRegistry is empty on a fresh state dir; configured models are served
through the snapshot's prepared facts. The pdf tool resolved candidates via
the registry-only resolveModelFromRegistry helper, so every fallback
candidate failed with `Unknown model` while the main turn and image tool
(already on resolveModelAsync) worked.

Resolve each pdf candidate through resolveModelAsync with the prepared
stores, matching the image sibling, and delete the registry-only helper.
Adds a regression test that acquires a real static prepared runtime on a
fresh state dir with a config-inline model.

Observed live: Mantis run 32574012855 (both lanes died in the pdf bridge).
2026-08-22 20:02:07 +05:30
Ayaan Zaidi 5248c2fac7 fix(sqlite): isolate read-only snapshot preparation to stop WAL lock drops (#127855)
Runs prepareSqliteReadOnlyLocation[Sync] in a short-lived child process so POSIX close() can no longer drop the gateway's WAL locks (the #125744 producer), and adds a Linux WAL sidecar split-brain tripwire that invalidates and evicts a connection whose -wal/-shm fds no longer match the on-disk sidecars. Regression net: F_GETLK lock-survival test plus platform-agnostic smoke/error tests.
2026-08-22 11:39:18 +00:00
Ayaan Zaidi 460f5b6c61 perf(mantis): parallelize proof builds and warm caches (#127798)
* perf(mantis): parallelize proof builds and warm caches

* fix(mantis): size build image for the copied pnpm store

* chore(ui): refresh startup JS gzip baseline after streamed-markdown perf work

Identical source measures 345034-345058 B across builds while the
committed baseline left only a 9 B margin under the 512 B ratchet
tolerance, so build-artifacts flips on gzip nondeterminism (green on
main run 32559609413, red on PR run 32559442295, red locally).
Regenerated with scripts/check-control-ui-performance.mts
--update-baseline; the 350 KiB hard ceiling still bounds creep.
2026-08-22 07:53:36 +00:00
Peter Steinberger 89e38cfef9 fix(tui): stop local shell descendants on exit (#127652)
* fix(tui): own local shell process scopes

Keep local shell root results independent from authoritative process-scope
extinction, and make TUI shutdown cancel and join its ProcessSupervisor scope.
On Windows, create commands atomically inside a retained non-breakaway Job
Object and prove extinction from exact Job accounting.

Fixes #127488

* fix(process): preserve optional extinction waits
2026-08-21 17:01:09 -07:00
Peter Steinberger 5165fbb4e7 refactor(process): supervise Claude node invocations (#127475)
* refactor(process): supervise Claude node invocations

* fix(process): preserve exact node invocation environment

* test(telegram): await album reply dispatch deterministically
2026-08-21 15:36:52 -07:00
ClawSweeper 229ce32e32 fix(ui): align run history dropdown text (#127443)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-21 13:12:10 -07:00
Peter Steinberger 1353ce0995 feat: run Codex sessions on approved paired devices (#127202)
* feat(codex): execute paired-device sessions over node carrier

* fix(node-host): preserve approved invocation session identity

* fix(codex): observe paired-node execution leases before handshake

* fix: fence paired-device placement and Codex execution owners

* fix: satisfy paired-device placement CI ownership guards

* fix(codex): reject credentialed paired-node URL parameters

* fix(codex): fence nested remote HTTP session credentials

* fix(codex): scrub node process URLs and preserve plaintext HTTP

* test(codex): republish node inventory after capability approval
2026-08-21 12:50:26 -07:00
Josh Avant 0b85966072 fix gateway conversation route ownership (#126424) 2026-08-21 12:20:21 -07:00
Sasan 6aced3350d fix(ui): Model Providers usage cards stay empty after a failed usage.status (#120301)
* fix(ui): recover provider usage after transient gateway failures

Keep failed provider-usage Results cold across Models and Usage direct and preloaded paths. Preserve canonical Gateway lifecycle ownership, request epochs, and route provenance.

Co-authored-by: Sasan Sotoodehfar <sasan1200@gmail.com>

* test(ui): shrink provider assertion safety baseline

Drop the obsolete grandfathered non-null assertion after moving provider probe-result policy into its owner.

Co-authored-by: Sasan Sotoodehfar <sasan1200@gmail.com>

* test(ui): tolerate browser font geometry rounding

Match existing chat-layout two-pixel renderer tolerance on both completed-work spacing boundaries.

Co-authored-by: Sasan Sotoodehfar <sasan1200@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-21 11:59:55 -07:00
Vincent Koc 1da74794b6 fix(release): establish immutable release plan contract (#127008)
* fix(release): define immutable release plan contract

* fix(release): harden immutable plan authority

* fix(release): tighten release plan authority

* fix(release): share plugin publication authority

* fix(release): verify plan authority remotely

* fix(release): track ClawHub publication authorities

* fix(release): trust remote tooling tag identity

* fix(release): close plugin publication authority

* fix(release): align npm authority selection

* fix(release): bind plans to validation intent

* fix(release): require qualification cadence

* fix(release): reject lossy canonical values

* fix(release): narrow qualification cadence

* fix(release): bind plan parser dependency

* fix(release): add tagless diagnostic plans

* fix(release): attest release plan parser tree

* fix(release): isolate verified plan parser snapshot

* fix(release): verify plan tooling before execution
2026-08-21 11:24:22 -07:00
ClawSweeper ebdb6115dd feat(ui): compact mobile chat header (#126788)
* feat(ui): compact mobile chat header

* refactor(ui): move mobile status into session menu

* fix(ui): close mobile status menu before details

* test(ui): follow compact header actions

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-21 06:54:41 -07:00
Peter Steinberger 718dacc46a fix(fleet): publish backups without partial finals (#126942) 2026-08-20 19:13:53 -07:00