Commit Graph

7899 Commits

Author SHA1 Message Date
Peter Steinberger 03be260e5b fix(lint): assertion SAFETY ratchet — exempt as-unknown, absorb merge drift (#124445)
* fix(lint): exempt as-unknown from SAFETY ratchet and rebaseline for merge drift

* chore(lint): refresh assertion baseline after rebase
2026-08-15 23:10:02 -07:00
Peter Steinberger 6aa27d6ecd refactor: retire August compat windows (embedding API, pi aliases, target parser, spawning hook, setup exports, WhatsApp inbound aliases) (#124416)
* refactor(plugin-sdk): retire embedded Pi aliases

* refactor(channels): retire explicit target compatibility

* refactor(plugins): retire subagent spawning hook

* refactor(plugin-sdk): retire shipped channel setup exports

* refactor(whatsapp): retire inbound callback aliases

Proof: focused build and WhatsApp E2E green; broad WhatsApp suite 188/189 files green. extensions/whatsapp/src/monitor-inbox.policy.test.ts flakes only in the parallel batch and passes isolated (10/10).

* refactor(plugin-sdk): retire memory embedding registrar

Migrate every bundled provider and manifest to registerEmbeddingProvider and contracts.embeddingProviders. Preserve memory-specific batching, local-service acquisition, index identity, and auto-selection through the canonical generic registry adapter, then remove the parallel registrar, registry, diagnostics, contracts, tests, and docs.

* chore(plugin-sdk): tighten retired surface budgets

Pin the post-retirement public SDK surface to 144 entrypoints, 4,312 exports, 2,564 callable exports, and 1,133 deprecated exports; agent-harness-runtime now permits exactly nine deprecated exports.
2026-08-15 22:43:47 -07:00
Peter Steinberger 1384e277af refactor(types): enforce chained-assertion guard in AI and UI (#124361)
* refactor(types): drain chained-assertion ledger — ai and ui

* refactor(ui): extract chat state contract

* fix(ai): preserve strict Claude request cleanup

* test(ui): synchronize terminal timeout clock

* fix(ui): validate observer digest before run mutation
2026-08-15 22:25:42 -07:00
Peter Steinberger 6335e358f3 fix(ci): keep Crabbox dependencies intact after pnpm dlx (#124423)
* fix(ci): isolate Crabbox pnpm dlx state

* fix(ci): clarify hydrated modules errors
2026-08-15 22:13:26 -07:00
Peter Steinberger 203aafc415 feat(lint): SAFETY-comment assertion ratchet + repo deslop skill (#124359)
* feat(lint): add SAFETY-comment assertion ratchet

* feat(skills): add repo deslop skill

* fix(lint): refresh initial assertion baseline

* chore(lint): align assertion baseline with main

* chore(lint): sync baseline with current assertion ledger

* test(ui): stabilize Control UI E2E waits

* chore(lint): sync narrowed assertion ledger

* chore(lint): sync fully drained assertion ledger

* fix(lint): close assertion ratchet bypasses
2026-08-15 22:03:48 -07:00
Peter Steinberger acbbff19ba refactor(types): drain chained-assertion ledger — extensions (#124378)
* refactor(types): drain chained-assertion ledger — extensions

* fix(types): parse Matrix summary events at the boundary

* style(types): satisfy extension map lint

* style(types): name the Tlon image marker cleanly

* fix(browser): preserve deep MCP snapshots iteratively
2026-08-15 20:55:01 -07:00
Josh Lehman a0498f7a9c fix: restore native OpenAI web search in packaged runs (#124215)
* oc-e13.2: preserve web search failure evidence

* oc-e13.2: include provider owners in runtime plans

* oc-e13.2: prepare provider owners before harnesses

* oc-e13.2: retain provider selections in runtime owners

* oc-e13.2: keep harness selection helper internal

* test(agents): cover prepared runtime registry loads

Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-15 20:30:41 -07:00
Peter Steinberger bb68ad057c refactor(types): drain chained-assertion ledger — agents (#124354)
* refactor(types): drain chained-assertion ledger — agents

* fix(agents): preserve non-configurable stream iterators

* refactor(agents): call provider failover hook directly
2026-08-15 20:28:31 -07:00
Peter Steinberger 6bbc57e526 refactor(types): drain chained-assertion ledger — core (#124351) 2026-08-15 19:41:31 -07:00
Peter Steinberger 1ab85edb0e fix(workers): bundle workspace rsync receiver (#124339) 2026-08-15 19:23:05 -07:00
Jason (Json) 4be10d44d5 fix(ci): avoid false Crabbox auth failures during readiness (#119700)
* fix(ci): trust Crabbox doctor for broker readiness

* fix(crabbox): preserve doctor auth compatibility

* fix(crabbox): retain legacy auth validation

* fix(ci): trust structured Crabbox doctor readiness

Punchcard-Session: calm-meadow-summit-bc

* fix(ci): trust structured Crabbox doctor readiness

* fix(ci): satisfy Crabbox readiness types

* test(ci): use managed temp directory helper

* test(ci): stabilize Crabbox readiness fixtures

* test(ci): preserve temp helper baseline

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-15 19:47:19 -06:00
Peter Steinberger 78502eda6d feat(workers): run device sessions from Gateway bundles (#124037)
* feat(workers): run device sessions from Gateway bundles

Install the current Gateway bundle before a device environment becomes ready, verify it at attach and tunnel boundaries, launch only from the immutable namespaced bundle directory, and retire stale environments for idempotent reprovisioning. Remove the local execution mode and preserve the node-local build claim only as temporary inventory metadata for the final projection/cleanup slice.

* docs(runners): record Gateway bundle cutover

* test(ci): repair runner validation fixtures

# Conflicts:
#	src/scripts/test-projects.test.ts

* fix(workers): surface outdated node recovery

Keep legacy runner inventory diagnostic-only while exposing the update-and-reconnect action through node, environment, provider, placement, and Control UI surfaces.

* fix(workers): reject legacy inventory with recovery

* fix(workers): bundle worker deploy closure

* test(workers): close bundle cutover gates

* fix(workers): compose browser runtime at build

* fix(workers): satisfy bundle cutover gates

* fix(workers): route temp runtime through infra

* docs(workers): align bundle host guidance

* fix(ui): fence outdated session destinations
2026-08-15 17:46:44 -07:00
Josh Lehman 3bb7fdd40b fix: restore frozen Codex release validation (#124204)
* oc-c45: fix frozen Codex release resolution

* fix(release): keep frozen Codex suites fail closed
2026-08-15 15:38:57 -07:00
Peter Steinberger ceb469abb3 refactor(release): remove summary test facades (#124259) 2026-08-15 12:41:03 -07:00
Pavan Kumar Gondhi 8668aeb969 fix(discord): bind transcript capture to source account [AI] (#118579)
* fix(discord): bind transcript capture to source account

* style(agents): keep transcript tool wiring compact

* fix(transcripts): declare account binding channels

* fix(transcripts): report effective capture account

* fix(transcripts): enforce account lifecycle ownership

* fix(transcripts): preserve cross-surface control

* fix(copilot): preserve transcript channel context

* fix(transcripts): fail closed for legacy channel owners

* fix(transcripts): add trusted legacy recovery

* fix(transcripts): preserve auto-start cleanup ownership

* fix(transcripts): reject untrusted account starts

* fix(transcripts): keep persisted ownership authoritative

* fix(transcripts): harden legacy recovery

* fix(transcripts): preserve agent ownership boundary

* fix(transcripts): scope account binding to source channel

* fix(transcripts): preserve unattributed owner isolation

* fix(transcripts): own configured captures by account

* docs(plugins): clarify transcript auto-start ownership

* test(transcripts): cover account-less recovery

* docs(transcripts): scope legacy recovery by provider

* fix(discord): reuse eligible account ordering for transcripts

* test(discord): use neutral transcript account fixtures

* fix(transcripts): keep accountless recovery local

* fix(discord): resolve transcript accounts by voice capability

* fix(transcripts): bound account resolution failures

* fix(transcripts): bound account tool output

* fix(transcripts): honor unresolved provider accounts

* fix(transcripts): preserve binding when providers are missing

* fix(transcripts): fail closed on unknown binding provenance

* fix(transcripts): qualify account lifecycle capability

* fix(transcripts): normalize provable legacy owners

* fix(transcripts): bind scheduled capture to caller authority

* fix(transcripts): preserve scheduled caller identity tuple

* fix(transcripts): preserve channel-less scheduled authority

* fix(plugin-sdk): publish transcript provider types

* fix(transcripts): use exact lifecycle ownership tokens

* fix(transcripts): preserve local ownerless lifecycle access

* fix(transcripts): allow local configured capture control

* fix(transcripts): preserve scheduled caller channel

* fix(transcripts): retain named-agent legacy recovery

* fix(transcripts): deny unrelated remote channels

* fix(doctor): validate transcript owner inference

* fix(transcripts): restrict legacy remote recovery

* fix(ci): align transcript Doctor checks

* fix(transcripts): require Doctor-owned legacy metadata

* fix(transcripts): reject unowned remote capture starts

* fix(transcripts): reject unbound Discord lifecycle calls

* fix(transcripts): distinguish legacy owner rows

* test(discord): keep unavailable account fixture typed

* fix(transcripts): mark current imports for Doctor

* fix(transcripts): complete account ownership validation

* fix(discord): restore transcript package boundary

* fix(discord): preserve bundled transcript entry boundary

* docs(transcripts): clarify Discord auto-start account

* fix(transcripts): bind account-owned imports

* fix: preserve transcript and cron policy state

* fix(cron): preserve scheduled transcript authority

* fix(discord): keep legacy transcript rows local

* fix(transcripts): narrow account ownership boundary

* fix(transcripts): preserve trusted caller ownership

* fix(discord): enforce transcript source authorization

* fix(ci): bound Control UI gzip build variance

* test(qa): align transcript scenario contracts

* fix(agents): repair rebased caller context

* fix(discord): restore rebased account ownership

* test(discord): restore voice account fixtures

---------

Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-08-15 12:10:43 -07:00
Peter Steinberger 394648c702 refactor(test): remove test-force testing facade (#124225) 2026-08-15 11:46:30 -07:00
Josh Avant fc4d5d744f fix(sessions): prevent cleanup from deleting readable transcripts (#123495)
* fix(sessions): make transcript archival atomic

* fix(sessions): stabilize SQLite archive CI

* test(gateway): synchronize lifecycle patch race

* fix(sessions): finish archive recovery accounting

* fix: key transcript archives by generation

Remeasure physical disk usage after archive publication so budget results and pruning use the bytes actually present on disk.

Refs oc-8e9

* fix(sessions): normalize doctor archive generations (oc-a28)

---------

Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>
2026-08-15 09:59:59 -07:00
Josh Lehman 8cfcc3155a test: align onboarding TTY prompts (oc-efc) (#124199) 2026-08-15 08:58:16 -07:00
Peter Steinberger b365f7ec89 test: move core coverage to owner boundaries (#124184)
* test: move core coverage to owner boundaries

* ci: lower plugin SDK surface budget
2026-08-15 07:42:53 -07:00
Peter Steinberger 4f68eee80a refactor(test): remove unused testing bag members (#124175)
* test(tooling): remove unused testing bag members

* fix(test): preserve partial spawn result stubs
2026-08-15 06:18:23 -07:00
Peter Steinberger cc9883a3d3 fix(ci): invalidate session catalog sdk declarations (#124165) 2026-08-15 06:52:35 -06:00
Peter Steinberger c98ae0f99c test(scripts): remove duplicate parser facades (#124167) 2026-08-15 05:37:04 -07:00
Peter Steinberger 1610771b1d test(tooling): remove obsolete runner facades (#124159) 2026-08-15 04:47:33 -07:00
Peter Steinberger 94a0661322 fix(cua): initialize execution resources on first use (#124156) 2026-08-15 04:30:08 -07:00
Peter Steinberger abf0ef6513 fix(computer-use): repair artifact verification and post-approval descriptor found by the Linux gate (#124128)
* fix(cua-computer): prove Linux X11 live vertical

* test(computer-use): authenticate isolated Linux rig

* fix(gateway): refresh computer use after node approval

* refactor(cua-computer): resolve the plugin manifest by static import

* fix(gateway): break plugin runtime import cycle

* fix(computer-use): bind live rig to committed helpers
2026-08-15 03:53:23 -07:00
Peter Steinberger 23f84a851a fix(build): bound CLI metadata render fanout (#124153) 2026-08-15 03:52:33 -07:00
Peter Steinberger fe5fa802fa feat(lint): enforce no-chained-type-assertions (#124119) 2026-08-15 02:13:37 -07:00
Peter Steinberger 2c0de878c6 fix(release): preflight plugin npm trusted publishers (#124095)
* fix(release): preflight npm trusted publishers

* fix(release): fully escape npm package path
2026-08-15 01:05:54 -07:00
Peter Steinberger c83c3bc3a9 fix(plugin-sdk): keep published pre-split plugin imports loading after upgrade (#124086)
* fix(plugin-sdk): keep published pre-split plugin imports loading after upgrade

Same bug class as #124041: published plugin artifacts import SDK names at
module top level, so removing them from the barrel makes the installed
plugin fail to load (voice-call/matrix doctor contracts silently never run
their migrations; whatsapp and slack channels fail outright) after a core
upgrade. Verified against the actual npm tarballs (2026.7.2-beta.7):

- openclaw/plugin-sdk/runtime-doctor: voice-call + matrix doctor contracts
  import repair names (archiveLegacyStateSource, detect/repair state DB
  schema, plugin install-path repair, removePluginFromConfig,
  createPluginStateSyncKeyedStore) that moved to doctor-repair-runtime.
- openclaw/plugin-sdk/channel-feedback: whatsapp imports
  shouldAckReactionForWhatsApp (owner policy moved in-plugin by #121257).
- openclaw/plugin-sdk/channel-outbound: slack imports
  resolveChannelProgressDraftRender (render key retired by #122927).

Adds deprecated load-only bridges with named removal windows, bumps the
SDK surface budgets with comments, and locks behavior with unit tests
plus a loader fixture that fails without the bridges.

* test(plugin-sdk): cover the repair bridge in the runtime-doctor facade surface lock
2026-08-15 01:05:08 -07:00
Peter Steinberger a8f1a0d345 test(computer-use): live end-to-end gate for both macOS providers (#123991)
* fix(computer-use): preserve semantic click observations

* fix(cua-computer): isolate desktop and window sessions

* fix(cua-computer): route cursor reads through desktop scope

* test(computer-use): add isolated macOS live proof rig

* style(cua-computer): format driver sessions

* fix(cua-computer): forward lazy desktop tools

* fix(computer-use): narrow live proof artifact path

* test(computer-use): split schema contract coverage

* refactor(cua-computer): unify session start state

* build(computer-use): register live proof entrypoint

* style(computer-use): satisfy full lint contract

* fix(computer-use): harden live proof authority

* fix(cua-computer): keep window authority immutable

* fix(computer-use): close partial sessions safely
2026-08-14 23:37:53 -07:00
Peter Steinberger 1320a0bff9 feat(lint): reject widen-then-assert type laundering (#124003)
* feat(lint): add no-widen-then-assert guard

* refactor: preserve typed boundary evidence

* refactor(types): remove redundant unknown aliases

* fix(agent): preserve replay sanitizer fallback

* fix(lint): close widen-then-assert nested-chain and const-alias bypasses
2026-08-14 22:10:19 -07:00
Peter Steinberger a32a7ae9af feat(cua-computer): verify the managed driver artifact on Windows and Linux node hosts (#123986) 2026-08-14 21:08:13 -07:00
Peter Steinberger d6e6d67adc fix(plugins): uninstall fully removes isolated npm plugin files (#123973)
* fix(plugins): remove isolated npm projects on uninstall

Ordinary uninstall now removes the whole owner-managed per-plugin npm project, including packed archives and transitive dependency debris, while shared roots and retained update generations keep their existing lifecycle behavior.

* fix(plugins): preserve failed install cleanup

Allow persistence-failure compensation to remove only a planner-validated isolated npm project root, while continuing to reject shared or ambiguous cleanup targets.
2026-08-14 21:03:12 -07:00
Peter Steinberger aec8096bbc refactor(gateway): remove obsolete worker test seams (#123970) 2026-08-14 20:30:34 -07:00
Peter Steinberger 2276dca1d3 fix(ci): route the protocol coverage record guard through record-shared
The inlined isRecord in 7e54cc9d19 tripped the coercion-helper declaration
guard on main (runs 31859544700+); the dependency-light scripts/lib/
record-shared.mjs seam is the sanctioned owner for scripts that must run
without workspace package resolution.
2026-08-14 19:44:29 -07:00
Peter Steinberger 7e54cc9d19 perf(ci): make push/PR preflight dependency-free and prune the store archive
The manifest planner closure and the protocol coverage script import only
node builtins and relative files (verified importing the full closure with
an empty node_modules under native type stripping), so push/PR preflight
drops the pnpm store restore and install (~30s off the barrier every lane
waits behind). Manual dispatches keep the tsx path for frozen targets, and
the coverage script inlines the record guard under the documented
dependency-free exception.

The store archive accretes every prior lockfile generation through
prefix-key restores (measured 2.05 GiB, ~36s restore in every hosted job);
the warmup writer now prunes to the current lockfile closure before saving.
2026-08-14 19:25:16 -07:00
Peter Steinberger a2d1b0c03b perf(ci): anchor storage-state stripe balance with measured file walls
Run 31856622489's compact-small-14 owned a 335s wall because the
storage-state hosted split packed state-migrations (27s), sqlite-snapshot
(24s), and session-cost-usage (10s) into one stripe against uniform default
weights. Anchor those files with CI checkmark walls from run 31814517685 and
lift the group hint to its observed 235s so the halves pack realistically.
2026-08-14 18:41:30 -07:00
Peter Steinberger ad508a51c2 perf(ci): overlap two tsgo graphs inside each test-type stripe
Each graph is a serial single-project build, so tsgo gains little past four
cores; run 31852071103 measured ~34s/graph on 8 vCPU versus ~42s on hosted
4-core. Overlapping two fresh shard processes per CI stripe (--concurrency 2)
uses the idle cores and roughly halves the stripe body; local runs keep the
heap-bounded serial default.
2026-08-14 17:11:39 -07:00
Peter Steinberger 7f891f4a78 fix(ui): stale tabs keep dispatching after gateway updates (#123882)
* fix(ui): reject stale bundled clients at connect

* chore: keep release notes out of runtime fix

* fix(ui): preserve stale-build admission invariants
2026-08-14 17:05:10 -07:00
Peter Steinberger 0a6b95a3df feat: cloud workers for the codex runtime (remote-exec placements) (#123743)
* feat(gateway): add remote-exec cloud placements

* feat(codex): run cloud turns through remote exec

* fix(sandbox): quote ssh_config path directives containing whitespace

Crabbox lease keys default to ~/Library/Application Support/... on macOS;
unquoted IdentityFile/UserKnownHostsFile/CertificateFile arguments tokenize
on the space and fail as 'extra arguments'. Found via live remote-exec
cloud-worker proof.

* test: consolidate gateway maintenance schedule coverage

* fix(ci): invalidate plugin sdk declarations on state changes
2026-08-14 16:46:56 -07:00
Peter Steinberger 98a8e0d63f fix(macos): prevent mismatched CUA driver endpoints (#123845)
* fix(macos): make CUA driver endpoint handoff atomic

* ci: record approved CUA env budget increase

* test: satisfy changed-gate hygiene

* style(macos): use failable endpoint string conversion

* fix(macos): strip retired CUA worker environment

* ci: constrain CUA env budget approval

* test(macos): isolate inherited CUA environment
2026-08-14 16:04:43 -07:00
Peter Steinberger 3ef7f590a7 fix(ci): invalidate plugin SDK declarations on auth changes (#123861)
* fix(ci): invalidate plugin sdk declarations on auth changes

* test(ui): await device migration overlay updates
2026-08-14 15:21:29 -07:00
Pavan Kumar Gondhi d5e89de906 fix(synology-chat): deliver attachments without forwarding source URLs [AI] (#119941)
* fix(synology-chat): host outbound attachments

* fix(synology-chat): isolate hosted media routes

* fix(synology-chat): harden hosted media limits

* fix(synology-chat): inspect hosted media content

* fix(synology-chat): reject ambiguous media routes

* fix(synology-chat): retain indeterminate media capabilities

* fix(synology-chat): mask public callback URLs

* fix(synology-chat): align callback sensitivity metadata

* fix(synology-chat): reserve media capability query keys

* fix(synology-chat): release rejected staged media

* fix(synology-chat): preserve ambiguous media handoffs

* fix(synology-chat): scan complete active media preamble

* fix(synology-chat): report validated attachment readiness

* fix(synology-chat): bound public media capability probes

* fix(synology-chat): bound hosted media responses

* test(synology-chat): model response headers read-only

* fix(synology-chat): bound hosted media reads

* fix(synology-chat): bound hosted media delivery

* fix(synology-chat): retain media through active serves

* fix(plugin-sdk): lease hosted media readers atomically

* fix(synology-chat): close hosted media review gaps

* test(synology-chat): clean up hosted media state

* fix(system-agent): canonicalize sensitive config paths

* fix(system-agent): honor runtime config sensitivity hints

* fix(config): inherit sensitive metadata

* fix(synology-chat): close latest review findings

* test(system-agent): keep config recovery checks lint-clean

* fix(system-agent): redact structured config secrets

* fix(synology-chat): harden active-content sniffing

* fix(security): close hosted media review gaps

* fix(security): close remaining hosted media review findings

* fix(system-agent): narrow dynamic owner ids safely

* fix(system-agent): narrow dynamic channel ids safely

* test(channels): isolate hosted media proofs

* fix(security): close config and hosted media review gaps

* test(plugin-sdk): split outbound media retention coverage

* test(plugin-sdk): isolate capacity store fixtures

* test(system-agent): assert config secrecy invariant
2026-08-14 17:05:20 -05:00
Peter Steinberger d27e318072 improve: make git installs use a blobless clone (#123835)
* perf: use blobless clone in git installer

* refactor(install): move clone-filter rationale above the call

Keep the file's comment convention (comments on their own lines) instead of a
150-column trailing comment, and record why blob:none is preferred over
--depth 1 plus why no fallback is needed.

Narrow the ordering test's source needle to the stable prefix so it stops
duplicating the behavioral flag assertion and no longer breaks whenever the
clone flags change.
2026-08-14 14:38:21 -07:00
Peter Steinberger af3118b187 fix(install): propagate Linux build-tool failures instead of claiming success (#123817)
install_build_tools_linux ran run_quiet_step and then returned 0
unconditionally from every package-manager branch, so a failed build-tool
install was printed as an error and immediately overwritten with a success
line. The installer emitted "Installing build tools failed" followed by
"Build tools installed", and the caller's "Continuing without auto-installing
build tools" warning was unreachable. The npm-failure recovery path likewise
reported "Build tools setup complete" and retried an install that could not
succeed. install_build_tools_macos already propagated its status; only the
Linux sibling swallowed it.

Return the package manager's exit status and collapse the five duplicated
is_root/sudo branches into one command list, which removes the bug class
rather than patching a single branch.

Verified against the live openclaw.ai script: a stubbed apt-get failure
reproduced the false success before the change and reports the honest warning
after it.
2026-08-14 13:41:17 -07:00
Peter Steinberger b822e6e425 refactor(github): consolidate guard display sanitization (#123620) 2026-08-14 13:29:21 -07:00
Peter Steinberger 58ab589da5 fix(ui): stale tabs restore terminals without owners (#123660)
* fix(ui): fence stale same-version clients by build

* test(ui): satisfy build identity lint guards

* fix(ui): complete build identity fencing

* chore: leave release notes to release prep

* test(ui): align build identity fixtures

* fix(ui): fence reconnects on pending worker

* test(ui): stabilize cross-platform update proof

* test(ui): satisfy service worker lint

* test(ui): preserve offline socket cohorts
2026-08-14 13:19:02 -07:00
Peter Steinberger 7c977e0f84 perf(ci): cut hosted CI critical path toward five-minute walls (#123780)
* perf(ci): cut hosted CI critical path toward five-minute walls

Stripe the serial core test-type graphs across two hosted jobs and drop the
duplicated tsgo:test:root pass; gate the six-part QA Smoke matrix off pull
requests unless a QA-owned surface changed; split the fat multi-config Node
shards (cli/cli-process, unit-fast isolated/fake-timers, infra
logging-process/runtime-config) and lower the hosted split ceiling to 150
predicted seconds so no compact lane owns a ~280s wall; expand tooling to
seven stripes.

* perf(ci): widen hosted test-type striping to three jobs

Run 31825922122 measured ~40s per core test-type graph on loaded hosted
runners (282s worst stripe body of the two-way split); three stripes keep
each lane near 150s body under load.
2026-08-14 13:03:52 -07:00
Peter Steinberger 3744af3d44 improve(mac): guard elevation signing identity against drift (#123764)
scripts/mac-elevation-host.sh ships as the portable installer added in
#123675, so it is deliberately self-contained and cannot source shared
constants. That forces it to duplicate ELEVATION_TEAM_ID and
ELEVATION_IDENTITY from scripts/codesign-mac-app.sh, with nothing keeping
the two copies in sync. Add a test asserting they agree, so rotation drift
fails at build time instead of on a target Mac.

Also document why the sign-time and install-time elevation verification
functions both exist: verify_elevation_app requires a notarized and stapled
bundle, so it cannot replace the sign-time check, and deleting that check
would defer every identity failure until after a notarization submission is
already spent.

No behavior change: no artifact bytes, filenames, modes, receipt fields,
signing, notarization, or install paths are touched.
2026-08-14 12:50:57 -07:00
Vyctor H. Brzezowski 3f006ba0fc fix(ui): complete mobile pairing after code redemption (#120933)
* fix(ui): complete pairing setup lifecycle

Redeemed and expired mobile setup codes stayed on screen as usable QR
codes, so a successful pairing had no visible outcome and expired bearer
material still looked live.

The Gateway now mints an opaque, non-authorizing setupId beside each
setup credential, returns its authoritative expiresAtMs, records the
terminal outcome of the exact redemption, and broadcasts
device.pair.setup.completed. Because that broadcast is dropped for
buffered operator sockets, the completion is persisted first and can be
reconciled through the new device.pair.setupStatus method: the Control UI
asks for the recorded outcome before it may present a credential as
expired, so a pairing that succeeds is never shown as a failure.

The Control UI models one closed lifecycle (selection, loading, waiting,
success, expired, error) correlated only by the active setupId, and
Pairing help now carries the external-link affordance.

* fix(ui): preserve unknown pairing outcomes

* test(ui): target pairing terminal headings

* test(ui): align pairing completion fixture

* fix(gateway-protocol): decode setup-code results from older gateways

Older protocol-v4 gateways omit the new setupId and expiresAtMs
lifecycle fields, so requiring them in the generated native model broke
decoding an existing device.pair.setupCode response. Keep both optional
at the wire boundary, require lifecycle metadata before the Control UI
enters its waiting state so a missing outcome stays visible, and cover
the legacy payload with Swift and schema regressions.

* fix(ui): surface rejected pairing dialog loads

The lazy pairing chunk could reject while its overlay was already open,
leaving the shell rendering nothing at all. Record the rejection on the
shell and render a recoverable modal with a reason and a retry so the
open action always ends in a visible outcome.

* fix(state): preserve pairing setup schema compatibility

* test(gateway): cover pairing setup release train

* fix(gateway): commit pairing setup completion atomically

* refactor(state): distinguish setup transaction helpers

* refactor(state): remove obsolete bootstrap restore path

* fix(gateway): preserve setup handoff type safety

* fix(gateway): keep pairing completion terminal after consume

* fix(gateway): validate Watch binding during setup commit

* fix(gateway): revalidate setup credential expiry at commit

* chore: refresh Plugin SDK API contracts after rebase

* fix(pairing): prune expired setup completions

* chore: retrigger CI

* fix(protocol): deduplicate setup expiry field

* fix(protocol): refresh pairing setup clients

* fix(gateway): make pairing setup completion durable

* fix(ui): retire expired pairing credentials immediately

* fix(ui): keep pairing dialog visible while loading

* fix(macos): align setup result initializer order

* fix(gateway): restore generic bootstrap retries

* chore(ui): record pairing startup budget

* chore(ui): refresh pairing startup budget

* style(gateway): format maintenance imports

* test(gateway): cover session-sharing mock

* fix(state): defer setup correlation schema

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-14 11:10:30 -07:00