## Summary
- Extends `openhuman.test_reset` so E2E resets also wipe Memory Tree state via the existing `memory_tree_wipe_all` path.
- Adds reset summary fields for memory-tree rows, content directories, and Composio sync-state rows so Appium logs show exactly what was cleared.
- Adds a focused async unit test covering memory-tree content directory cleanup through the new reset helper.
## Problem
- #1862 tracks that `openhuman.test_reset` only cleared auth/onboarding/cron state, while Memory Tree data could survive between specs in a shared Appium session.
- That means memory-oriented specs can pass or fail based on chunks, wiki content, or sync cursors left by an earlier spec.
## Solution
- Calls `read_rpc::wipe_all_rpc(&config)` from `test_support::rpc::reset` after cron cleanup and before config/auth clearing.
- Surfaces `memory_tree_rows_deleted`, `memory_tree_dirs_removed`, and `memory_tree_sync_state_cleared` in `ResetSummary`, `reset_json`, and the controller schema.
- Keeps this as a scoped #1862 slice; other domains listed in the issue can land as separate hook PRs.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) — focused unit test covers Memory Tree content-dir cleanup; existing `wipe_all_rpc` owns table/sync-state failure behavior.
- [x] **Diff coverage >= 80%** — new Rust test covers the new helper path; CI coverage gate is authoritative.
- [x] Coverage matrix updated — N/A: E2E test-support reset plumbing, no product feature row added/removed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` — N/A: no feature matrix row.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) — N/A: test-support RPC only.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section — N/A: scoped slice; references #1862 without closing the umbrella.
## Impact
- E2E specs that call `resetApp(...)` now start without prior Memory Tree chunks, summary/wiki files, or sync cursors.
- User runtime behavior is unchanged unless the E2E-only `openhuman.test_reset` controller is compiled/enabled.
## Related
- Refs #1862
- Follow-up PR(s)/TODOs: add hook coverage for remaining #1862 domains: channels, skills, webview_accounts, threads, notifications, webhooks, cost, referral, composio.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/1862-test-reset-memory-tree`
- Commit SHA: `48630b40f69400d6a3c5e055e80c25486e3bba6d`
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: no frontend files changed.
- [x] `pnpm typecheck` — N/A: no TypeScript files changed.
- [x] Focused tests: attempted `cargo test -p openhuman test_support::rpc::tests::wipe_memory_tree_removes_content_dirs_and_reports_summary --lib`.
- [x] Rust fmt/check (if changed): `cargo fmt --all --check`; `git diff --check`.
- [x] Tauri fmt/check (if changed): N/A: no Tauri shell files changed.
### Validation Blocked
- `command:` `cargo test -p openhuman test_support::rpc::tests::wipe_memory_tree_removes_content_dirs_and_reports_summary --lib`
- `error:` local Windows build fails before tests in `whisper-rs-sys` because `clang.dll` / `libclang.dll` is missing and `LIBCLANG_PATH` is unset.
- `impact:` focused test did not execute locally; CI Linux/Windows runners with libclang are expected to compile and run it.
### Behavior Changes
- Intended behavior change: E2E-only test reset now wipes Memory Tree state in addition to cron/auth/onboarding state.
- User-visible effect: none in normal builds; E2E logs show memory-tree wipe counts.
### Parity Contract
- Legacy behavior preserved: cron cleanup, auth clearing, onboarding reset, and active-user removal still run and still short-circuit on failure.
- Guard/fallback/dispatch parity checks: Memory Tree wipe reuses the existing user-facing `wipe_all_rpc` implementation instead of adding a second deletion path.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: this PR
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **New Features**
* Reset now clears memory-tree persistent data during fresh-install resets and reports rows deleted, directories removed, and sync-state entries cleared.
* **Documentation**
* Updated reset operation schema and outputs to include memory-tree cleanup fields.
* **Tests**
* Added a unit test verifying memory-tree wipe removes content directories and reports summary metrics.
* **Bug Fixes**
* Increased core startup readiness timeout to reduce startup failures.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2308?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Extends the auth profile lock wait horizon so a fresh leaked lock can cross the stale-lock threshold and be reclaimed.
- Keeps the existing 30s stale threshold unchanged; only the caller-facing timeout moves to `STALE_LOCK_AGE_MS + 5s`.
- Adds a regression test that locks the timeout/stale-age relationship so the recovery path cannot become unreachable again.
## Problem
- Sentry issue TAURI-RUST-B1 reports `Timed out waiting for auth profile lock`.
- The stale-lock reclaim threshold is 30s, but the lock wait timeout was 10s.
- That meant a just-orphaned lock with a live pid could never age into the existing age-based recovery before callers gave up.
## Solution
- Derive `LOCK_TIMEOUT_MS` from `STALE_LOCK_AGE_MS + 5_000`.
- Update stale-lock comments to avoid the stale 10s wording.
- Add a focused unit-level guard for the timeout relation.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] **Diff coverage ≥ 80%** — changed lines (Vitest + cargo-llvm-cov merged via `diff-cover`) meet the gate enforced by [`.github/workflows/coverage.yml`](../.github/workflows/coverage.yml). Run `pnpm test:coverage` and `pnpm test:rust` locally; PRs below 80% on changed lines will not merge.
- [x] Coverage matrix updated — N/A: internal auth-profile lock recovery constant, no matrix feature row.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related`
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces — N/A: no release-cut surface touched.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Auth profile operations now wait long enough for existing stale-lock recovery to handle fresh leaked locks.
- Worst-case wait before reporting a truly live lock increases from 10s to 35s.
- No storage schema or API contract changes.
## Related
- Closes: #2318
- Follow-up PR(s)/TODOs: N/A
- Coverage matrix feature IDs: N/A: credentials lock recovery internals.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: codex/2318-auth-profile-lock-timeout
- Commit SHA: c5267484
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: no frontend files changed.
- [x] `pnpm typecheck` — N/A: no TypeScript files changed.
- [x] Focused tests: attempted `cargo test -p openhuman credentials::profiles --lib`.
- [x] Rust fmt/check (if changed): `cargo fmt --all --check`; `git diff --check`.
- [x] Tauri fmt/check (if changed): N/A, no `app/src-tauri` files changed.
### Validation Blocked
- `command:` `cargo test -p openhuman credentials::profiles --lib`
- `error:` `whisper-rs-sys` build could not find `clang.dll` / `libclang.dll`; `LIBCLANG_PATH` is not set in this local Windows environment.
- `impact:` The targeted Rust test binary did not run locally; CI has the Linux Rust toolchain/image and should execute it.
### Behavior Changes
- Intended behavior change: auth profile lock acquisition can wait past the stale-lock threshold and reclaim a fresh leaked lock instead of timing out first.
- User-visible effect: fewer startup/session failures from transient orphaned `auth-profiles.lock` files.
### Parity Contract
- Legacy behavior preserved: stale lock detection logic, pid checks, malformed-lock rules, and guard cleanup are unchanged.
- Guard/fallback/dispatch parity checks: existing stale-lock tests remain in place; new constant guard ensures recovery remains reachable.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: N/A
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Refactor**
* Improved lock timeout configuration for enhanced maintainability.
* **Tests**
* Added test to validate lock timeout behavior and timing constraints.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2321?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Skip Subconscious ticks before writing per-task activity rows when no OpenHuman session/local provider path is available.
- Add provider availability fields to `subconscious_status` and show a paused/configuration banner in Intelligence > Subconscious.
- Route the tick evaluator through `subconscious_provider` while reusing the existing memory-tree chat provider plumbing.
Closes#1374
## Testing
- [x] `cargo fmt --all --check`
- [x] `pnpm --filter openhuman-app test -- src/components/intelligence/__tests__/IntelligenceSubconsciousTab.test.tsx`
- [x] `pnpm --filter openhuman-app compile`
- [x] `pnpm i18n:check`
- [x] `git diff --check`
- [x] `cargo test -p openhuman subconscious::engine::tests --lib` attempted locally, blocked before tests by `whisper-rs-sys` missing `libclang` (`LIBCLANG_PATH` unset).
## PR Checklist
- [x] I linked the relevant issue(s) above.
- [x] I added or updated tests for the changed behavior, or explained why this is not needed.
- [x] I ran the relevant local checks, or documented why they could not be run.
- [x] I kept the change scoped to the issue.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **New Features**
* Show an amber warning when the AI provider is unavailable, display the unavailable reason, provide a quick link to AI settings, disable the "Run Now" button, and show a translated tooltip explaining the unavailable status.
* **Internationalization**
* Added provider-unavailable title and settings label translations across multiple languages.
* **Tests**
* Added tests covering the provider-unavailable UI, disabled Run Now behavior, and settings navigation.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2314?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- refuse `openhuman.config_set_browser_allow_all(enabled=true)` unless `OPENHUMAN_BROWSER_ALLOW_ALL_RPC_ENABLE=1` is present
- keep runtime disable available so an already-enabled process can re-enforce the browser allowlist
- update the RPC schema text and unit coverage for rejected enable, override-enabled toggle, and disable behavior
Closes#1899
## Testing
- [x] `cargo fmt --all --check`
- [x] `git diff --check`
- [x] `cargo test -p openhuman set_browser_allow_all --lib` attempted; blocked before test execution because `whisper-rs-sys` could not find `clang.dll` / `libclang.dll` (`LIBCLANG_PATH` unset)
## Checklist
- [x] I have tested the changes locally or documented why a local test could not complete.
- [x] I have kept the change scoped to the linked issue.
- [x] I have updated relevant tests or documentation.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
## Release Notes
* **Bug Fixes**
* Browser allow-all feature now requires explicit operator approval via environment variable to enable, restricting access to authorized users only.
* Disabling the feature remains unrestricted.
* Enhanced security audit logging for all browser allow-all state changes.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2312?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Bundles the glibc dynamic linker that `sharun` needs inside the Linux AppImage when the post-build AppImage cleanup runs.
- Repackages and re-signs AppImage artifacts when the only mutation is adding the missing loader, not just when graphics libraries were stripped.
- Keeps the existing Mesa/libdrm/libva stripping behavior intact and adds a release smoke item for the Ubuntu 24.04 `Interpreter not found!` regression.
## Problem
- `OpenHuman_0.54.0_amd64.AppImage` can exit immediately on Ubuntu 24.04 with `Interpreter not found!` because the AppImage contains a `sharun` launcher but no `lib/ld-linux-x86-64.so.2`.
- The existing post-processing script only repacked when graphics libraries were removed, so it had no guard for a missing `sharun` interpreter.
## Solution
- Detect `sharun`-style launchers by checking the extracted AppDir launcher binaries for the `Interpreter not found!` marker.
- Resolve the expected loader from the build target architecture and copy it into `squashfs-root/lib/` when missing.
- Fail the post-processing step if the AppImage uses `sharun` but the build host cannot provide the required loader.
- Track all modified AppImages, whether modified by stripping graphics libs or by adding the loader, so updater tarballs and signatures stay in sync.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) — release smoke checklist updated; local function smoke covers loader injection path.
- [x] **Diff coverage >= 80%** — N/A: shell release packaging script and docs are not covered by Vitest/cargo diff coverage.
- [x] Coverage matrix updated — N/A: release packaging behavior, not a product feature row.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` — N/A: no feature matrix row.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md))
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Linux AppImage release artifacts should launch on clean Ubuntu 24.04 hosts without requiring users to extract the AppImage and manually copy `ld-linux-x86-64.so.2`.
- Packaging fails earlier if a future build cannot locate the required loader, preventing a known-broken AppImage from shipping.
## Related
- Closes#2297
- Follow-up PR(s)/TODOs: N/A
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/2297-appimage-sharun-loader`
- Commit SHA: `4260df24f5355a63df02e748e276586ebed0c53a`
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: no frontend files changed.
- [x] `pnpm typecheck` — N/A: no TypeScript files changed.
- [x] Focused tests: Git Bash smoke test for `ensure_sharun_interpreter` copies `ld-linux-x86-64.so.2` into a synthetic sharun AppDir.
- [x] Rust fmt/check (if changed): N/A: no Rust files changed.
- [x] Tauri fmt/check (if changed): N/A: no Tauri Rust files changed.
- [x] Shell syntax/check: `C:\Program Files\Git\bin\bash.exe -n scripts/release/strip-appimage-graphics-libs.sh`; `git diff --check`.
### Validation Blocked
- `command:` Full AppImage rebuild and launch on Ubuntu 24.04.
- `error:` No produced Linux AppImage artifact is available in this local Windows workspace.
- `impact:` CI release packaging will exercise the changed script; manual release smoke checklist now covers the Ubuntu 24.04 launch regression.
### Behavior Changes
- Intended behavior change: AppImage post-processing now bundles the missing `sharun` dynamic linker when needed.
- User-visible effect: Linux users should no longer hit `Interpreter not found!` on affected AppImages.
### Parity Contract
- Legacy behavior preserved: existing graphics-library stripping, re-signing, and updater tarball rebuild behavior remain intact.
- Guard/fallback/dispatch parity checks: AppImages unchanged by stripping or loader injection are still left untouched; missing host loader now fails packaging instead of shipping a broken artifact.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: this PR
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Bug Fixes**
* AppImages now remove incompatible host graphics libraries and auto-include a missing bundled dynamic loader when needed, preventing "Interpreter not found" failures on clean Ubuntu 24.04 hosts.
* **Chores**
* Added a smoke-test checklist item to validate AppImage launches on Ubuntu 24.04.
* Release tooling now only repacks and re-signs AppImages that were actually modified.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2307?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Replaces the fixed post-hash `browser.pause(2_000)` with a route readiness wait.
- `navigateViaHash()` now waits for the target hash, `document.readyState === "complete"`, and a mounted React root before returning.
- `walkOnboarding()` now waits for `#/home` and a Home-page marker after the onboarding next button unmounts.
- Documents the navigation-readiness pattern in the E2E guide.
## Problem
- #1864 reports a first-navigation race after onboarding: the hash changes, but the target panel can be empty because React has not settled yet.
- The old helper returned after a fixed pause, so specs could start looking for panel text before the routed view mounted.
## Solution
- Add `waitForHashRouteReady()` to make hash navigation wait on concrete browser/app signals.
- Add `waitForPostOnboardingHome()` so the onboarding walker does not hand control back until Home is actually ready.
- Throw navigation readiness failures immediately instead of hiding them behind a later text timeout.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) - helper behavior tightened; E2E suite is the exercising path.
- [x] **Diff coverage >= 80%** - N/A locally: E2E helper/doc change; CI E2E jobs are authoritative.
- [x] Coverage matrix updated - N/A: E2E helper behavior change, no feature row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` - N/A: no matrix feature ID applies.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) - N/A: no release-cut surface.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Runtime/user impact: none; test helper only.
- E2E impact: hash navigation and post-onboarding transitions now wait on real readiness signals instead of fixed sleeps.
- Failure mode improves: route readiness failures surface at navigation time with the target hash in the error.
## Related
- Closes#1864
- Follow-up PR(s)/TODOs: N/A
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/1864-e2e-navigation-readiness`
- Commit SHA: `15f56af3c6c865fbd322010d25b047a998ebd964`
### Validation Run
- [x] `pnpm --filter openhuman-app exec prettier --check test/e2e/helpers/shared-flows.ts` - passed
- [x] `pnpm typecheck` - passed
- [x] Focused tests: N/A, E2E helper change not run locally
- [x] Rust fmt/check (if changed): `cargo fmt --all --check` - passed; `git diff --check` - passed
- [x] Tauri fmt/check (if changed): N/A
### Validation Blocked
- `command:` full E2E rerun
- `error:` not run locally; requires built desktop app/Appium harness
- `impact:` remote E2E CI remains authoritative for the harness change
### Behavior Changes
- Intended behavior change: E2E helpers wait for route/onboarding readiness before specs continue.
- User-visible effect: none.
### Parity Contract
- Legacy behavior preserved: same routes and onboarding flow; only readiness timing changed.
- Guard/fallback/dispatch parity checks: existing text assertions remain in specs after helper navigation.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: this PR
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Tests**
* Enhanced E2E helpers for more reliable hash-based navigation and for stronger verification that onboarding completes and the Home page is fully settled.
* **Documentation**
* Updated E2E testing guide with cross-platform navigation guidance recommending the hash navigation helper and noting post-onboarding Home-page readiness checks.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2304?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Adds shared `waitForTestId` and `clickTestId` E2E helpers for stable DOM hooks.
- Adds missing `cron-jobs-panel` and `cron-refresh` hooks to the Cron Jobs settings panel.
- Migrates the reference cron E2E flow away from Tailwind class/DOM walking to cron row/action test IDs.
- Documents the E2E `data-testid` naming taxonomy in the E2E guide.
## Problem
- #1861 calls out `cron-jobs-flow.spec.ts` as the concrete example of brittle selectors: it found `morning_briefing` via Tailwind class strings and `closest('div.p-4')`.
- That breaks on harmless class/layout refactors and makes the reference spec a weak template for future E2E work.
## Solution
- Use existing `CoreJobList` cron row/action hooks directly from the spec.
- Add the missing panel/refresh hooks so the whole cron flow can avoid text/button discovery for row actions.
- Centralize test ID waiting/clicking in `element-helpers.ts` instead of keeping local DOM snippets in specs.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) - updated the reference cron E2E spec and helper path.
- [x] **Diff coverage >= 80%** - N/A locally: E2E helper/spec/doc change; CI diff coverage is authoritative.
- [x] Coverage matrix updated - N/A: E2E selector-hardening change, no feature row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` - N/A: no matrix feature ID applies.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) - N/A: no release-cut surface.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section - N/A: this is a scoped slice that references #1861 without closing the broader audit issue.
## Impact
- Runtime impact: none outside stable `data-testid` attributes on the Cron Jobs panel.
- Test impact: cron E2E is less coupled to Tailwind classes and container structure.
- Compatibility: `waitForTestId` is documented as tauri-driver/DOM-backed; Mac2 specs should keep accessibility/text helpers unless IDs are mirrored into accessible labels.
## Related
- Refs #1861
- Follow-up PR(s)/TODOs: add stable hooks/migrations for the remaining settings, skills, conversation, onboarding, and notification E2E surfaces tracked by #1861.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/1861-cron-e2e-testids`
- Commit SHA: `28eca40a3d2e3a75b61105887e4faf58d4c0866e`
### Validation Run
- [x] `pnpm --filter openhuman-app exec prettier --check src/components/settings/panels/CronJobsPanel.tsx test/e2e/helpers/element-helpers.ts test/e2e/specs/cron-jobs-flow.spec.ts` - passed
- [x] `pnpm typecheck` - passed
- [x] Focused tests: N/A, E2E spec migration not run locally
- [x] Rust fmt/check (if changed): `cargo fmt --all --check` - passed; `git diff --check` - passed
- [x] Tauri fmt/check (if changed): N/A
### Validation Blocked
- `command:` `pnpm --filter openhuman-app exec tsc -p test/tsconfig.e2e.json --noEmit`
- `error:` local command could not find `tsc` / `@wdio/globals/types` via that invocation
- `impact:` app-wide `pnpm typecheck` passes; remote E2E/TS jobs remain authoritative for the E2E tsconfig
### Behavior Changes
- Intended behavior change: none for users; E2E selectors now target stable hooks.
- User-visible effect: none.
### Parity Contract
- Legacy behavior preserved: cron load, refresh, pause/resume, run-history, and remove behavior unchanged.
- Guard/fallback/dispatch parity checks: spec still asserts the same UI and sidecar persistence behavior.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: this PR
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Tests**
* Added E2E helpers and updated cron-jobs flow to use stable test identifiers for more reliable UI interactions and polling.
* **Documentation**
* Added guidance on stable test ID naming and how to use the new E2E helpers in the testing guide.
* **Maintenance**
* Cron Jobs panel and controls now expose stable identifiers for testing (no user-facing behavior changes).
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2301?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Adds a fast-fail path when `composio_list_tools` ends up empty for requested or connected toolkits that do not have curated OpenHuman agent catalogs.
- Returns a clear unsupported-toolkit error instead of a successful empty `tools` response for uncurated scopes such as OneDrive, Excel, or Todoist.
- Keeps existing behavior for catalogued toolkits and direct-mode empty responses.
- Adds focused unit coverage for toolkit normalization and unsupported-toolkit messaging.
## Problem
- Some toolkits can be connected in the UI but do not have curated OpenHuman agent tool catalogs yet.
- When the agent asks `composio_list_tools` for those toolkits, it can receive an empty usable tool list and continue trying until max iterations.
- Users then see a generic agent failure instead of a direct explanation that the connected toolkit is not agent-ready.
## Solution
- Track the explicit `toolkits` filter, or the active connected toolkits when filtering to connected accounts.
- If the final `tools` list is empty and the scoped toolkit set includes uncatalogued toolkits, return a `ToolResult::error` with a concrete agent-ready support message.
- Leave catalog creation and UI preview/coming-soon badges as follow-up slices so this PR stays small.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] **Diff coverage ≥ 80%** — local coverage run is blocked by missing libclang; CI coverage gate will verify changed lines.
- [x] Coverage matrix updated — N/A: behavior-only Composio tool failure path, no feature row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` — N/A: no matrix feature ID changed.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) — N/A: no release smoke checklist surface changed.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section — N/A: partial fix for #2283; catalog/UI work remains.
## Impact
- Runtime: Composio agent tool discovery.
- User-visible: the agent gets a direct unsupported-toolkit message instead of looping on an empty action list.
- Compatibility: catalogued toolkits still return tools as before; direct mode still returns success+empty by design.
## Related
- Refs #2283
- Follow-up PR(s)/TODOs: add curated catalogs for OneDrive/Excel/Todoist; add UI preview/agent-coming-soon labeling for uncatalogued connected toolkits.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/2283-uncurated-toolkit-fast-fail`
- Commit SHA: `d299c8ae92c690b911647f22746372572f17ff60`
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: no frontend changes.
- [x] `pnpm typecheck` — N/A: no TypeScript changes.
- [x] Focused tests: blocked locally; see Validation Blocked.
- [x] Rust fmt/check (if changed): `cargo fmt --check` passed.
- [x] Tauri fmt/check (if changed): N/A: no Tauri shell changes.
### Validation Blocked
- `command:` `cargo test --lib empty_uncurated_toolkits_message --manifest-path Cargo.toml`
- `error:` `whisper-rs-sys` build script could not find `clang.dll` / `libclang.dll`; `LIBCLANG_PATH` is unset in this Windows environment.
- `impact:` focused Rust tests could not run locally, but the helper tests are included for CI.
### Behavior Changes
- Intended behavior change: empty `composio_list_tools` results for uncatalogued requested/connected toolkits now fail fast with a useful message.
- User-visible effect: the agent should stop burning through max iterations when a connected toolkit is not yet agent-ready.
### Parity Contract
- Legacy behavior preserved: catalogued toolkits, scope filtering, connection filtering, and direct-mode short-circuit behavior are unchanged.
- Guard/fallback/dispatch parity checks: unit tests cover requested toolkit normalization, uncatalogued toolkit messaging, and catalogued toolkit no-op behavior.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): none found for #2283 at PR creation time.
- Canonical PR: this PR for the fast-fail slice only.
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved toolkit filtering so empty results now return clear, user-facing guidance when selected toolkits lack curated agent tools, including which toolkits are affected.
* **Tests**
* Added unit tests to validate normalized toolkit filtering and the new uncatalogued-toolkit messaging behavior, including provider-backed cases.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2293?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- require `OPENHUMAN_E2E_MODE=1` before `openhuman.test_reset` can wipe state
- export the runtime flag from the unified E2E session runner
- document the E2E runtime flag in the E2E testing guide
Closes#1863.
## Testing
- [x] `cargo fmt --all --check`
- [x] `git diff --check`
- [x] `cargo test -p openhuman --features e2e-test-support test_support::rpc --lib` attempted locally; blocked before tests by missing `libclang`/`clang.dll` from `whisper-rs-sys`
- [x] `bash -n app/scripts/e2e-run-session.sh` attempted locally; blocked because Bash resolves to WSL and WSL is not enabled on this machine
## Checklist
- [x] I have tested my changes locally or explained why local testing was limited.
- [x] I have added or updated tests for behavior changes.
- [x] I have updated documentation where needed.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
## Release Notes
* **Documentation**
* Updated end-to-end testing documentation with new environment variable details.
* **Tests**
* Enhanced end-to-end testing infrastructure with explicit mode verification for test-support operations.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2326?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Clarifies in the root README that managed integrations are backend-proxied through OpenHuman's Composio connector layer.
- Updates the integrations docs to distinguish managed mode from direct Composio mode.
- Documents that direct mode needs the user's own Composio API key and separately hosted trigger webhook plumbing.
## Problem
- #2020 asks for clearer disclosure around cloud/backend and integration dependencies.
- The README advertised 118+ integrations with one-click OAuth, but did not state the managed Composio/backend boundary near that claim.
- The integrations page said users did not need to think about Composio, which is true for managed mode but incomplete for direct/BYO mode.
## Solution
- Add a short managed-vs-direct disclosure beside the README integrations bullet.
- Replace the vague Composio parenthetical in the integrations docs with explicit backend, OAuth, rate-limit, and webhook responsibilities.
- Add the direct-mode privacy-boundary change near the existing Privacy boundary section.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) — N/A: docs-only clarification.
- [x] **Diff coverage ≥ 80%** — N/A: docs-only change.
- [x] Coverage matrix updated — N/A: docs-only change.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related`
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces — N/A: docs-only change.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section — N/A: #2020 is broader; this PR references it as a scoped docs follow-up.
## Impact
- Users evaluating OAuth/integration architecture get clearer docs before connecting accounts.
- No runtime behavior changes.
## Related
- Refs: #2020
- Follow-up PR(s)/TODOs: N/A
- Coverage matrix feature IDs: N/A: docs-only change.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: codex/2020-composio-disclosure-docs
- Commit SHA: 0d5a7ec2
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: docs-only change.
- [x] `pnpm typecheck` — N/A: docs-only change.
- [x] Focused tests: N/A: docs-only change.
- [x] Rust fmt/check (if changed): N/A: no Rust files changed.
- [x] Tauri fmt/check (if changed): N/A: no Tauri files changed.
- [x] `git diff --check`
### Validation Blocked
- `command:` N/A
- `error:` N/A
- `impact:` N/A
### Behavior Changes
- Intended behavior change: documentation now names the managed Composio/backend path and direct-mode responsibility split.
- User-visible effect: clearer README/GitBook disclosure for integration setup.
### Parity Contract
- Legacy behavior preserved: no code paths changed.
- Guard/fallback/dispatch parity checks: N/A.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: N/A
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Documentation**
* Clarified how Composio-backed integrations work in managed mode versus the new direct mode
* Updated documentation to explain that managed mode handles OAuth, rate limits, and webhooks through the backend, while direct mode requires users to manage webhooks with their own Composio API key
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2325?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Localizes the context-diagram alt text in `README.md`, `README.ja-JP.md`, and `README.ko.md`.
- Leaves the already-present `bash` install fences unchanged.
- Aligns these README variants with the localized alt-text pattern already used by the German and Simplified Chinese READMEs.
## Problem
- #2162 tracks markdown-lint cleanup for root/Japanese/Korean READMEs.
- The install fences are already fixed on current `main`, but the context diagram still used generic English alt text in all three files.
## Solution
- Replace `OpenHuman context diagram` with descriptive localized alt text per README locale.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) — N/A: docs-only alt text change.
- [x] **Diff coverage ≥ 80%** — N/A: docs-only change.
- [x] Coverage matrix updated — N/A: docs-only change.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related`
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces — N/A: docs-only change.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Documentation accessibility metadata improves for screen readers and markdown-lint checks.
- No runtime impact.
## Related
- Closes: #2162
- Follow-up PR(s)/TODOs: N/A
- Coverage matrix feature IDs: N/A: docs-only change.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: codex/2162-readme-alt-locales
- Commit SHA: 0f5a796d
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: docs-only change.
- [x] `pnpm typecheck` — N/A: docs-only change.
- [x] Focused tests: N/A: docs-only change.
- [x] Rust fmt/check (if changed): N/A: no Rust files changed.
- [x] Tauri fmt/check (if changed): N/A: no Tauri files changed.
- [x] `git diff --check`
- [x] Verified install fences already use `bash` in the three affected READMEs.
### Validation Blocked
- `command:` N/A
- `error:` N/A
- `impact:` N/A
### Behavior Changes
- Intended behavior change: localized alt text for the README context diagram.
- User-visible effect: better accessibility metadata in README variants.
### Parity Contract
- Legacy behavior preserved: README layout, image path, and install snippets unchanged.
- Guard/fallback/dispatch parity checks: N/A.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: N/A
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Documentation**
* Improved documentation accessibility and internationalization through refined image alt text descriptions. Updated the OpenHuman context-building diagram descriptions across English, Japanese, and Korean README versions with more accurate, language-appropriate text to better serve all international users and enhance overall documentation clarity.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2324?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Routes live/current factual requests (weather, forecasts, recent web facts, "use Grok/live data") to the available `research` tool.
- Replaces the stale `delegate_researcher` prompt reference with the synthesized tool name `research`.
- Updates the chat harness subagent fixture to emit `research` so the forced tool call matches the current delegation surface.
- Adds a prompt-builder regression test that locks the live-data rule and rejects the stale tool name.
## Problem
- The orchestrator could acknowledge live weather/research requests with "on it" without actually calling the research tool.
- The prompt named `delegate_researcher`, but the current researcher tool is exposed as `research` via `delegate_name = "research"`.
- Users who named an unwired provider like Grok could stall the agent instead of falling back to the available live research path.
## Solution
- Teach the orchestrator to call `research` for live/current/time-sensitive facts that direct tools cannot answer.
- Explicitly tell it not to stop at "on it" and not to wait for the exact named provider when that provider is not wired in.
- Align the E2E harness fixture with the real `research` tool name.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement) - added prompt regression assertion and updated E2E forced tool fixture.
- [x] **Diff coverage >= 80%** - N/A locally: tiny prompt/test fixture change; CI diff coverage will be authoritative.
- [x] Coverage matrix updated - N/A: prompt routing change, no feature row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` - N/A: no matrix feature ID applies.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) - N/A: no release-cut surface.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Runtime: orchestrator prompt only, plus E2E harness fixture alignment.
- User-visible effect: live weather/current fact requests should call research instead of ending with an acknowledgement.
- No migration, security, or dependency impact.
## Related
- Closes#2164
- Follow-up PR(s)/TODOs: N/A
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/2164-live-data-research`
- Commit SHA: `dc63d1d3e1ea531a1609594debd1e0ca95329b27`
### Validation Run
- [x] `pnpm --filter openhuman-app exec prettier --check test/e2e/specs/chat-harness-subagent.spec.ts` - passed
- [x] `pnpm typecheck` - N/A: comments/string fixture plus Rust prompt text only
- [x] Focused tests: `cargo test --lib build_routes_live_facts_to_research_tool` attempted; blocked before test execution by local `libclang` setup
- [x] Rust fmt/check (if changed): `cargo fmt --all --check` - passed; `git diff --check` - passed
- [x] Tauri fmt/check (if changed): N/A
### Validation Blocked
- `command:` `cargo test --lib build_routes_live_facts_to_research_tool`
- `error:` `whisper-rs-sys` build could not find `clang.dll` / `libclang.dll`; `LIBCLANG_PATH` is unset in this Windows environment
- `impact:` Rust prompt unit test did not execute locally; remote CI environment should validate it
### Behavior Changes
- Intended behavior change: live/current factual requests route to `research` when no direct tool can answer.
- User-visible effect: requests like "forecast for Bremerhaven today" should produce a researched answer instead of a bare "on it" acknowledgement.
### Parity Contract
- Legacy behavior preserved: direct answers, connected integration routing, crypto/code/planner/critic/archive routing remain unchanged.
- Guard/fallback/dispatch parity checks: prompt test asserts live facts mention weather/forecast/Grok fallback and rejects stale `delegate_researcher` naming.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): N/A
- Canonical PR: this PR
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
## Release Notes
* **Tests**
* Enhanced test coverage for research request handling and subagent communication.
* **Chores**
* Improved internal routing and terminology for research operations to support live, time-sensitive fact queries more effectively.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2299?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Rewrites failed `morning_briefing` cron alert bodies to a concrete recovery message instead of the generic agent fallback.
- Strips `<openhuman-link>` tags from cron alert bodies before they are persisted to the notification center.
- Uses recent-notification dedupe for cron alerts so repeated identical failures do not spam the list.
- Sanitizes notification card previews on the frontend so raw OpenHuman link markup is never rendered as text.
## Problem
- Failed morning briefing runs stored the generic agent failure message directly in the notifications store.
- That message is designed for chat bubbles and includes internal `<openhuman-link>` markup.
- The notification center renders integration notification bodies as plain text, so users saw raw markup and a non-actionable error.
## Solution
- Add a cron alert body formatter that detects the built-in morning briefing failure shape and replaces it with actionable copy.
- Preserve normal successful briefing content, while stripping any OpenHuman link tags down to their visible label for notification previews.
- Route cron notification persistence through the existing `insert_if_not_recent` dedupe helper.
- Add frontend preview formatting plus component coverage for link-markup stripping.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] **Diff coverage ≥ 80%** — local coverage run is blocked by missing libclang; CI coverage gate will verify changed lines.
- [x] Coverage matrix updated — N/A: behavior-only cron/notification rendering fix, no feature row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` — N/A: no matrix feature ID changed.
- [x] No new external network dependencies introduced (mock/local tests only)
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) — N/A: notification rendering copy only.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Runtime: cron alert persistence and notification center preview rendering.
- User-visible: morning briefing failures now explain likely recovery steps; raw `<openhuman-link>` markup is hidden in notifications.
- Compatibility: chat-facing generic agent fallback remains unchanged.
## Related
- Closes#2279
- Follow-up PR(s)/TODOs: verify the final desktop notification flow on macOS build hardware once CI artifacts are available.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/2279-morning-briefing-notifications`
- Commit SHA: `513e41ccd39f483563460cf742246ab9850d1cfc`
### Validation Run
- [x] `pnpm --filter openhuman-app exec prettier --check src/components/notifications/NotificationCard.tsx src/components/notifications/NotificationCard.test.tsx` passed.
- [x] `pnpm typecheck` passed.
- [x] `pnpm --filter openhuman-app test -- src/components/notifications/NotificationCard.test.tsx` passed.
- [x] Rust fmt/check (if changed): `cargo fmt --all --check` passed.
- [x] Focused Rust tests: blocked locally; see Validation Blocked.
- [x] Tauri fmt/check (if changed): N/A: no Tauri shell changes.
### Validation Blocked
- `command:` `cargo test --lib cron_alert_body --manifest-path Cargo.toml`
- `error:` `whisper-rs-sys` build script could not find `clang.dll` / `libclang.dll`; `LIBCLANG_PATH` is unset in this Windows environment.
- `impact:` focused Rust tests could not run locally, but the scheduler tests are included for CI.
- `note:` full `pnpm --filter openhuman-app format:check` also reports pre-existing repo-wide Prettier drift; changed notification files pass targeted Prettier check.
### Behavior Changes
- Intended behavior change: failed morning briefing cron alerts now use actionable notification copy and identical recent cron alerts are skipped.
- User-visible effect: notification bodies do not show raw OpenHuman link markup.
### Parity Contract
- Legacy behavior preserved: successful cron output still reaches proactive delivery and notification persistence; chat fallback message remains unchanged.
- Guard/fallback/dispatch parity checks: unit tests cover morning briefing failure rewrite, link stripping, duplicate alert persistence, and frontend preview rendering.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): none found for #2279 at PR creation time.
- Canonical PR: this PR.
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Bug Fixes**
* Notification previews no longer show raw markup tags and now collapse whitespace, improving readability.
* **Improvements**
* Morning briefing failures display a clear, user-friendly failure message.
* Repeated cron job alerts are deduplicated to reduce notification noise.
* **Tests**
* Added tests covering notification preview formatting, cron alert rewriting, and deduplication.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2296?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- Narrows JSON-RPC session-expiry detection to confirmed OpenHuman app-session shapes.
- Keeps generic downstream/provider `401 Unauthorized` and `invalid token` errors from publishing `SessionExpired`.
- Adds diagnostic logging that includes the RPC method and sanitized reason when an auth-like error is not treated as session expiry.
- Updates classifier tests for true session expiry, scoped 401s, and generic invalid-token text.
## Problem
- The previous JSON-RPC classifier treated any `401` + `unauthorized` text as a global app session expiry.
- That could clear the stored session and bounce users to sign-in for unrelated provider, integration, or channel errors.
- This is the root pattern behind the Discord card logout report.
## Solution
- Reuse the strict `observability::is_session_expired_message` classifier at the JSON-RPC dispatch boundary.
- Preserve `SessionExpired` publication for explicit OpenHuman auth states: `session expired`, `SESSION_EXPIRED`, `no backend session token`, and `session JWT required`.
- Add a diagnostics-only predicate for generic auth-looking errors so they are logged with method context but do not clear the session.
- Update comments in `observability` to match the stricter dispatch behavior.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] **Diff coverage ≥ 80%** — local coverage run is blocked by missing libclang; CI coverage gate will verify changed lines.
- [x] Coverage matrix updated — N/A: behavior-only core classifier hardening, no feature row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` — N/A: no matrix feature ID changed.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) — N/A: no release smoke checklist surface changed.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Runtime: core JSON-RPC auth/error handling.
- User-visible: scoped provider/integration 401s should remain recoverable errors instead of logging the user out.
- Security/privacy: session-expiry reasons are sanitized before logging/publishing.
- Compatibility: explicit OpenHuman session-expired sentinels still clear the session as before.
## Related
- Closes#2286
- Refs #2285
- Follow-up PR(s)/TODOs: identify the exact Discord card-click RPC from user logs if the UI still needs a provider-specific error state.
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `codex/2286-session-expired-narrowing`
- Commit SHA: `6f98f1e28a113afd0ea47908d0a397ecfe681560`
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — N/A: no frontend changes.
- [x] `pnpm typecheck` — N/A: no TypeScript changes.
- [x] Focused tests: blocked locally; see Validation Blocked.
- [x] Rust fmt/check (if changed): `cargo fmt --check` passed.
- [x] Tauri fmt/check (if changed): N/A: no Tauri shell changes.
### Validation Blocked
- `command:` `cargo test --lib is_session_expired_error --manifest-path Cargo.toml`
- `error:` `whisper-rs-sys` build script could not find `clang.dll` / `libclang.dll`; `LIBCLANG_PATH` is unset in this Windows environment.
- `impact:` focused Rust tests could not run locally, but the changed classifier tests are included for CI.
### Behavior Changes
- Intended behavior change: generic provider/integration/channel `401 Unauthorized` text no longer publishes `DomainEvent::SessionExpired`.
- User-visible effect: users should not be logged out by a scoped downstream 401, including the suspected Discord card-click path.
### Parity Contract
- Legacy behavior preserved: explicit OpenHuman session expiry, uppercase `SESSION_EXPIRED`, missing backend session token, and missing session JWT still clear the app session.
- Guard/fallback/dispatch parity checks: classifier tests cover true session expiry, generic 401, invalid token, and local missing-session cases.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): none found for #2286/#2285 at PR creation time.
- Canonical PR: this PR.
- Resolution (closed/superseded/updated): N/A
Co-authored-by: aqilaziz <gonzes7@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>