Skip to content

test(gui): pin existing guards at their entry points - #32

Open
SaulBuilds wants to merge 5 commits into
mainfrom
test/gn-gap-pins
Open

SaulBuilds wants to merge 5 commits into
mainfrom
test/gn-gap-pins

Conversation

@SaulBuilds

Copy link
Copy Markdown
Contributor

What

Tests only. These pin existing guards at their entry points, not only at the helper. For each guard listed below, I reverted the guard in place on main @ 0656235, ran the package suite, and saw it stay green. Each new test fails on an assertion when that guard is reverted, and passes when it is restored.

The production code is unchanged. The only non-test addition is a #[cfg(test)] seam, WalletService::expire_reauth_window_for_test, which ages the re-auth clock.

citrate-desktop-app

Guard Entry point New test
Supervision-token fail-closed + loopback URL check NodeAgentClient::try_new tests/relay_client_fail_closed.rs::try_new_fails_closed_on_missing_token_and_non_loopback_url
Real transfer value handed to the re-auth gate CitrateLinkService::send_sponsored (loopback JSON-RPC stub) send_sponsored_passes_the_real_value_to_the_reauth_gate
AA chain-id guard send_sponsored send_sponsored_refuses_off_the_aa_chain
CITRATE_AUTH_URL / CITRATE_BUNDLER_URL policy CitrateLinkService::new new_applies_the_authority_url_policy_to_env_overrides
Origin / Host guard MCP dispatch route dispatch_refuses_cross_origin_and_foreign_host_before_routing
Calldata size cap on a canonical dynamic payload RelayValidator::validate validator_refuses_canonical_submit_result_over_the_calldata_cap
Constant-time compare looks at every byte ct_eq, session/end ct_eq_rejects_a_single_byte_difference_at_any_position, session_end_refuses_a_near_miss_owner_token
Chat fallback chain only from default_chat_endpoints AppCore wiring (source-level) appcore_chat_fallbacks_come_only_from_default_chat_endpoints
Pinned bootnode identity uses connect_to_trusted NodeService::start connect loop (source-level) pinned_bootnode_identity_is_enforced_at_connect
One rev-pinned source per git crate Cargo.lock tests/lockfile_single_source.rs (2 tests)

citrate-native

The UI callbacks are closures inside main(), so they can't be driven without a window. These are source-level pins on the production text: the test module is cut out first, each guard is matched by its exact trimmed line, inside its own handler and before the action it protects, and each has a negative control.

Guard New test
Send dialog refuses an empty password send_handler_requires_a_password_before_signing
Send dialog validates the recipient send_handler_validates_the_recipient_before_signing
In-flight send flag set before the send send_handler_disables_the_button_before_the_send_starts
Unlocking flag set before the attempt unlock_handler_marks_unlocking_before_the_attempt
Verify-failure log carries no seed words mnemonic_verify_failure_log_carries_no_seed_material
Faucet is testnet-only and funds the selected account faucet_handler_is_testnet_only_and_funds_the_selected_account
Chat send plan uses the selected account + validated recipient chat_send_plan_resolves_the_selected_account_and_validates_the_recipient
Every contract-write gate is a plain if !confirm_tx_intent( that returns before the write natb007_write_confirmation.rs: 3 new tests (main, app_binder, negative controls)

Standard: met

  • Revert check: for every row, the guard was reverted in place and the named test went red, then the guard was restored (harness: one guard at a time, cargo test -p <pkg>). Before these tests, every one of those reverts was green on the existing suites.
  • Suites (display-free, isolated user/pid/net namespace, temp HOME, no D-Bus, fresh session keyring):
    • cargo test -p citrate-desktop-app: 454 → 466 passed, 0 failed (1 ignored, unchanged).
    • cargo test -p citrate-native --bins --tests: 192 → 202 passed, 0 failed. No window is opened and no display is needed.
  • Host safety: no test touches the network. The RPC/bundler stub binds 127.0.0.1:0, env overrides point at temp files, and none of the new tests use the keychain.
  • fmt: cargo fmt --all -- --check passes.
  • clippy: cargo clippy -p citrate-desktop-app --all-targets -- -D warnings fails with the same 6 lints on main and on this branch. The new code adds none.
  • Negative controls: every source-level pin asserts that its check rejects the bad shape.
  • Dead code: none was added. Separately, the grant_owners reap in handle_initialize can never fire, because the grant store marks grants revoked and never drops them. It's worth deleting in a follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4

SaulBuilds and others added 5 commits October 22, 2026 18:38
… authority-url guards at their entry points

Adds tests at the call sites (not only the helpers) for: the relay
client's production constructor (token + loopback), send_sponsored's
chain guard and value hand-off to the re-auth gate, the MCP dispatch
origin/host guard, the CITRATE_AUTH_URL/BUNDLER_URL policy in
CitrateLinkService::new, the relay calldata size cap on a canonical
dynamic payload, and source-level pins for the AppCore chat wiring and
the pinned-bootnode connect call. Tests only (plus a cfg(test) seam to
age the re-auth clock).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4
… session/end

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4
…r call sites

The UI callbacks are closures inside main(), so these are source-level
pins on the production text (the test module is cut out first), by
exact line, inside each handler and before the action it protects,
each with a negative control: send-dialog password and recipient
checks, the in-flight send flag, the unlocking flag, the seed-free
verify-failure log, the faucet's testnet/selected-account checks, the
chat send plan, and a stricter shape check that every contract-write
confirmation gate is a plain refusal that returns before the write.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4
@SaulBuilds
SaulBuilds requested a review from a team as a code owner October 23, 2026 03:14
));
wallet.set_rpc_url(&stub);
wallet
.unlock(LINKED_EOA, "password123")

@BerryManifold BerryManifold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Codex static review of 9a63f0fc1119127843b12c0b4b188351974643c3 is complete. Result: incomplete; details retained privately. Details and coverage limits are recorded in the project's private review log. No tests were executed by this reviewer. Both account submissions represent the same Codex review, not independent reviews.

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

Automated Codex static review of 9a63f0fc1119127843b12c0b4b188351974643c3 is complete. Result: incomplete; details retained privately. Details and coverage limits are recorded in the project's private review log. No tests were executed by this reviewer. Both account submissions represent the same Codex review, not independent reviews.

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants