Skip to content

test: Wave 14 - comprehensive adapter and facade tests#40

Merged
EffortlessSteven merged 4 commits intomainfrom
wave-14/adapter-tests
Mar 1, 2026
Merged

test: Wave 14 - comprehensive adapter and facade tests#40
EffortlessSteven merged 4 commits intomainfrom
wave-14/adapter-tests

Conversation

@EffortlessSteven
Copy link
Copy Markdown
Member

Adds 79 tests across adapter crates and facade: rustcrypto (31), rustls (20), facade e2e (18), prop tests (10). All tests pass locally. No determinism/policy impact.

Copilot AI review requested due to automatic review settings March 1, 2026 18:30
@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 1, 2026

Warning

Rate limit exceeded

@EffortlessSteven has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 19 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0489cd1 and f423152.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • crates/uselesskey-rustcrypto/tests/rustcrypto_comprehensive.rs
  • crates/uselesskey-rustls/tests/rustls_comprehensive.rs
  • crates/uselesskey/Cargo.toml
  • crates/uselesskey/tests/facade_e2e.rs
  • crates/uselesskey/tests/prop_tests.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wave-14/adapter-tests

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

❤️ Share

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

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

Review Summary by Qodo

Add 79 comprehensive adapter and facade integration tests

🧪 Tests

Grey Divider

Walkthroughs

Description
• Adds 79 comprehensive integration tests across rustcrypto and rustls adapters
• Covers sign-verify round trips, deterministic key reproduction, and debug safety
• Includes facade e2e tests verifying order-independent derivation and label uniqueness
• Adds property-based tests validating determinism under random seeds
Diagram
flowchart LR
  A["Test Suite"] --> B["rustcrypto_comprehensive<br/>31 tests"]
  A --> C["rustls_comprehensive<br/>20 tests"]
  A --> D["facade_e2e<br/>18 tests"]
  A --> E["prop_tests<br/>10 tests"]
  B --> B1["RSA/ECDSA/Ed25519<br/>sign-verify"]
  B --> B2["Deterministic<br/>reproduction"]
  B --> B3["Debug safety<br/>no key leaks"]
  C --> C1["Certificate/key<br/>DER conversion"]
  C --> C2["TLS handshakes<br/>mTLS support"]
  C --> C3["Deterministic<br/>chains"]
  D --> D1["Order-independent<br/>derivation"]
  D --> D2["Label uniqueness<br/>verification"]
  E --> E1["Property-based<br/>determinism"]
  E --> E2["PEM format<br/>invariants"]
Loading

Grey Divider

File Changes

1. crates/uselesskey-rustcrypto/tests/rustcrypto_comprehensive.rs 🧪 Tests +497/-0

Comprehensive rustcrypto adapter integration tests

• Adds 31 comprehensive tests for RSA, ECDSA, Ed25519, and HMAC key types
• Tests sign-verify round trips with multiple message sizes and wrong message failures
• Validates deterministic key reproduction with same seed and different labels
• Verifies debug output safety (no PEM markers or key material leakage)
• Includes cross-type tests ensuring all key types work from same factory

crates/uselesskey-rustcrypto/tests/rustcrypto_comprehensive.rs


2. crates/uselesskey-rustls/tests/rustls_comprehensive.rs 🧪 Tests +408/-0

Comprehensive rustls adapter TLS integration tests

• Adds 20 comprehensive tests for TLS certificate and key handling
• Tests DER conversion correctness for certificates, chains, and private keys
• Validates TLS handshakes with certificate chains, mTLS, and SNI verification
• Tests deterministic chain and self-signed certificate reproduction
• Includes debug safety tests and cross-CA failure scenarios

crates/uselesskey-rustls/tests/rustls_comprehensive.rs


3. crates/uselesskey/tests/facade_e2e.rs 🧪 Tests +283/-0

Facade end-to-end deterministic behavior tests

• Adds 18 end-to-end tests verifying deterministic behavior through public facade API
• Tests deterministic reproduction for RSA, ECDSA, Ed25519, HMAC, and token types
• Validates order-independent derivation (ABC vs CBA generation order produces same keys)
• Verifies different labels produce different keys and debug output is safe
• Tests PEM format validity, factory modes, and seed round-trip functionality

crates/uselesskey/tests/facade_e2e.rs


View more (2)
4. crates/uselesskey/tests/prop_tests.rs 🧪 Tests +205/-0

Property-based determinism and format invariant tests

• Adds 10 property-based tests using proptest with random seed generation
• Tests deterministic reproduction for RSA (5 cases), ECDSA (20 cases), Ed25519 (30 cases), HMAC (30
 cases), and token (30 cases)
• Validates PEM well-formedness under random seeds and HMAC secret length spec compliance
• Verifies token prefix invariant and different seeds produce different keys
• Tests corrupt PEM never returns original through negative fixtures

crates/uselesskey/tests/prop_tests.rs


5. crates/uselesskey/Cargo.toml Dependencies +1/-0

Add proptest dependency for property tests

• Adds proptest to dev-dependencies for property-based testing

crates/uselesskey/Cargo.toml


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

qodo-free-for-open-source-projects bot commented Mar 1, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. PEM blob in proptests 📘 Rule violation ⛨ Security
Description
The new property tests commit a PEM-looking private key block string literal. This is a
secret-shaped blob in a test path and violates the fixture policy.
Code

crates/uselesskey/tests/prop_tests.rs[R191-192]

+            let pem = "-----BEGIN PRIVATE KEY-----\nMIIBVQIBADANBg==\n-----END PRIVATE KEY-----\n";
+
Evidence
The compliance rule forbids committing PEM/DER/key-like blobs under test/fixture paths. The property
test includes a PEM header/footer and base64 body in a string literal under
crates/uselesskey/tests/.

CLAUDE.md
crates/uselesskey/tests/prop_tests.rs[191-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A PEM-looking private key string literal is committed in property tests, which violates the no-secret-shaped-blobs rule.
## Issue Context
These literals can trip secret scanners and are disallowed even if they are not real keys.
## Fix Focus Areas
- crates/uselesskey/tests/prop_tests.rs[189-203]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. assert_eq! prints key DER 📘 Rule violation ⛨ Security
Description
The new rustls adapter tests compare private key DER bytes using assert_eq!, which will print key
material on failure. This can leak private keys into CI logs when a test fails.
Code

crates/uselesskey-rustls/tests/rustls_comprehensive.rs[R98-103]

+        let key = chain.private_key_der_rustls();
+        assert_eq!(
+            key.secret_der(),
+            chain.leaf_private_key_pkcs8_der(),
+            "private key DER must match source"
+        );
Evidence
The compliance rule forbids leaking key material via debug/log/error output. These added tests use
assert_eq! to compare raw private key DER returned by secret_der() and
leaf_private_key_pkcs8_der(), which would be printed on assertion failure.

CLAUDE.md
crates/uselesskey-rustls/tests/rustls_comprehensive.rs[98-103]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Rustls adapter tests use `assert_eq!` to compare private key DER values. On failure, this prints private key bytes into logs.
## Issue Context
Assertion failures are visible in CI output, and the compliance policy forbids leaking key material via logs/errors.
## Fix Focus Areas
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[94-104]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[333-346]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[155-160]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[177-182]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[185-190]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[199-204]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Handshake may succeed early 🐞 Bug ⛯ Reliability
Description
try_handshake returns Ok(()) even if the handshake never completes (it breaks on !progress and
does not verify is_handshaking() is false). This can cause flaky failures (or confusing assertions
downstream) when the handshake stalls or exceeds MAX_HANDSHAKE_ITERATIONS.
Code

crates/uselesskey-rustls/tests/rustls_comprehensive.rs[R50-84]

+/// Drive a TLS handshake between server and client. Returns Ok(()) on success.
+fn try_handshake(
+    server: &mut rustls::ServerConnection,
+    client: &mut rustls::ClientConnection,
+) -> Result<(), rustls::Error> {
+    let mut buf = Vec::new();
+    for _iteration in 0..MAX_HANDSHAKE_ITERATIONS {
+        let mut progress = false;
+
+        buf.clear();
+        if client.wants_write() {
+            client.write_tls(&mut buf).unwrap();
+            if !buf.is_empty() {
+                server.read_tls(&mut &buf[..]).unwrap();
+                server.process_new_packets()?;
+                progress = true;
+            }
+        }
+
+        buf.clear();
+        if server.wants_write() {
+            server.write_tls(&mut buf).unwrap();
+            if !buf.is_empty() {
+                client.read_tls(&mut &buf[..]).unwrap();
+                client.process_new_packets()?;
+                progress = true;
+            }
+        }
+
+        if !progress {
+            break;
+        }
+    }
+    Ok(())
+}
Evidence
The helper breaks out of the loop when no progress is made and then unconditionally returns Ok,
without checking whether either side is still handshaking.

crates/uselesskey-rustls/tests/rustls_comprehensive.rs[48-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`try_handshake` can return `Ok(())` even when the TLS handshake is still in progress (or stalled), because it breaks on `!progress` and unconditionally returns success.
## Issue Context
Several tests rely on `try_handshake` to drive the handshake to completion (or failure). If the handshake requires more iterations than `MAX_HANDSHAKE_ITERATIONS`, or enters a state where no side wants to write but the handshake is still not complete, the helper will silently report success, and tests may fail later in less-obvious ways.
## Fix Focus Areas
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[48-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new “Wave 14” test suite expanding coverage for the uselesskey facade and adapter crates, focusing on deterministic behavior and end-to-end correctness across key types.

Changes:

  • Add facade property tests (proptest) covering determinism and basic invariants across RSA/ECDSA/Ed25519/HMAC/token.
  • Add facade end-to-end integration tests for determinism, ordering, label separation, debug-safety, and negative fixtures.
  • Add comprehensive adapter integration tests for uselesskey-rustcrypto (sign/verify, conversions, debug-safety) and uselesskey-rustls (config conversion + TLS/mTLS handshakes + determinism).

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
crates/uselesskey/tests/prop_tests.rs New property-based tests for facade determinism and basic formatting/invariant checks.
crates/uselesskey/tests/facade_e2e.rs New end-to-end facade tests validating deterministic derivation and safety expectations.
crates/uselesskey/Cargo.toml Adds proptest as a dev-dependency for new property tests.
crates/uselesskey-rustls/tests/rustls_comprehensive.rs New rustls adapter integration tests including handshake scenarios and determinism checks.
crates/uselesskey-rustcrypto/tests/rustcrypto_comprehensive.rs New rustcrypto adapter integration tests for sign/verify, determinism, debug-safety, and cross-type usage.
Cargo.lock Locks proptest for the uselesskey crate’s new dev-dependency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +193 to +202
let bad_header = corrupt_pem(pem, CorruptPem::BadHeader);
let bad_footer = corrupt_pem(pem, CorruptPem::BadFooter);
let bad_base64 = corrupt_pem(pem, CorruptPem::BadBase64);

// Suppress unused variable warning
let _ = seed;

prop_assert_ne!(bad_header, pem);
prop_assert_ne!(bad_footer, pem);
prop_assert_ne!(bad_base64, pem);
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

This proptest case parameter (seed) is unused, so the test executes the exact same assertions for every generated input (wasted runtime and misleading “property” semantics). Either convert this to a regular #[test], or use seed to vary the corruption (e.g., choose variant/position) so each case explores different inputs.

Suggested change
let bad_header = corrupt_pem(pem, CorruptPem::BadHeader);
let bad_footer = corrupt_pem(pem, CorruptPem::BadFooter);
let bad_base64 = corrupt_pem(pem, CorruptPem::BadBase64);
// Suppress unused variable warning
let _ = seed;
prop_assert_ne!(bad_header, pem);
prop_assert_ne!(bad_footer, pem);
prop_assert_ne!(bad_base64, pem);
// Use the seed to choose which corruption variant to apply,
// so each proptest case can explore different inputs.
let choice = seed[0] % 3;
let variant = match choice {
0 => CorruptPem::BadHeader,
1 => CorruptPem::BadFooter,
_ => CorruptPem::BadBase64,
};
let corrupted = corrupt_pem(pem, variant);
prop_assert_ne!(corrupted, pem);

Copilot uses AI. Check for mistakes.
Comment on lines +280 to +282
let seed = Seed::from_env_value(original).expect("seed");
let fx = Factory::deterministic(seed);
assert!(matches!(fx.mode(), Mode::Deterministic { .. }));
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

seed_round_trip doesn’t actually test a round-trip (it only checks that a deterministic Factory reports Mode::Deterministic, which is already covered by deterministic_factory_mode). Either rename the test to reflect what it asserts, or extend it to validate a real seed property (e.g., that Seed::from_env_value is deterministic / stable for a given input).

Suggested change
let seed = Seed::from_env_value(original).expect("seed");
let fx = Factory::deterministic(seed);
assert!(matches!(fx.mode(), Mode::Deterministic { .. }));
// Seed must be stable/deterministic for a given env value
let seed1 = Seed::from_env_value(original).expect("seed1");
let seed2 = Seed::from_env_value(original).expect("seed2");
assert_eq!(seed1, seed2, "Seed::from_env_value must be deterministic");
// Factories constructed from the same seed must be deterministic mode
let fx1 = Factory::deterministic(seed1);
let fx2 = Factory::deterministic(seed2);
assert!(matches!(fx1.mode(), Mode::Deterministic { .. }));
assert!(matches!(fx2.mode(), Mode::Deterministic { .. }));

Copilot uses AI. Check for mistakes.
let signing = SigningKey::<Sha256>::new_unprefixed(private);
let verifying = VerifyingKey::<Sha256>::new_unprefixed(public);

for msg in [b"hello" as &[u8], b"", b"a".repeat(4096).as_slice()] {
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

for msg in [.., b"a".repeat(4096).as_slice()] takes a slice of a temporary Vec<u8>, which won’t compile (temporary dropped while borrowed). Bind the repeated buffer to a local variable (or use a Vec/array stored outside the loop) and iterate over stable references.

Suggested change
for msg in [b"hello" as &[u8], b"", b"a".repeat(4096).as_slice()] {
let long_msg_buf = b"a".repeat(4096);
let long_msg: &[u8] = &long_msg_buf;
for msg in [b"hello" as &[u8], b"", long_msg] {

Copilot uses AI. Check for mistakes.
let signing = kp.p256_signing_key();
let verifying = kp.p256_verifying_key();

for msg in [b"hello" as &[u8], b"", b"x".repeat(8192).as_slice()] {
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

This loop uses b"x".repeat(8192).as_slice() inside an array literal, which borrows from a temporary Vec<u8> and will fail to compile. Store the repeated message in a local variable first, then iterate over slices to it.

Suggested change
for msg in [b"hello" as &[u8], b"", b"x".repeat(8192).as_slice()] {
let long_msg = b"x".repeat(8192);
for msg in [b"hello" as &[u8], b"", long_msg.as_slice()] {

Copilot uses AI. Check for mistakes.
let signing = kp.ed25519_signing_key();
let verifying = kp.ed25519_verifying_key();

for msg in [b"hello" as &[u8], b"", b"y".repeat(10000).as_slice()] {
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

b"y".repeat(10000).as_slice() borrows from a temporary Vec<u8> created inside the array literal; this will not compile due to the temporary being dropped. Create the large message buffer in a variable (e.g., let big = vec![..];) and reference it in the loop.

Suggested change
for msg in [b"hello" as &[u8], b"", b"y".repeat(10000).as_slice()] {
let big = vec![b'y'; 10000];
for msg in [b"hello" as &[u8], b"", big.as_slice()] {

Copilot uses AI. Check for mistakes.
if !progress {
break;
}
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

try_handshake returns Ok(()) even if the handshake never completes (e.g., loop exits due to !progress or hitting the iteration cap). This can cause false positives/negatives in both success and failure tests. Consider returning an error (or panicking in the helper) if client.is_handshaking() or server.is_handshaking() is still true after the loop.

Suggested change
}
}
if client.is_handshaking() || server.is_handshaking() {
return Err(rustls::Error::General(
"try_handshake: TLS handshake did not complete".into(),
));
}

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +42
fn install_provider() {
INIT.call_once(|| {
let _ = rustls::crypto::ring::default_provider().install_default();
});
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

install_provider() installs a process-global rustls default provider and ignores the result. This is unnecessary here because the tests already build configs with an explicit CryptoProvider, and duplicating global installs across multiple test modules/binaries can create flaky races. Prefer removing the global install and relying solely on the explicit provider, or centralize provider installation in shared testutil so it happens exactly once per test binary.

Copilot uses AI. Check for mistakes.
Comment on lines +191 to +192
let pem = "-----BEGIN PRIVATE KEY-----\nMIIBVQIBADANBg==\n-----END PRIVATE KEY-----\n";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Pem blob in proptests 📘 Rule violation ⛨ Security

The new property tests commit a PEM-looking private key block string literal. This is a
secret-shaped blob in a test path and violates the fixture policy.
Agent Prompt
## Issue description
A PEM-looking private key string literal is committed in property tests, which violates the no-secret-shaped-blobs rule.

## Issue Context
These literals can trip secret scanners and are disallowed even if they are not real keys.

## Fix Focus Areas
- crates/uselesskey/tests/prop_tests.rs[189-203]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +98 to +103
let key = chain.private_key_der_rustls();
assert_eq!(
key.secret_der(),
chain.leaf_private_key_pkcs8_der(),
"private key DER must match source"
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. assert_eq! prints key der 📘 Rule violation ⛨ Security

The new rustls adapter tests compare private key DER bytes using assert_eq!, which will print key
material on failure. This can leak private keys into CI logs when a test fails.
Agent Prompt
## Issue description
Rustls adapter tests use `assert_eq!` to compare private key DER values. On failure, this prints private key bytes into logs.

## Issue Context
Assertion failures are visible in CI output, and the compliance policy forbids leaking key material via logs/errors.

## Fix Focus Areas
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[94-104]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[333-346]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[155-160]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[177-182]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[185-190]
- crates/uselesskey-rustls/tests/rustls_comprehensive.rs[199-204]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

EffortlessSteven and others added 4 commits March 1, 2026 16:18
rustcrypto (31 tests):
- RSA/ECDSA/Ed25519/HMAC sign-verify round trips
- Wrong message verification failures
- Deterministic key reproduction
- Different labels produce different keys
- RSA-4096 key conversion
- Cross-curve panic tests (p256/p384)
- HMAC SHA-256/384/512 compute and verify
- Tag length verification
- Debug safety (no key material leakage)
- Cross-adapter all-types from same factory
- Deterministic all-types stability

rustls (20 tests):
- Certificate/key DER conversion correctness
- Chain structure (leaf + intermediate)
- Root certificate matching
- RSA/ECDSA/Ed25519 private key conversion
- TLS handshake with chain
- mTLS handshake
- Wrong SNI fails handshake
- Cross-CA fails handshake
- Deterministic chain and self-signed reproduction
- Different seeds produce different chains
- Debug safety for chains and self-signed certs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
facade_e2e.rs (18 tests):
- Deterministic reproduction for RSA, ECDSA, Ed25519, HMAC, token
- Order-independent derivation (ABC vs CBA generation order)
- Different labels produce different keys
- Debug safety (no PEM markers leaked)
- Negative fixture CorruptPem variants
- PEM format well-formedness
- Factory mode verification
- Seed round-trip

prop_tests.rs (10 tests):
- Property-based determinism for RSA, ECDSA, Ed25519, HMAC, token
- PEM well-formedness under random seeds
- HMAC secret length matches spec
- Token prefix invariant
- Different seeds produce different ECDSA keys
- Corrupt PEM never returns original

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@EffortlessSteven EffortlessSteven merged commit f2d383e into main Mar 1, 2026
4 checks passed
@EffortlessSteven EffortlessSteven deleted the wave-14/adapter-tests branch March 5, 2026 15:20
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.

2 participants