Skip to content

Promote develop → main (170 commits, 2026-07-04 evening wave) - #13176

Merged
NubsCarson merged 174 commits into
mainfrom
promote/develop-to-main-20260704-2
Jul 4, 2026
Merged

Promote develop → main (170 commits, 2026-07-04 evening wave)#13176
NubsCarson merged 174 commits into
mainfrom
promote/develop-to-main-20260704-2

Conversation

@NubsCarson

Copy link
Copy Markdown
Member

[cloud-frontdoor] Promote PR: lands develop `2072cbc86c` on main. The branch tip is a merge commit whose tree is exactly develop's tree — the one conflict (`packages/cloud/api/src/stubs/elizaos-core.ts`) resolved to develop's version, which is content-identical to main's hotfixed copy (the SSRF-guard block sits at a different offset; sorted-content md5s match) and keeps exactly one `runWithTrajectoryPurpose` export.

Pre-merge gates (run locally — CI runners are dead, deploy goes out via wrangler OAuth)

  • `packages/cloud/shared` typecheck (tsgo): clean
  • `packages/cloud/api` typecheck (tsgo): clean
  • `bunx wrangler deploy --env production --dry-run`: clean, 0 esbuild errors, 15958 KiB / 3539 KiB gzip
  • `bun run --cwd packages/app build:web` (prod env): green, chunk-safety verifier OK (392 chunks, crypto graph lazy)
  • Worker stub: exactly one `runWithTrajectoryPurpose` export (line 268)
  • No new cloud DB migrations in the delta

Notable in the 170-commit delta

Money/security: server-generated /v1/messages billing requestId closes the client-controllable affiliate-dedupe key (#12994 + regression lock #13016, #12938); floor /v1/messages output tokens so reasoning models can't bill empty output (#12865); fail-closed unwired a2a paid skills (#13020) + legacy paid-skill dispatch coverage (#13025); path-traversal rejection in eliza-app webhook forwarder (#12970); node-identity mutation guard on re-bootstrap (#12962); end-to-end mute enforcement (#12892) + phone mute controls (#13059); valid OpenAI finish_reason in streaming (#12945).
UI/app: demo punch-list round 2 (#12948); iOS late stream-listener fix (#12791); home-screen frame gate flake fix (#12942).
Everything else: error-policy/fallback-slop sweeps, prose-header cleanup waves, script normalization (#12902/#12903/#12262), LifeOps persona scenario coverage (#12283), embeddings hardening (#13008/#13012/#12971).

Deploy plan after merge: local `wrangler deploy --env production` for the Worker + `wrangler pages deploy` for eliza-cloud/eliza-app from a fresh worktree of main, then live verification (health, operational checks, money gates).

lalalune and others added 30 commits July 4, 2026 00:44
…, annotate justified handlers (#12827)

Continues the packages/feed fallback-slop sweep (#12276, part of #12182). The two
unambiguous domain-slop exemplars (world-state snapshot reads, gameService
outcome) were already converted to fail loud by #12750. This pass re-derives the
suspect list and annotates the justified survivors across the domain/api/db/
shared/engine/web layers with grep-able `// error-policy:J<N>` comments so
"every remaining handler has a documented justification" is mechanically
checkable.

19 handlers annotated (12 J3 untrusted-input sanitizing, 5 J4 user-facing
degrade, 2 J7 diagnostics-must-not-kill-the-loop). No behavior change: every
annotated site was verified to return a typed invalid/absent signal or a
designed degrade, never a fabricated success. The one empty catch in feed
(tools/chroma existence probe) is annotated J3; feed now has zero unannotated
empty catches.

Precision over completeness: the remaining ~330 suspects are dominated by
`?? <lit>` / `|| <lit>` numeric config/display defaults and logged content/
cache/tick-isolation degrades that a careful read classifies as legitimate or
genuinely ambiguous — left untouched per the sweep's over-removal guard rather
than reclassified recklessly.

Refs #12276

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…re barrel (#12834)

Fixes #12794

@elizaos/core emits per-file .js only for explicit build entrypoints;
dist/contracts/ is .d.ts-only, so app-core's credential-resolver importing
runtime VALUES from '@elizaos/core/contracts/first-run-options' resolved to
a non-existent dist/contracts/first-run-options.js and broke 'bun run dev'
boot with "Cannot find module".

- packages/core/src/index.node.ts: re-export the 4 first-run provider
  helpers (getDirectAccountProviderForFirstRunProvider,
  getFirstRunProviderOption, getStoredFirstRunProviderId,
  normalizeFirstRunProviderId) from the existing
  ./contracts/first-run-options barrel entry (contracts stay types-only).
- packages/app-core/src/api/credential-resolver.ts: import those values
  from '@elizaos/core' instead of the .js-less contracts subpath.
- packages/core/src/__tests__/runtime-barrel.test.ts: regression guard
  asserting the barrel keeps re-exporting the 4 helpers.
…, annotate justified handlers (#12826)

packages/ui + packages/app client degrade sweep (batch #12267 of #12182).

Converted (silent swallow -> observable failure):
- bridge/storage-bridge.ts: synced Preferences set/remove writes no longer
  swallow rejections via .catch(() => {}); a dropped session/auth/first-run
  sync now logs at error. Fire-and-forget scheduling kept.
- state/useChatCallbacks.ts: the three best-effort empty-draft cleanup
  deletes now log at warn (J6) instead of a silent .catch(() => {}); the
  server-side cleanupEmptyConversations sweep remains the backstop.

Annotated justified handlers (// error-policy:J<N>):
- app/url-trust-policy.ts: J3 fail-closed URL parse (security).
- app/android-update-checker.ts: J4 best-effort background OTA.
- ui/widgets/home-dismissal-store.ts, ui/chat/index.ts: J3 start-clean parse
  of untrusted persisted local state.
- ui/api/app-shell-capabilities.ts: J3 URL parse -> invalid.
- ui/api/i18n-locale-client.ts: J4 advisory-only language hint.
- ui/bridge/storage-bridge.ts: J4 native-bridge/hydration best-effort degrades.

Real-error-path test: useChatCallbacks.select-race.test.tsx drives a rejecting
deleteConversation through the real cleanup path and asserts the failure
surfaces to the logger (not a silent swallow).

Refs #12267

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…, annotate justified handlers (#12825)

App plugins B slice (wallet/vision/music/agent-skills/browser/workflow/training).
High-confidence conversions only; large sitesLeft by design (precision over
completeness).

- wallet/local-eoa-backend: resolveSolanaKeypair swallowed the typed
  SolanaPrivateKeyInvalidError into null, so a configured-but-malformed
  SOLANA_PRIVATE_KEY read identically to "no wallet configured"
  (WalletBackendNotConfiguredError). Let the typed invalid-key error propagate;
  a real test asserts the malformed-key path now surfaces and the genuine
  no-key path still reports NO_WALLET_CONFIGURED.
- browser/workspace/browser-capture: the two real empty catches in
  stopBrowserCapture are teardown — annotated error-policy:J6 with logger.debug.
- browser/bridge-policy + routes/workspace: URL/tab-id parse helpers returning
  null on malformed input are explicit typed-invalid signals — annotated
  error-policy:J3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…e stub exports (#12807)

The #12051 develop→main promote brought code that imports two @elizaos/core
symbols the Worker bundle's stub (wrangler [alias] target) does not export,
so 'wrangler deploy' esbuild fails and the API Worker never shipped:

- runWithTrajectoryPurpose — pulled in via @elizaos/shared
  email-classification; stubbed as a passthrough, same rationale as the
  existing runWithTrajectoryContext stub (no trajectory manager on the
  Worker).
- fetchWithSsrfGuard — pulled in via plugin-elizacloud transcription
  (audioUrl fetch). Stubbed as a real Worker-safe port of
  core/network/fetch-guard (http(s)-only, blocked-hostname +
  private/reserved-IP-literal rejection incl. v4-mapped IPv6, manual
  redirect following with per-hop re-validation, cross-origin credential
  stripping, spec 301/302/303 GET rewrites, timeout wiring) — NOT a bare
  fetch passthrough, so the SSRF guarantee survives if the path ever runs
  on the Worker. DNS pinning is not portable to workerd (no node:dns) and
  is the one intentional delta.

Deploy typecheck ('Verify Worker') resolves the real @elizaos/core types, so
this class of break only surfaces at the wrangler bundling step; the stub
parity test now imports and exercises both new exports so 'bun test' catches
the next one.

Unblocks the security promote (#11981 cross-org IDOR + #11943/#11958
app-key scope + money fixes) reaching the production Worker.

Co-authored-by: nubs <nubsontopgang@gmail.com>
Co-authored-by: Shaw <shawmakesmagic@gmail.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
packages/app-core + logger slice of the #12182 fallback-slop sweep. Converts the
three named app-core exemplars from fabricated-success to fail-fast, and
annotates the logger's J6/J7 internal handlers.

- database-rows-compat-routes: a `?? 0` on the row-count query made a broken
  count read as "0 rows". Now throws (message carries DB_COUNT_UNAVAILABLE); the
  server.ts handleCompatRoute try/catch is the J1 boundary that translates it to
  a structured 500. Kept as a plain Error (not the @elizaos/core ElizaError
  barrel) so this route module stays off the heavy core import that its
  isolate:false test suite mocks minimally — the J1 boundary logs err.message
  and never inspects the error type, so behavior is identical.
- fs remote list(): stat/guard failures on directory entries silently vanished,
  making a partial listing look complete. Now collected into a new
  FileListResult.failedEntries[] and surfaced; designed sandbox exclusions
  (FS_PATH_DENIED / FS_PATH_OUTSIDE_ROOT) stay silently filtered (not failures).
- cloud-pair inline boot-config script: a failed token handoff silently
  redirected to "/" unpaired. Now logs (browser console) and shows a visible
  "pairing failed" message, guarding the redirect behind the success path.
- logger.ts: annotate the leaf logger's own internal handlers — J7 (cannot
  report through itself: getFs browser probe, ensureFileLog init) and J6
  (best-effort fd close on process exit).

Real-error-path tests (no mocked failing dependency): broken count row →
throw(/DB_COUNT_UNAVAILABLE/) with no SELECT * read; numeric-string count still
resolves without fabricating zero; fs phase5-smoke asserts a dangling symlink
surfaces in failedEntries while designed exclusions do not; cloud-pair asserts
the fail-visible catch branch (console.error + message + guarded redirect).

Refs #12266

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
#12850)

* fix(core): fact write dedupe + kind-stamped relationship echo

the facts_and_relationships stage wrote each extracted relationship into
the facts table with no kind metadata; the facts reader defaults missing
kind to durable, so every unverified single-message echo resurfaced as a
permanent durable fact — and the same claim landed twice (fact row +
echo row, ms apart). stamp the echo with the stage-1 classification
(kind current, stage confidence, keywords) and add a structural
write-time dedupe in runtime.createMemory: skip a facts insert when an
equivalent row (same normalized text + room + entity) already exists,
returning the existing id. text+scope equality only — paraphrase dedupe
stays with the llm pool and the reflection pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(core): format fact write dedupe fixture

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
…bearing modules (B01 part 2) (#12874)

Adds accurate prose file headers and removes/rewrites churn comments across 58
load-bearing files at packages/core/src root + types/: the AgentRuntime
(runtime.ts, with its getSetting/embedding-width invariants), plugin lifecycle,
entities/character, roles/access, memory/db/search, cloud auth+routing, action
naming/docs, settings/boot, connectors/services, utils, and the core type
barrels.

Comments only — zero functional diff, machine-proven by
scripts/assert-comment-only-diff.mjs (every TypeScript code token identical to base).

Part of #12231 (parent #12181). Follows #12824 (B01 part 1).

Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Move the "Classify changed paths" path-gate jobs from GitHub-hosted
ubuntu-24.04 onto the idle [self-hosted, hetzner-robot] fleet.

These jobs run on every PR/push at the top of their workflows, are pure
metadata (actions/checkout + `node packages/scripts/ci-path-gate.mjs`,
no bun/apt/sudo/docker/setup-node), finish in well under a minute, and
only execute repo-controlled classifier code. None use
pull_request_target, so no fork secret exposure. Node is a known-good
capability on the fleet (github-script/zombie-janitor + full monorepo
deploy jobs already rely on it).

Fleet: 26 hetzner-robot runners online, ~22 idle, while every queued job
targets ubuntu-24.04. Draining these cheap high-frequency jobs onto the
idle fleet cuts GH-hosted queue latency for everyone.

Rollback: revert one runs-on line per job.

Co-authored-by: wakesync <shadow@shad0w.xyz>
…they can't bill for empty output (#12864) (#12865)

/v1/messages set effectiveMaxTokens = request.max_tokens with no floor for
non-Anthropic reasoning models. Cerebras reasoning models (zai-glm-4.7,
gpt-oss-120b, gemma-4-31b — accepted as bare ids) spend hidden reasoning
tokens, so a small max_tokens is consumed by reasoning alone and the caller is
billed the full budget for empty output. chat/completions fixed this class
(computeEffectiveMaxTokens, MIN_RESPONSE_TOKENS=4096); messages diverged.

Fix: extract messagesEffectiveMaxTokens (mirrors the chat/completions floor)
and apply it at both message token sites — reasoning models floored to 4096,
non-reasoning pass through, Anthropic CoT covers thinking + response.

Test: messages-reasoning-floor.test.ts — 4/4 green; red without the fix (3/1,
the floor case returns the un-floored budget). typecheck + biome clean.
(Local run needed a packages/core dist rebuild — the stale dist was missing the
new ElizaError export; unrelated to this change.)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…, annotate justified handlers (#12885)

App plugins A slice (personal-assistant, health, agent-orchestrator,
computeruse, coding-tools, shell). Precision-focused: convert high-confidence
slop to fail-fast, annotate justified J-category handlers, leave ambiguous
absent-value / designed-degrade sites untouched.

Converted (slop → surface the failure):
- plugin-personal-assistant automation-node-contributor: native Calendar
  permission double-catch fabricated null on total failure, collapsing
  "unknown" into "no permission system". Now the cached read is a J4 fallback
  and a total failure is reported via runtime.reportError → ERROR_REPORTED
  (agent-visible), returning null only as an explicit "unknown".
- plugin-computeruse a11y-provider: Darwin + Windows snapshot() silently
  swallowed subprocess failures (a11y permission revoked / binary missing)
  into an empty scene the agent trusts as complete. Now surfaced via
  logger.warn (J4) while keeping the documented "[] = no reachable nodes"
  contract so scene-builder still always produces a Scene.
- plugin-computeruse driver: console.warn → logger.warn (logger-only rule).

Annotated justified handlers (// error-policy:J<N>):
- J3 existence/parse probes: desktop-control.commandExists,
  session-cwd-service.isDirectory, terminal-capabilities.canExecute,
  a11y-provider parseHyprlandClients/parseSwayTree.
- J4 provider failover / designed degrade: a11y-provider tryAtspi/tryHyprland/
  trySway, the four connector-status resolvers (null → "not connected").
- J6 best-effort per-entry enrichment: coding-tools ls per-entry lstat race.

Tests (real error paths, no mock-swallow):
- automation-node-contributor.error-policy.test.ts: cached fallback returns the
  cached value with no reportError; total failure reports once and returns null.
- a11y-provider.error-policy.test.ts: drives the real missing-binary path
  (osascript/powershell absent) and asserts the failure is surfaced via
  logger.warn instead of silently swallowed.

Refs #12273.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…, annotate justified handlers (#12886)

Long-tail batch (#12275). Converts one genuine slop site to an observable
fast-fail and documents the justified error handlers in the security-critical
surfaces of the slice (packages/security, packages/vault, plugin-x402) plus the
best-effort teardown/parse handlers in plugin-capacitor-bridge / plugin-gitpathologist
/ plugin-x.

Convert (J7): plugins/plugin-xr vision-pipeline swallowed a per-frame
IMAGE_DESCRIPTION model failure with console.error + return null — invisible to
the error surface and a logger-only violation. Now runtime.reportError makes a
systemic model misconfig observable while preserving the designed per-frame
degrade (a bad frame must not kill the XR loop). Real error-path test added.

Annotate (keep): every other touched catch is a justified handler documented
with // error-policy:J<N>: x402 replay guard + durable reservation fail CLOSED
on error (deny, never fabricate a reservation); security/vault URL+key-id parses
return typed-invalid; op/which/version availability probes answer their boolean
contract; capacitor unlinkSync teardowns and the sandbox-fs candidate probe are
best-effort; the gitpathologist HEAD-keyed cache skips corrupt entries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…plugins (B12) (#12910)

Comment-cleanup batch B12 (parent #12181): purpose-explaining prose headers
on previously header-less files + churn/change-narration removal across the
LifeOps and personal-assistant plugin family (personal-assistant, health,
goals, todos, reminders, scheduling, calendar, inbox, meetings, contacts,
finances, relationships, documents, form, commands).

Includes rewriting the "OUTCOME rewrite of the routing-only... (#9310)"
change-narration blocks on the PA test scenarios into present-tense
descriptions (what owner flow each scenario asserts + live-model harness),
preserving the #9310 anchor.

Comments and whitespace only — no functional diff. Machine-verified by
`bun run check:comment-only` (TS-parser code-token equality vs develop).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…#12892)

* fix: make channel/server mute enforceable end to end

- muted-room drop no longer bypassed by mentions (strict-mode deployments made mute a no-op)
- server-wide mute via ROOM scope=server (world.metadata, consulted by the same inbound gate)
- durationMinutes persisted as agentMuteUntilIso; inbound due-check auto-unmutes at the ISO time
- muted flag in list_channels + mutedRoomCount in list_connections
- plugin-discord drops muted channels before ingestion (persisted, runtime-mutable, threads inherit parent mute)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* style(mute): format mute hardening tests

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…e WORKFLOW scenario (WI-6/WI-7) (#12913)

* test(#12362): overlap-blocking + real ScheduledTask-spine coexistence (WI-6/WI-7)

The WI-6 e2e already proves a workflow schedules through the real core
TaskService tick, dispatches, records an execution + TriggerRunRecord, and
coexists with a LifeOps task on one clock (cases a–d). Two gaps remained from
issue #12362's Done-when:

- (e) overlapping-fire blocking THROUGH the workflow trigger path: gate the
  real WORKFLOW_DISPATCH so the first fire stays in-flight across two ticks;
  the second tick sees the trigger task in the core executing set and skips it
  (blocking !== false), so exactly one execution lands.
- (f) the "one clock, two consumers" LifeOps fire with a REAL domain artifact:
  drive the actual ScheduledTask spine (real runner + in-memory store +
  state-log — the same adapters runner-service.ts uses) from a LIFEOPS_SCHEDULER
  worker fired by the core clock, and assert a real `fired` state-log row.

The spine imports @elizaos/core for types only, so pulling it into this
cross-cutting integration test adds no second runtime copy of core.

bun run --cwd plugins/plugin-workflow test → 356 pass, 0 fail (34 files).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(#12362): live WORKFLOW-action scenario + evidence; lint fixes

- Add packages/scenario-runner/test/scenarios/live-workflow-action-executions.scenario.ts
  (lane: live-only): a real model routes "show my workflow's recent runs" to
  the WORKFLOW action's executions op over a genuinely seeded + executed
  embedded workflow; finalChecks assert actionCalled WORKFLOW success + that
  the seeded execution is readable through the real service. Loads clean; the
  pr-deterministic corpus guard stays green (live-only is excluded).
- Evidence: .github/issue-evidence/12362-workflow-lifeops-integration.md.
- Sort the integration test's imports (organizeImports) and hoist the spine
  newTaskId increment out of the template literal (noAssignInExpressions).

The live run is blocked in this dev env by a repo-wide install gap (jimp, a
declared dep of the optional plugin-vision, is absent from the shared
node_modules); documented in the evidence. The deterministic proxy sibling
already covers the WORKFLOW action path, and the integration tests prove the
scheduling/dispatch path with real services + artifacts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
…et" (#12915)

PR #12521 replaced the launcher's hyperliquid/polymarket id blocklist with
the group-based wallet sub-page hide (isGroupedLauncherSubPage keys on
group === "wallet"). The real plugin-hyperliquid registration carries
group: "wallet" (plugins/plugin-hyperliquid/src/plugin.ts), but the
home-screen e2e views stub still registered hyperliquid without the group,
so curation no longer dropped it and the 'hyperliquid is absent from the
launcher' assertion failed on the develop tip.

Mirror the real registration in the stub so the e2e exercises the actual
group-based hide instead of the removed blocklist. Product behavior was
already correct; this is fixture drift only.
Co-authored-by: moon <stupidlybadadvice@gmail.com>
…TouchDriver fixes (#12840)

* test(ui): launcher gesture-loop web lane + real-browser CdpTouchDriver fixes (#12375)

The shared launcher-loop engine (#12373) shipped a jsdom self-check and the
native lanes but no real-browser web runner, so its CdpTouchDriver had never
driven a live surface. Add the seeded fixture web lane (run-launcher-loop-e2e)
and fix the driver's real-browser gaps that a live run surfaces:
- committing rail swipes were dropped at stepDelayMs 2 (Chromium coalesces the
  touchMove burst); use the proven 16ms/step recipe + a bounded re-dispatch and
  read data-page to confirm the flick landed;
- the open-notification selector missed the real notification-sheet[data-open];
- settle() returned mid-commit; wait for animations done + the rail parked;
- tapTile tapped off-window tiles after a gridScroll; scroll into view first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(ui): scope touch loop weights + commit passing launcher-loop artifacts (#12375)

Exclude the two families that diverge from the shared model on a coarse-pointer
surface: railEdgeButton (chevrons self-hide on touch; the model always
navigates) and tileLongPress (the read-only launcher tile is a plain onClick
button, so a stationary touch long-press launches on release while the model
treats it as inert). Both are covered elsewhere (desktop launcher-interaction +
gesture-matrix). Pre-scan context drops video/trace; stale failure JSONs are
cleared each run. Artifacts: launcher-loop.webm (500-action walkthrough),
brand-scan.json (no blue before/after), launcher-loop.html.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(app)+ci: real-app launcher gesture-loop ui-smoke spec + CI gate + matrix (#12375)

- launcher-gesture-loop.spec.ts drives the shared launcher-loop engine against
  the REAL booted app's composed home↔launcher surface (navigation-safe
  alphabet: tileIds []), on the desktop chromium + mobile-chromium projects,
  with a blue+hover brand scan bookending the loop. Wired into the
  mobile-chromium testMatch.
- chat-shell-gestures.yml runs the fixture loop-web lane (pinned seed 12375) and
  uploads output-launcher-loop; it already generates the shared i18n data the
  fixture bundle needs.
- LAUNCHER_INTERACTION_MATRIX: loop-web/loop-web-app promoted from pending to
  live; Status documents the driver fixes, the two scoped-out families, and the
  failure-replay flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* style: biome format launcher-loop driver + real-app spec (#12375)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(app): record hover-probe failures as evidence, not a hard gate (#12375)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(ui): refresh launcher loop artifacts

---------

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…2921)

Fallback-slop sweep (packages/agent, #12182): the 3 remaining unannotated
empty catches in the agent API layer are justified handlers, now carrying
grep-able `// error-policy:J<N>` annotations per the binding rubric:

- server.ts WS-upgrade `socket.destroy()` → J6 best-effort teardown (the
  socket may already be destroyed after a failed upgrade).
- wallet-capability.ts EVM service-registry probes (×2) → J3: a service
  lookup that throws means that provider isn't usable here, so it is treated
  as absent and the next candidate is tried. The function returns an honest
  `false` (capability absent), never a fabricated success.

No behavior change — comments added inside the catch blocks only. Clears the
last empty-catch sites in packages/agent/src so `noEmptyBlockStatements` holds.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… prober contract, biome drift (#12919)

Repairs the accumulated red on develop so bun run verify passes again
(modulo two pre-existing failures noted below):

- @elizaos/core: export security/redact from the browser barrel —
  cloud-shared's logger (bundled into the app UI) imports
  isSensitiveKeyName/redactLogArgs from the root barrel (#12572 follow-up).
- plugin-local-inference: fix two logger.warn(msg, {error}) calls to
  pino-style ({error}, msg) — introduced in #12546, broke typecheck of
  every package that type-includes the downloader source.
- plugin-sql: carry the !agent.name narrowing across the withRetry closure
  in AgentStore.create (#12602 follow-up).
- plugin-personal-assistant: adapt the website-blocking prober to the
  shared PermissionState contract (adds required platform field) instead
  of exposing plugin-blocker's narrower local shape.
- plugin-tee: allowImportingTsExtensions (tsconfig is noEmit).
- packages/ui: biome-ignore annotations for the two intentional
  registryVersion useMemo deps; type-collapse cast for the postcss/tailwind
  dual-major seam in the e2e fixture builder.
- Repo-wide biome format normalization emitted by the self-fixing lint
  scripts (ui, agent, cloud-shared, cloud-ui and dependents).

Still red on develop (pre-existing, untouched): @elizaos/app#typecheck
(ui/navigation export resolution under tsgo), @elizaos/electrobun#typecheck.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…s (B01 part 3) (#12926)

Adds accurate prose file headers and removes/rewrites churn comments across 225
files in packages/core/src/features — the core capability subsystems:
advanced-capabilities, basic-capabilities, trust, documents, messaging,
plugin-manager, secrets, advanced-memory, working-memory, trajectories,
advanced-planning, plugin-config, sub-agent-credentials, oauth, credential-proxy,
payments, subscription-auth, autonomy. Each file's header names the capability it
belongs to and its role (action / provider / service / schema).

Comments only — zero functional diff, machine-proven by
scripts/assert-comment-only-diff.mjs (every TypeScript code token identical to base).

Part of #12231 (parent #12181). Follows #12824 (p1) and #12874 (p2).

Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
lalalune and others added 14 commits July 4, 2026 03:37
…-scripts

fix(#12902): normalize plugin host registry scripts
…er-scripts

fix(#12902): normalize cloud api agent server scripts
… (B03) (#13065)

Adds accurate purpose-explaining prose file headers and removes/rewrites churn
comments across 358 headerless files in packages/app-core (the HTTP API + dashboard
host that runs agents), packages/app (the web+desktop dashboard, Vite+React), and
packages/shared (cross-package utilities + brand assets). React component headers
describe what the component renders and its dashboard role; app-core headers name
the surface mounted; shared-util headers state the computed contract.

Comments only — zero functional diff, machine-proven by
scripts/assert-comment-only-diff.mjs (every TypeScript code token identical to base).
No JSX/className/string changed — not a UI change, so no visual review needed.

Part of #12233 (parent #12181).

Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Shaw <shawgotbags@gmail.com>
…intlify pages (#13067)

`packages/docs` is a Mintlify site whose pages are `.mdx`, and internal links omit
the extension (`/config-schema`, `/user/change-character`). check-docs.mjs only
tried `.md` / `README.md` / `index.md` when resolving an extensionless link target,
so every link to an `.mdx` page was reported as a "missing linked file" — 261
false positives at full docs scope.

Add `.mdx` and `index.mdx` to candidatePaths. At `--scope=docs` this drops the
reported issue count 715 -> 454; the pages that actually exist (config-schema.mdx,
user/change-character.mdx, agents/runtime-and-lifecycle.mdx, …) are no longer
flagged, and the launchdocs gate still passes.

The remaining 454 are genuine breakage — dominated by a removed `/guides/*` page
family (connectors 46, cloud 20, wallet 17, coding-swarms 15, …) that docs still
link to — and are the content-reconciliation scope of #12462 (a follow-up requiring
content decisions on whether those guides are recreated, repointed, or removed).

Part of #12462 (extend check-docs.mjs so command/link drift is caught mechanically).

Co-authored-by: moon <stupidlybadadvice@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* docs(#12841): add cloud api prose headers

* docs(#12841): keep comment-only gate reproducible

---------

Co-authored-by: moon <stupidlybadadvice@gmail.com>
* docs(#12842): add cloud services prose headers

* docs(#12842): keep comment-only gate reproducible

---------

Co-authored-by: moon <stupidlybadadvice@gmail.com>
* docs(#12845): add cloud-shared db prose headers

* docs(#12845): keep comment-only gate reproducible

---------

Co-authored-by: moon <stupidlybadadvice@gmail.com>
… WI-6) (#13167)

Drive the shared launcher-loop engine (fast-check command stream + trusted CDP
touch, packages/ui/src/testing/launcher-loop) against the REAL booted app's
composed home-launcher surface — the fixture web lane merged as #12686 covers
the full alphabet incl. tile launches; this lane proves production wiring with
the navigation-safe alphabet (tileIds: []) since a tile tap unmounts the
surface. Every §D invariant is checked after each command; blue + hover brand
scans assert (empty-array expects) before and after the loop, with hover-probe
failures recorded as evidence rather than a flake gate.

Runs on desktop chromium (auto-discovered keyless PR lane) and Pixel-7
mobile-chromium (added to the project testMatch). Both executed locally
against the booted app: 40/40 actions green on each, evidence committed under
.github/issue-evidence/12179-launcher-loops/real-app/. Matrix doc updated:
loop-web is live via #12686's runner, loop-web-app is this lane.

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Tree is exactly origin/develop's tree (2072cbc). The one conflict —
packages/cloud/api/src/stubs/elizaos-core.ts — resolved to develop's
version (content-identical to main's; the SSRF-guard block sits at a
different offset). Exactly one runWithTrajectoryPurpose export.
@NubsCarson
NubsCarson merged commit df9371e into main Jul 4, 2026
19 of 93 checks passed
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ea98c45e-4af8-42ae-8638-6c41880086dd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch promote/develop-to-main-20260704-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NubsCarson
NubsCarson deleted the promote/develop-to-main-20260704-2 branch July 4, 2026 12:51
@greptile-apps

greptile-apps Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review. (3000 files found, 100 file limit)

@NubsCarson

Copy link
Copy Markdown
Member Author

[cloud-frontdoor] Deployed to prod via local wrangler (CI runners dead), account 23cf6fea:

  • Worker eliza-cloud-api-prod: version eed5d376-2fd1-4590-8278-643f316c6735 from main df9371e403 (tree == develop 2072cbc86c)
  • Pages eliza-cloud (apex): deployment e3449cb5, live bundle index-C2LuZ2Un.js (was index-opqSY9G9.js)
  • Pages eliza-app: deployment e50ad3cb (Production/main), live bundle index-CZxwbLT-.js (was index-CA9wcIoG.js)

Live verification: apex + app 200 w/ fresh hashes; api/health ok; api/health/operational ok (steward_platform / payouts evm+solana / crons all green); money gates correct — oxapay webhook 400, stripe webhook 400 on junk POSTs, /api/v1/models 200. No new cloud DB migrations in this delta; no secrets touched.

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

❌ PR title does not match the required pattern. Please use one of these formats:

  • 'type: description' (e.g., 'feat: add new feature')
  • 'type(scope): description' (e.g., 'chore(core): update dependencies')
    Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants