Skip to content

fix(ci): unblock release lane — Rust E0063, macOS E0463, and E2E login-consume fixtures#4511

Merged
senamakel merged 7 commits into
tinyhumansai:mainfrom
senamakel:fix/tinyagents-toolcompleted-started-at-ms
Jul 4, 2026
Merged

fix(ci): unblock release lane — Rust E0063, macOS E0463, and E2E login-consume fixtures#4511
senamakel merged 7 commits into
tinyhumansai:mainfrom
senamakel:fix/tinyagents-toolcompleted-started-at-ms

Conversation

@senamakel

Copy link
Copy Markdown
Member

Summary

  • Fix three independent blockers that keep the main → release PR (Release: merge main into release #4490) and the whole Release CI lane red. All three are pre-existing on main; the fast PR lane never exercises them, and Release CI has not been green since it was introduced (feat(ci): two-branch CI — changed-files-only PR lane, full-suite release lane, release-branch cuts, cancellation watchdog #4486).
  • Rust unit build: add the new started_at_ms field to a ToolCompleted test event so the core lib-test compiles (was E0063).
  • macOS bundle build: install the x86_64-apple-darwin cross target on the toolchain the build actually uses (rust-toolchain.toml = 1.96.1), fixing E0463 can't find crate for core in the universal CEF helper.
  • Desktop E2E login: repoint the E2E mock + login specs at the current /auth/login-token/consume endpoint so performFullLogin succeeds (unblocks the auth cascade that was failing every shard).

Problem

The Release CI gate requires the full Rust suites, the macOS desktop bundle, and the desktop E2E matrix to pass. Three separate regressions blocked it:

  1. E0063 — the tinyagents vendor bump (chore(vendor): bump tinyagents — V1 perf + V2 reasoning #4502) added a required started_at_ms: Option<u64> field to AgentEvent::ToolCompleted; a unit test in src/openhuman/tinyagents/observability.rs still constructed the event without it → the core lib-test failed to compile on Linux and Windows.
  2. E0463 can't find crate for corerust-toolchain.toml was bumped to 1.96.1 (feat: finish TinyAgents harness migration (#4249) #4399), but CI installs Rust via dtolnay/rust-toolchain@1.93.0. The action's targets: input added x86_64-apple-darwin to 1.93.0, while the toolchain-file override (1.96.1) is what the vendored tauri-cli build.rs uses to compile the universal CEF helper — so the cross target was missing on the build toolchain, failing the macOS bundle.
  3. Stale E2E login fixtures — the core moved login-token consume to POST /auth/login-token/consume (token in the JSON body, response { success, data: { jwt } }) in fix(channels): repair Discord & Telegram messaging end-to-end (#3712, #3763) #3794; the removed legacy route was /telegram/login-tokens/:token/consume. The E2E mock only served the legacy path and returned jwtToken, and every login/auth spec asserted on the legacy URL substring. Once the full desktop E2E suite began running in Release CI (feat(ci): two-branch CI — changed-files-only PR lane, full-suite release lane, release-branch cuts, cancellation watchdog #4486), performFullLogin never received a JWT, so every shard cascaded (Auth consume call missing, Welcome screen still not visible).

Solution

  • observability.rs: add started_at_ms: None to the ToolCompleted event the observability test emits. Verified with cargo check --lib --tests (clean).
  • CI (e2e-reusable.yml, build-desktop.yml): after the toolchain-file toolchain is materialized, run rustup target add x86_64-apple-darwin (and aarch64 in the release build) against the active (override) toolchain on macOS. Verified: the macOS bundle build now succeeds on a dispatched Release CI run.
  • E2E mock (scripts/mock-api/routes/auth.mjs): accept /auth/login-token/consume (legacy path kept as a harmless alias) and return data.jwt — the field the core parses. Verified locally: default → 200 {data:{jwt}}, token=expired/invalid401.
  • E2E specs: swap the consume matcher substring to /auth/login-token/consume across auth-access-control, login-flow, mega-flow, voice-mode, local-model-runtime, logout-relogin-onboarding, and the Playwright login-flow spec. The specs already reset the request log per test and match on path only, so this is behavior-preserving. Verified on a dispatched Release CI run: the foundation shard went from 0 passing → 16 passed and the auth/login specs pass.

No product code changes — the E2E fix is fixtures-only, and the core already behaves correctly.

Note: this PR unblocks the deterministic gates and the auth cascade. A large tail of previously-masked, pre-existing E2E spec failures across other areas (agent-harness/tool-flow, webhooks, chat, onboarding, navigation, settings, connectors) is now visible for the first time, plus a macOS E2E harness that has never launched in CI. Those are tracked as follow-up (see ## Related) and are out of scope here.

Submission Checklist

  • Tests added or updated — E2E fixtures updated (mock route + specs) to match current core behavior; Rust test fixed to compile. Failure paths covered (expired/invalid → 401 preserved).
  • N/A: Diff coverage ≥ 80% — changes are CI workflow YAML, an E2E test-only Rust fixture, and E2E test fixtures/specs; no product src lines changed, so diff-cover has no product lines to gate.
  • N/A: Coverage matrix — behaviour-only/test-infra change, no feature rows affected.
  • N/A: no feature IDs affected.
  • No new external network dependencies — mock backend only.
  • N/A: no release-cut manual-smoke surface touched.
  • N/A: no linked issue to close (follow-ups listed below).

Impact

  • CI only for the toolchain change (macOS bundle build path). No runtime/product behavior change.
  • Unblocks the Rust unit suites (Linux + Windows), the macOS desktop bundle, and the desktop-E2E login prerequisite for the release lane.

Related

  • Closes:
  • Follow-up PR(s)/TODOs: remaining Release-CI desktop-E2E spec failures (agent-harness/tool-flow, webhooks, chat, onboarding, navigation, settings, connectors) and the macOS E2E harness launch failure — to be addressed in follow-up PRs.

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/tinyagents-toolcompleted-started-at-ms
  • Commit SHA: beeda48

Validation Run

  • N/A pnpm --filter openhuman-app format:check — changed specs are prettier-clean; scripts/mock-api is outside the app's prettier scope (formatted manually).
  • N/A pnpm typecheck — no app/src product code changed.
  • Focused tests: cargo check --lib --tests (clean); mock endpoint curl-verified; dispatched Release CI run confirms macOS build green + foundation E2E 0→16 passing.
  • Rust fmt/check (if changed): cargo check clean.
  • N/A Tauri fmt/check — no Tauri Rust changed.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: none (test-infra + CI only).
  • User-visible effect: none.

Parity Contract

  • Legacy behavior preserved: mock keeps the legacy consume path as an alias; expired/invalid → 401 preserved; specs match on path only with per-test log reset.
  • Guard/fallback/dispatch parity checks: N/A.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none
  • Canonical PR: this
  • Resolution: N/A

https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU

senamakel added 3 commits July 4, 2026 18:23
The tinyagents vendor bump (tinyhumansai#4502) added a `started_at_ms: Option<u64>`
field to `AgentEvent::ToolCompleted`. The observability unit test still
constructed the event without it, breaking the lib-test build
(E0063) and failing Release CI's Rust Core Tests lane.

Claude-Session: https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU
…lchain

The root rust-toolchain.toml was bumped to 1.96.1 (tinyhumansai#4399), but CI still
installs Rust via `dtolnay/rust-toolchain@1.93.0`. That action's `targets:`
input added x86_64-apple-darwin to 1.93.0, while the toolchain-file override
(1.96.1) is what the vendored tauri-cli's build.rs actually uses to compile
the universal CEF helper. The x86_64 target was therefore missing on the
build toolchain, failing the macOS bundle with E0463 "can't find crate for
`core`". Add the target to the active (override) toolchain explicitly in the
macOS E2E build steps (e2e-reusable.yml) and the release build (build-desktop.yml).

Claude-Session: https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU
…n/consume

The core moved the login-token consume call to `POST /auth/login-token/consume`
(token in the JSON body, response `{ success, data: { jwt } }`) back in tinyhumansai#3794;
the removed legacy route was `/telegram/login-tokens/:token/consume`. The E2E
mock server still only served the legacy path and returned `jwtToken`, and every
login/auth spec asserted on the legacy URL substring — so once the full desktop
E2E suite began running in the new Release CI lane (tinyhumansai#4486), `performFullLogin`
never saw a consume call, no JWT was returned, and every shard cascaded
("Auth consume call missing", "Welcome screen still not visible").

- mock (scripts/mock-api/routes/auth.mjs): accept the new path (legacy kept as a
  harmless alias) and return `data.jwt` (the field the core parses), not jwtToken.
- specs: swap the consume matcher substring to `/auth/login-token/consume` across
  auth-access-control, login-flow, mega-flow, voice-mode, local-model-runtime,
  logout-relogin-onboarding, and the Playwright login-flow spec.

Pure test-fixture fix; no product code changes.

Claude-Session: https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU
@senamakel
senamakel requested a review from a team July 4, 2026 19:48
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 54 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4c47f61e-fa76-4885-86f1-2036520609df

📥 Commits

Reviewing files that changed from the base of the PR and between 7850cf3 and 3656dd4.

📒 Files selected for processing (30)
  • .github/workflows/build-desktop.yml
  • .github/workflows/e2e-reusable.yml
  • app/test/e2e/helpers/shared-flows.ts
  • app/test/e2e/specs/auth-access-control.spec.ts
  • app/test/e2e/specs/card-payment-flow.spec.ts
  • app/test/e2e/specs/chat-harness-scroll-render.spec.ts
  • app/test/e2e/specs/composio-triggers-flow.spec.ts
  • app/test/e2e/specs/connector-jira.spec.ts
  • app/test/e2e/specs/cron-jobs-flow.spec.ts
  • app/test/e2e/specs/local-model-runtime.spec.ts
  • app/test/e2e/specs/login-flow.spec.ts
  • app/test/e2e/specs/logout-relogin-onboarding.spec.ts
  • app/test/e2e/specs/mega-flow.spec.ts
  • app/test/e2e/specs/navigation-settings-panels.spec.ts
  • app/test/e2e/specs/navigation.spec.ts
  • app/test/e2e/specs/notifications.spec.ts
  • app/test/e2e/specs/onboarding-modes.spec.ts
  • app/test/e2e/specs/rewards-progression-persistence.spec.ts
  • app/test/e2e/specs/settings-advanced-config.spec.ts
  • app/test/e2e/specs/settings-channels-permissions.spec.ts
  • app/test/e2e/specs/settings-dev-options.spec.ts
  • app/test/e2e/specs/skill-execution-flow.spec.ts
  • app/test/e2e/specs/tool-browser-flow.spec.ts
  • app/test/e2e/specs/voice-mode.spec.ts
  • app/test/e2e/specs/webhooks-ingress-flow.spec.ts
  • app/test/e2e/specs/webhooks-tunnel-flow.spec.ts
  • app/test/playwright/specs/login-flow.spec.ts
  • app/test/wdio.conf.ts
  • scripts/mock-api/routes/auth.mjs
  • src/openhuman/tinyagents/observability.rs

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

senamakel added 3 commits July 4, 2026 19:55
Foundation shard (all stale fixtures, no product change):
- onboarding-modes: accept #/chat as a "home" landing (/home→/chat IA merge);
  guard the Phase B RuntimeChoice Next like Phase C (avoids over-advancing
  inference→voice when local mode auto-redirects); click the always-rendered
  save-voice-routing button so the staged STT provider persists to config.toml
  (Voice Routing moved to staged-edit + explicit Save).
- navigation: drop /activity from ROUTES (now redirects to /settings/notifications,
  same rationale as the already-removed /home→/chat alias).
- navigation-settings-panels: accept #/chat|#/home for the post-navigateToHome hash.

Providers shard (under-budgeted arrow before-all hooks hitting the 30s Mocha
cap): convert notifications, cron-jobs-flow, and composio-triggers-flow before
hooks to `async function` + this.timeout(90_000), matching the passing specs.

Claude-Session: https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU
Stale fixtures (spec/mock only, no product change):
- chat-harness-scroll-render: messages scroll container class drifted
  (bg-[#f6f6f6] → surface token); match structural classes.
- skill-execution-flow: accept the current home copy string.
- settings-dev-options: panel headings now come from the route-registry title
  ("Webhooks"/"Autocomplete", not the dead *Debug titleKeys); memory-debug now
  redirects to /brain?tab=memory-debug (assert section content, not heading).
- settings-advanced-config: drive the controlled autonomy input via native
  setter + React change event so Save's isChanged gate fires (setValue didn't).
- connector-jira: clear the durable localStorage composio:connections cache so
  the modal opens in the idle phase (prior ACTIVE test poisoned the cache).

Harness resilience for the single shared CEF session (relieves the ~25 flaky
before-all/30s-ceiling failures across shards):
- wdio.conf.ts: specFileRetries=1 (deferred) unless bailing — absorbs transient
  cold-start/bring-up races; deterministic failures still fail on retry.
- shared-flows.walkOnboarding: trim the already-onboarded wait 15s→8s so every
  resetApp finishes well under the 30s Mocha hook budget.
- Convert under-budgeted arrow before() hooks to `async function` +
  this.timeout(90_000): webhooks-ingress, webhooks-tunnel, tool-browser,
  card-payment, settings-channels-permissions, rewards-progression.

Claude-Session: https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cd868a9218

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

sink.emit(AgentEvent::ToolCompleted {
call_id: "c1".into(),
tool_name: "echo".to_string(),
started_at_ms: None,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the remaining ToolCompleted literals

This hunk adds the new required started_at_ms field to one AgentEvent::ToolCompleted, but the same test module still constructs another ToolCompleted without that field in tool_completed_projects_output_arguments_and_elapsed at line 1247. When compiling against the tinyagents event shape this is fixing, the Rust test target still fails with E0063, so the release lane remains blocked.

Useful? React with 👍 / 👎.

Comment on lines +83 to +87
await browser.execute(() => {
Object.keys(window.localStorage)
.filter(k => k.includes('composio:connections'))
.forEach(k => window.localStorage.removeItem(k));
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wait for the mounted Jira state to clear

When this test runs after the preceding Jira card test in the shared WDIO session, the app is already on /connections with the ACTIVE connection held in React state. Clearing only localStorage does not update the mounted useComposioIntegrations state until a later poll/refetch, and navigateToSkills() can be a same-route no-op, so opening the modal immediately can still latch the connected phase and fail to render the subdomain input. Force a remount/refresh or wait for the disconnected state before opening the modal.

Useful? React with 👍 / 👎.

Same stale-title drift as settings-dev-options: the panel heading is the
route-registry title 'Webhooks', not the removed 'Webhooks Debug' key.

Claude-Session: https://claude.ai/code/session_01UAetDHQCyFtWnyP7RwGdJU
@senamakel

Copy link
Copy Markdown
Member Author

Diagnosed the one candidate real behavior change surfaced by this PR (once login + stale fixtures were cleared): the chat tool-round E2E specs fail because the TinyAgents harness's per-turn model-call sequence desyncs the mock's one-forced-response-per-call queue — the agent improvises analyze_image/subagent tool calls that error instead of emitting the scripted canary answer. Full evidence (failure DOM dump) and repro in #4517. Not an empty-full_response/renderer bug — the DOM disproves that.

Remaining Release-CI E2E tail after this PR is documented in #4517's Related section (CEF shared-session instability; onboarding-modes wizard).

@senamakel
senamakel merged commit 20d8c88 into tinyhumansai:main Jul 4, 2026
11 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant