Skip to content

test(e2e): backfill coverage for the wallet-not-configured reporting decision - #5967

Merged
M3gA-Mind merged 3 commits into
tinyhumansai:mainfrom
M3gA-Mind:w7/e2e-backfill
Sep 2, 2026
Merged

test(e2e): backfill coverage for the wallet-not-configured reporting decision#5967
M3gA-Mind merged 3 commits into
tinyhumansai:mainfrom
M3gA-Mind:w7/e2e-backfill

Conversation

@M3gA-Mind

@M3gA-Mind M3gA-Mind commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Backfills e2e coverage for the wallet-not-configured reporting decision (#5805, fixed by #5811), which an audit of the last week's merges found had no e2e coverage anywhere in tests/ExpectedErrorKind, expected_error_kind and WALLET_NOT_CONFIGURED returned zero matches across both Rust e2e lanes.

Adds tests/observability_wallet_expected_e2e.rs and registers the suite in scripts/test-rust-e2e.sh so it actually runs. No product code is changed.

Why this one first

Of the five items in my audit slice this was the highest-risk gap, for two independent reasons:

  • The classifier is deliberately substring-based over caller-supplied text, so it fails dangerously in both directions. Too narrow and Sentry re-floods (55 error events in 72 minutes on one ordinary session). Too broad and a genuine defect is silently demoted and never paged.
  • The demoted arm withholds the message body, so if it ever misclassifies, the evidence needed to notice is the thing it suppresses.

What the tests assert

They drive the real report_error_or_expected entry point and assert on what it emits, not only on the classifier's return value — "does not page" is the property the issue is about, and a classification that did not change what is emitted would fix nothing.

Coverage of the fix (these fail if the fix is reverted):

Test Asserts
a_context_wrapped_wallet_state_is_classified_as_expected the exact self_identity key_status: {e} shape from #5805 classifies as expected — this is the form that regressed
a_multiply_wrapped_wallet_state_is_still_classified_as_expected demotion survives arbitrary nesting depth, not just one wrapper
the_bare_wallet_sentinel_is_classified_as_expected the direct-RPC shape stays demoted
reporting_a_wrapped_wallet_state_emits_info_and_not_error the emitted record is INFO with kind = "wallet_not_configured", and is not ERROR

Guards, not coverage (these pass with the fix reverted, by design):

Test Why it exists
a_genuine_wallet_failure_is_not_demoted a substring matcher over caller-supplied text has a wide blast radius; this pins that a real wallet defect still pages, so a future widening of the needle fails here
reporting_a_genuine_wallet_failure_still_emits_error the contrast case — together with the INFO test it pins that the two are routed differently, so a change demoting everything fails rather than passing both

I am calling those two out explicitly rather than counting them as coverage, because they do not discriminate the change.

Revert-check

Fix disabled by short-circuiting the is_wallet_not_configured_message arm in expected_error_kind, then restored. All runs via ~/tinyhuman/ci-slot.sh.

Stage Result
With fix 6 passed; 0 failed
Fix reverted 3 passed; 4 failed — the four failures named my assertions
Fix restored 6 passed; 0 failed

The reverted run reproduced the issue verbatim in the captured output:

thread 'a_context_wrapped_wallet_state_is_classified_as_expected' panicked:
  assertion `left == right` failed: the RPC layer wraps the wallet sentinel as
  `{context}: {e}` (#5805); a classifier that only matches the bare message lets
  this page. Message under test: self_identity key_status: wallet is not
  configured; run wallet setup first
    left: None
   right: Some(WalletNotConfigured)

thread 'reporting_a_wrapped_wallet_state_emits_info_and_not_error' panicked:
  an unconfigured wallet is expected user-state and must be recorded as a
  breadcrumb at INFO. Captured output:
  ERROR openhuman::observability::report_error: [observability] rpc.invoke_method
  failed: self_identity key_status: wallet is not configured; run wallet setup first

That ERROR ... report_error line is exactly the log #5805 reported 55 times.

One test was dropped for being vacuous

the_demoted_wallet_record_withholds_caller_supplied_wrapper_text passed with the fix reverted, so it was dropped rather than shipped. Its payload was token-shaped (sk-ant-…) and the error path already runs sanitize_api_error, which redacts token-shaped text regardless — so the assertion held either way and did not discriminate the change. Pinning the deliberate withholding is still worth doing; it needs a payload the sanitizer will not redact, and a revert-check to prove it discriminates.

Not covered by this PR

The other four items in my slice (#5775, #5926, #5945, #5840) are frontend and belong in the Playwright lane. Three specs are written but are not included here because I could not revert-check them under the current machine limits, and an un-revert-checked test is exactly what this work exists to avoid shipping. They are preserved with notes at ~/tinyhuman/bugs/W7-unverified-specs/ and documented in ~/tinyhuman/bugs/W7-test-findings.md, including a specific warning about the IME one: the obvious version of that test is vacuous, and whoever verifies it must confirm it actually fails with the fix reverted.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) — four coverage tests plus two negative guards; the failure path is the whole point of the suite
  • Diff coverage ≥ 80%N/A: this PR adds only a test target and one line registering it; there is no product code on the changed lines for diff-cover to measure
  • Coverage matrix updated — N/A: behaviour-only change; no feature row added, removed or renamed
  • All affected feature IDs from the matrix are listed in the PR description under ## RelatedN/A: no matrix feature IDs affected
  • No new external network dependencies introduced — the suite is in-process; the tracing capture uses tracing-subscriber, already a dependency
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: no release-cut surface; test-only change
  • Linked issue closed via Closes #NNN in the ## Related section — N/A: #5805 is already closed by #5811; this backfills its missing coverage and should not re-close anything

Related

Impact

  • No runtime or product behaviour change. One new tests/*_e2e.rs target and its registration.
  • main is currently red on the Rust Quality layout gate — pre-existing, being fixed separately, not from this PR.

Summary by CodeRabbit

  • Bug Fixes

    • Corrected reporting for wallet-not-configured states, including context-wrapped and multiply-wrapped errors.
    • Ensured genuine wallet failures continue to be reported as errors.
    • Wallet-not-configured events are now logged at info level with the wallet_not_configured classification.
  • Tests

    • Added end-to-end coverage for wallet error classification, wrapping scenarios, and emitted log levels.
    • Included the new observability test in the default Rust E2E test suite.

@M3gA-Mind
M3gA-Mind requested a review from a team September 2, 2026 12:16

@tinysweeper tinysweeper 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.

tinysweeper found nothing blocking. Approving.

$0.0000 · 0 in / 0 out · 486 embedded · openrouter/openai/text-embedding-3-small

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Sep 2, 2026
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 09cdc31a-9efa-4989-af94-9b2adb513f77

📥 Commits

Reviewing files that changed from the base of the PR and between 52f3c5d and 7905443.

📒 Files selected for processing (1)
  • tests/observability_wallet_expected_e2e.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/observability_wallet_expected_e2e.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


Important

Approval pending

CodeRabbit has no unresolved comments, but it could not review the latest commit because the review limit was reached. Follow the review guidance in this comment to continue.

📝 Walkthrough

Walkthrough

The PR adds end-to-end tests for wallet-not-configured classification and reporting. It verifies tracing output for expected wallet state and genuine wallet failures. The test suite is added to the default Rust E2E suite list.

Changes

Wallet reporting observability

Layer / File(s) Summary
Wallet classification and reporting tests
tests/observability_wallet_expected_e2e.rs
Adds tracing capture helpers and tests for wrapped and bare wallet-not-configured errors, genuine wallet failures, and INFO versus ERROR reporting.
Default E2E suite wiring
scripts/test-rust-e2e.sh
Adds observability_wallet_expected_e2e to the default Rust E2E suite list.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 79054

This PR adds coverage for wallet-not-configured reporting without changing product behavior; no actionable merge-blocking risk remains beyond normal checks and review.

Poem

A rabbit checks the wallet gate,
Wrapped errors meet a kinder fate.
INFO shines where setup waits,
Real failures keep ERROR traits.
Tests hop through logs in flight,
And guard the signal day and night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the end-to-end test coverage added for the wallet-not-configured reporting decision.
Linked Issues check ✅ Passed The PR satisfies the linked issue objective [#5805] by adding end-to-end coverage for expected wallet-not-configured outcomes, including wrapped messages, INFO-level reporting with wallet_not_configur…
Out of Scope Changes check ✅ Passed The changes are limited to the requested end-to-end test and its registration in the Rust E2E suite. No unrelated product or runtime changes are present.
Full details: Linked Issues check

Explanation

The PR satisfies the linked issue objective [#5805] by adding end-to-end coverage for expected wallet-not-configured outcomes, including wrapped messages, INFO-level reporting with wallet_not_configured, and ERROR-level reporting for genuine wallet failures.


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

@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: 52f3c5dba5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread tests/observability_wallet_expected_e2e.rs
coderabbitai[bot]
coderabbitai Bot previously approved these changes Sep 2, 2026
@M3gA-Mind

Copy link
Copy Markdown
Collaborator Author

Pushed 790544367 — rustfmt on the new test file. Whitespace only, no assertion or test name changed; the revert-check reported above still stands.

Worth recording that the Rust Quality (fmt, clippy) failure on the first push was mine, not the known pre-existing layout gate. I checked rather than assuming, with rustfmt --edition 2021 --check on just the new file:

Diff in tests/observability_wallet_expected_e2e.rs:124:
-    let nested =
-        format!("rpc.invoke_method failed: self_identity key_status: {WALLET_NOT_CONFIGURED_MESSAGE}");
+    let nested = format!(
+        "rpc.invoke_method failed: self_identity key_status: {WALLET_NOT_CONFIGURED_MESSAGE}"
+    );

One wrapped line. Flagging it because "main is red on Rust Quality anyway" was an easy and wrong thing to conclude here.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Sep 2, 2026
…mansai#5805)

An unconfigured wallet is the default state of an optional feature, so the
condition must never reach Sentry as an error. tinyhumansai#5805 measured 55 error events
in 72 minutes on one ordinary local session while a genuine turn-killing
failure emitted nothing.

The part that regressed is the context-wrapped form: the bare sentinel was
already demoted by an exact-equality predicate, but the RPC layer lifts the
error with format!("self_identity key_status: {e}"), and exact equality stops
matching the moment any caller adds context. That shape appears ~800 times in
src/.

Adds tests/observability_wallet_expected_e2e.rs, driving the real
report_error_or_expected entry point and asserting on what it emits rather
than only on the classifier's return value, since "does not page" is the
property the issue is about. Registers the suite in scripts/test-rust-e2e.sh
so it actually runs.

Two of the six tests are deliberate guards rather than coverage of the fix:
they pin that a genuine wallet defect is still reported at ERROR, which is the
other side of the trade a substring matcher over caller-supplied text makes.
Whitespace only; no assertion or test name changed.
…not in logs

Codex on tinyhumansai#5967: this file's module doc says the observable contract is "this
does not page", but the assertions were on tracing output, and paging is not
decided there. `report_error_message` reaches Sentry by calling
`sentry::with_scope` / `capture_message` directly (core/observability.rs), not
through a tracing layer, and no Sentry tracing layer is installed here. So the
INFO/ERROR assertions would keep passing if the expected case started paging,
or if the genuine-error capture stopped.

The gate matters for where the fix belongs: that capture is
`#[cfg(feature = "crash-reporting")]`, which is absent from `[features]
default` but present in scripts/ci/product-features.txt — and the e2e lane
runs this target with that set (scripts/test-rust-e2e.sh passes
product-features.sh). The gap is real in the lane that runs it.

Add a `#[cfg(feature = "crash-reporting")] mod paging` counting envelopes on a
`sentry::test::TestTransport`, wired as tests/observability_smoke.rs does,
including its process-global `sentry::init` lock — cargo runs these functions
on parallel threads.

  a_wrapped_wallet_state_pages_nobody   -> 0 captured
  a_genuine_wallet_failure_still_pages  -> 1 captured

Added, not substituted: the INFO/ERROR assertions pin the breadcrumb's level
and its `kind` field, which is what makes a demotion attributable and which
TestTransport does not see. `#[cfg]` on the module rather than
`required-features` on the target: with the gate off there is nothing to
capture and both counts would be a vacuous 0, while `required-features` would
take the classification tests down with it in every contributor build — the
blunt instrument Cargo.toml already warns about on `observability_smoke`.

Proved non-vacuous: swapping the two inputs fails both new tests.

cargo test --features crash-reporting --test observability_wallet_expected_e2e
  ->  8 passed; 0 failed
@M3gA-Mind
M3gA-Mind merged commit 39388f6 into tinyhumansai:main Sep 2, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"wallet is not configured" logs at ERR to Sentry 55x in 72min while real turn failures emit nothing

1 participant