Skip to content

feat: gzip-compress DAPI responses - #5577

Open
PastaPastaPasta wants to merge 2 commits into
v5.1-devfrom
feat/dapi-response-compression
Open

PastaPastaPasta wants to merge 2 commits into
v5.1-devfrom
feat/dapi-response-compression

Conversation

@PastaPastaPasta

@PastaPastaPasta PastaPastaPasta commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

DAPI sends every response uncompressed. rs-dapi's Drive client says compression is "handled by Envoy", but the gateway has no compressor filter, and neither rs-dapi nor rs-dapi-client enables tonic compression. Checked live against mainnet evonodes (DAPI 4.1.x): native gRPC responses carry no grpc-encoding even when the client sends grpc-accept-encoding: gzip, and grpc-web responses carry no Content-Encoding even when the client sends Accept-Encoding: gzip, br.

Replaces #5576.

What was done?

  • rs-dapi: Platform and Core responses are gzip-compressed for clients that list gzip in grpc-accept-encoding. Clients that don't list it get uncompressed responses as before. Compressed requests are still not accepted. The server setup moves into platform_server() / core_server(), so the test harness serves exactly the production configuration.
  • rs-dapi-client (native): Platform and Core clients accept gzip responses. This covers rs-sdk, and Swift/Kotlin through rs-sdk-ffi. Nodes that don't compress ignore the header, so new clients work against old nodes. gzip comes from flate2's pure-Rust backend, so iOS and Android builds gain no C dependency.
  • rs-dapi-client (wasm): unchanged on purpose. Browsers and Node's fetch negotiate HTTP Content-Encoding with the gateway and decompress on their own. Also, grpc-accept-encoding isn't in the gateway's CORS allow-list, so sending it from a browser would fail the preflight.
  • rs-dapi-client retries: when a gzip response decompresses past the client's max_decoding_message_size, tonic returns ResourceExhausted ("Error decompressing: size limit…") instead of the OutOfRange an uncompressed oversized response gets. ResourceExhausted is retryable and bans the node, so without this fix one oversized response would ban healthy nodes one after another, for a limit that lives in the client. That status is now not retryable, the same as OutOfRange.
  • Gateway (Envoy): a gzip compressor for grpc-web responses only (application/grpc-web*). It sits above grpc_web, so the trailer frame is compressed too. Native application/grpc responses are never HTTP-compressed; rs-dapi compresses those messages itself. It uses window_bits: 15 (zlib's 32 KiB window) instead of Envoy's 4 KiB default. On the mainnet sample, the default window would cut savings on responses over 64 KiB from 82.6% to 5.5%, and over all messages from 55.2% to 12.3%. The cost is about 144 KiB of zlib state per in-flight compressed response.
  • dapi-grpc: the native-only transport feature enables tonic/gzip.
  • The misleading "handled by Envoy" comment and log line in the Drive client are removed, and packages/rs-dapi/doc/DESIGN.md is corrected. The rs-dapi → Drive hop stays uncompressed because it's local.

js-dapi-client in Node (@grpc/grpc-js) already sends grpc-accept-encoding: identity,deflate,gzip, so it gets compressed responses without changes.

Measurements (real responses)

162 read-only responses collected from 3 mainnet evonodes on 2026-10-25 (protocol 13, height 458,086), plus 227 from testnet. Each message was compressed on its own, the way gRPC per-message compression works. Savings are by bytes, gzip level 6, which is what tonic uses.

Mainnet n raw gzip-6 savings
All proof / no-proof query responses 119 1.72 MB 65.4%
Same, excluding the 5 responses > 64 KB 114 0.55 MB 29.0%
getFinalizedEpochInfos 2 790 KB 85.5%
getCurrentQuorumsInfo 3 379 KB 76.2%
getDocuments (DPNS, DashPay) 7 206 KB 38.3%
getDataContract / getDataContracts 15 87 KB 53–70%
getEpochsInfo 2 42 KB 27.7%
Single-identity queries (identity, keys, balance, nonces) 71 150 KB 2.2% (−1.6% to +7.5% per method)
Block headers stream (500 headers / message) 12 492 KB 12.0%
Mainnet size bucket n gzip-6 savings
< 1 KB 7 −2.2%
1–4 KB 88 4.9%
4–16 KB 12 38.5%
16–64 KB 7 41.7%
> 64 KB 5 82.5%

Testnet (protocol 14): 47.8% overall, 43.1% excluding responses over 64 KB.

The savings come from embedded payloads: contract schemas, documents, epoch and quorum data. Small proofs that are mostly 32-byte Merk hashes don't compress. 37 of the 119 mainnet messages, almost all single-identity proofs of 1–4 KB, come out slightly larger, by at most 23 bytes. I did not add a size threshold. tonic has none built in, and the loss on those messages is tiny next to the gains on the large ones.

zstd-3 saves within 1–4 points of gzip-6 at about 4× less CPU. The cost is a C dependency, so it is left for later. Measured CPU for gzip-6 (single thread, Apple M4 Pro, zlib): median 24 µs to compress a message, 5 µs to decompress, about 117 MB/s compression throughput. That's small next to the cost of producing a proof.

The percentages depend on the query mix, not on production traffic. Mainnet nodes were on 4.1.x, so v5 response shapes may differ somewhat.

How Has This Been Tested?

  • New rs-dapi test should_gzip_responses_only_for_clients_that_accept_gzip. It serves the production platform_server() configuration over an in-memory connection and checks three things: a plain tonic client gets no grpc-encoding, a client built with rs_dapi_client::transport::new_platform_client gets grpc-encoding: gzip, and both decode to the same message.
  • New rs-dapi test should_not_ban_nodes_for_a_gzip_response_over_the_client_limit. A compressible response goes through the real server to a client with a 1 KiB decode limit, and the test asserts the status is not retryable. Without the retry fix it fails with exactly that ResourceExhausted status.
  • New dashmate unit test that pins the compressor between cors and grpc_web and restricts it to the grpc-web content types.
  • cargo test -p rs-dapi --lib protobuf_request_errors, cargo test -p rs-dapi --lib server:: and cargo test -p rs-dapi-client --all-features.
  • cargo clippy -p rs-dapi -p rs-dapi-client -p dapi-grpc --all-features --all-targets --no-deps -- -D warnings.
  • cargo check --target wasm32-unknown-unknown for rs-dapi-client and wasm-sdk. flate2 is not in the wasm dependency tree.
  • packages/dashmate/scripts/validate-envoy-config.js --smoke: all 8 config variants and the rate-limit smoke checks pass on both envoyproxy/envoy:v1.39.0 and the pinned dashpay/envoy:1.39.0-impr.1.
  • Ran the rendered gateway config in the pinned Envoy image in front of a stub gRPC upstream serving a real 4.3 KB contract proof:
    • grpc-web + Accept-Encoding: gzip: content-encoding: gzip, 4,396 → 2,083 bytes on the wire, message and trailer frame intact after decompression.
    • grpc-web without Accept-Encoding: unchanged response.
    • grpc-web-text + Accept-Encoding: gzip: compressed.
    • Native gRPC with message-level gzip: passes through Envoy unchanged (grpc-encoding: gzip, 4,361 → 2,035 bytes, decompresses to the exact payload). Envoy does not HTTP-compress application/grpc.

Breaking Changes

None. Compression only happens when the client asks for it, so old clients see no change, and new clients work against old nodes.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

PR Hygiene · b7d36f1

  • Bots — coderabbitai ✓ · thepastaclaw not yet — /skip-bots proceeds without the ones not yet reported
  • Self-review — post /self-reviewed
  • Reviewer requests paused — your 5 review slots are occupied; this PR is excluded from reviewers' queues. Required approvals still count without a slot.
  • Build failed
  • Approvals
    • files with no dedicated owner (Cargo.lock, packages/dapi-grpc/Cargo.toml, packages/rs-dapi-client/src/transport.rs and 3 more) — QuantumExplorer or shumkov
    • dashmate (packages/dashmate/templates/platform/gateway/envoy.yaml.dot, packages/dashmate/test/unit/templates/envoyTemplate.spec.js) — ktechmidas or shumkov
    • rust-dapi (packages/rs-dapi/doc/DESIGN.md, packages/rs-dapi/src/clients/drive_client.rs, packages/rs-dapi/src/server/grpc.rs and 2 more) — QuantumExplorer or lklimek or shumkov

When every merge requirement is met, the PR Hygiene check passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.

Summary by CodeRabbit

  • New Features
    • Native gRPC responses can now be gzip-compressed when clients support it. gRPC-Web responses are compressed when requested.
  • Bug Fixes
    • Responses that exceed the client’s decompressed message-size limit are no longer retried. Other resource-exhaustion errors retain their existing retry behavior.
  • Documentation
    • Clarified compression behavior across native gRPC, gRPC-Web, and JSON-RPC connections, including that JSON-RPC responses are not compressed.

DAPI sent every response uncompressed: rs-dapi claimed Envoy handled
compression, but the gateway had no compressor filter.

- rs-dapi gzip-compresses Platform and Core responses for clients that
  list gzip in grpc-accept-encoding; other clients are unaffected.
- Native rs-dapi-client clients accept gzip responses (pure-Rust flate2,
  no new C dependency). The wasm client is unchanged: browsers negotiate
  HTTP Content-Encoding with the gateway themselves.
- The gateway gzips grpc-web responses (32 KiB window) for clients that
  send Accept-Encoding; native gRPC is never HTTP-compressed.
- A gzip response that decompresses past the client's decode limit is
  not retried, like an uncompressed oversized response, so it no longer
  bans healthy nodes.

On a mainnet sample, gzip saves 65% of response bytes overall (29%
without responses over 64 KiB); single-identity proofs barely change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 70a4e7a and b7d36f1.

Files selected for processing: 2
  • packages/dashmate/test/unit/templates/envoyTemplate.spec.js
  • packages/rs-dapi-client/src/transport/grpc.rs
Files skipped from review as they are similar to previous changes: 1
  • packages/rs-dapi-client/src/transport/grpc.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

DAPI gRPC services now configure gzip response compression and message-size limits. Native clients accept gzip responses, and decompression-limit errors are excluded from retries. The changes also document protocol-specific compression and test the Envoy gRPC-Web compressor configuration.

Changes: Negotiated gRPC compression

Layer / File(s) Summary
DAPI server gzip responses
packages/rs-dapi/src/server/grpc.rs, packages/rs-dapi/src/server/mod.rs, packages/rs-dapi/src/services/platform_service/protobuf_request_errors.rs
Platform and Core server constructors set request decoding limits, a shared response encoding limit, and gzip response compression. The unified server uses these constructors. Platform service tests check gzip negotiation and verify that a response exceeding the client’s decompressed message limit returns a non-retryable status.
Client gzip support and retry handling
packages/dapi-grpc/Cargo.toml, packages/rs-dapi-client/src/transport.rs, packages/rs-dapi-client/src/transport/*
The transport feature enables tonic/gzip. Native client constructors accept gzip responses, and pooled client creation uses the new constructors. Decompression-limit ResourceExhausted errors are not retried. Wasm client constructors and transport re-exports are added.
Protocol-specific compression details
packages/rs-dapi/doc/DESIGN.md, packages/rs-dapi/src/clients/drive_client.rs, packages/dashmate/test/unit/templates/envoyTemplate.spec.js
The design text distinguishes compression for native gRPC, gRPC-Web, JSON-RPC, and the local Drive hop. The Envoy test checks that the compressor follows CORS, precedes grpc_web, and lists four configured content types.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Possibly related issues

Suggested reviewers: lklimek, quantumexplorer, thepastaclaw, shumkov

Merge Risk: Minimal · up to b7d36

The compression changes are ready to merge with no identified correctness, availability, security, or data-integrity risk.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 52.38% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 9 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed 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 and concisely describes the primary change: adding gzip compression for DAPI responses when clients support it.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai ✓ · thepastaclaw not yet. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Oct 25, 2026
@PastaPastaPasta

Copy link
Copy Markdown
Member Author

@coderabbitai review


🤖 Posted autonomously by Claude on behalf of pasta.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw

thepastaclaw commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

🔍 Review in progress — actively reviewing now (commit b7d36f1) · triage: normal
██████████████████░░ 91% · about 5 min left · running for 39 min
✅ triage → ✅ Phase 1 → ✅ verify 1 → ✅ gate → ✅ Phase 2 → ✅ verify 2 → ✅ fresh Phase 2 → ⏳ fresh verify → ▫️ publish
Estimated from recent reviews of this tier · updated 02:05 UTC · live progress

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Final validation — Phase 1 + Phase 2

The gzip implementation is correctly scoped across native gRPC, grpc-web, and WASM transports, with no blocking correctness, security, or layering defects found. Three non-blocking test and maintainability improvements remain: Core response compression lacks direct coverage, the retry guard depends on tonic's error wording, and the Envoy test can throw a TypeError instead of reporting an assertion failure. The Rust workspace test failure is unrelated to this PR; one browser test check was still in progress in the supplied CI snapshot.

🟡 2 suggestion(s) | 💬 1 nitpick(s)

Review provenance

Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: normal by gpt-6.1-sol (effort low) — This is a broad cross-cutting change to gRPC transport, server compression, gateway configuration, client retry handling, and protocol error mapping, but it does not alter consensus, funds, cryptography, key handling, or storage.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity quota lookup failed), glm-5.3-flash (not used above high effort; tier asks max)
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort high); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort high); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort high); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort high); agent phase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-dapi/src/server/grpc.rs`:
- [SUGGESTION] packages/rs-dapi/src/server/grpc.rs:55-62: Core response compression lacks direct test coverage
  `core_server()` now enables gzip response compression, but the added integration coverage exercises only `platform_server()`. Because `core_server()` is a separate constructor, a future edit could remove or misconfigure its `send_compressed(CompressionEncoding::Gzip)` call without any test detecting the regression. Add a Core-service compression test, or expose the constructor under `cfg(test)` and cover it with a small Core harness.

In `packages/rs-dapi-client/src/transport/grpc.rs`:
- [SUGGESTION] packages/rs-dapi-client/src/transport/grpc.rs:133-137: Document the tonic-version dependency of the decompression-limit prefix
  `can_retry()` identifies the client-local decompression limit by prefix-matching tonic's English status message. That wording is an implementation detail rather than a stable status discriminator. The existing test will catch a wording change when it runs, but the constant should explicitly identify the tonic decoder source and version so a future tonic upgrade prompts a deliberate review instead of silently changing retry classification if the test is skipped or weakened.

In `packages/dashmate/test/unit/templates/envoyTemplate.spec.js`:
- [NITPICK] packages/dashmate/test/unit/templates/envoyTemplate.spec.js:46-49: Avoid a TypeError when the Envoy compressor block has no content types
  If the rendered compressor block contains no matching content-type lines, `match()` returns `null` and the test throws a TypeError before reaching an assertion. This produces a misleading failure and obscures the actual template regression. Normalize the match result to an empty array before mapping it.
Out-of-scope follow-up suggestions (1)

These are valid observations, but they are outside this PR's scope and should be handled in separate issues or author/maintainer-requested PRs rather than blocking this review.

  • Rust workspace test failure is pre-existing and unrelated — The supplied CI snapshot shows Rust workspace tests / Tests failing in the untouched packages/rs-sdk/src/platform/identities_contract_keys_query.rs because QuerySettings initializers omit verified_protocol_version. The changed files do not include this module, and the failure is unrelated to the gzip transport changes.
    • Follow-up: Track or fix the rs-sdk QuerySettings initializer issue separately on the appropriate development branch.

Comment on lines +55 to +62
/// Core service with the message limits and response compression DAPI serves it with.
/// See [platform_server].
fn core_server(service: CoreServiceImpl) -> CoreServer<CoreServiceImpl> {
CoreServer::new(service)
.max_decoding_message_size(MAX_CORE_DECODING_BYTES)
.max_encoding_message_size(MAX_ENCODING_BYTES)
.send_compressed(CompressionEncoding::Gzip)
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Suggestion: Core response compression lacks direct test coverage

core_server() now enables gzip response compression, but the added integration coverage exercises only platform_server(). Because core_server() is a separate constructor, a future edit could remove or misconfigure its send_compressed(CompressionEncoding::Gzip) call without any test detecting the regression. Add a Core-service compression test, or expose the constructor under cfg(test) and cover it with a small Core harness.

source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not adding this one here. A Core harness that gets a successful (and therefore compressible) response needs a real StreamingServiceImpl and a Core RPC backend: every Core unary method goes to Core RPC, and errors carry no body to compress. core_server() is the same three builder calls as platform_server(), and gzip negotiation itself is tonic behaviour that the Platform test already exercises end to end. Happy to add it if someone wants a Core service test fixture for other reasons.


🤖 Posted autonomously by Claude on behalf of pasta.

Comment on lines +133 to +137
/// Start of the status tonic returns when a compressed response decompresses past the
/// client's `max_decoding_message_size`. The limit is the client's own, so every node
/// would fail the same way: this must not ban nodes like other `ResourceExhausted`
/// statuses (an uncompressed oversized response is `OutOfRange`, also not retried).
const DECOMPRESS_LIMIT_ERROR: &str = "Error decompressing: size limit";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Suggestion: Document the tonic-version dependency of the decompression-limit prefix

can_retry() identifies the client-local decompression limit by prefix-matching tonic's English status message. That wording is an implementation detail rather than a stable status discriminator. The existing test will catch a wording change when it runs, but the constant should explicitly identify the tonic decoder source and version so a future tonic upgrade prompts a deliberate review instead of silently changing retry classification if the test is skipped or weakened.

Suggested change
/// Start of the status tonic returns when a compressed response decompresses past the
/// client's `max_decoding_message_size`. The limit is the client's own, so every node
/// would fail the same way: this must not ban nodes like other `ResourceExhausted`
/// statuses (an uncompressed oversized response is `OutOfRange`, also not retried).
const DECOMPRESS_LIMIT_ERROR: &str = "Error decompressing: size limit";
/// Prefix emitted by tonic 0.14's decoder when the client's own
/// `max_decoding_message_size` is exceeded while decompressing a response.
/// Re-check this prefix against tonic's decoder implementation on every tonic
/// upgrade; this failure is client-local and must not cause healthy nodes to be
/// retried or banned.
const DECOMPRESS_LIMIT_ERROR: &str = "Error decompressing: size limit";

source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done in b7d36f1: the doc now names tonic 0.14's codec::decode as the source and says to re-check it on tonic upgrades. should_not_ban_nodes_for_a_gzip_response_over_the_client_limit also fails if the wording changes (verified by removing the guard).


🤖 Posted autonomously by Claude on behalf of pasta.

Comment on lines +46 to +49
const contentTypes = envoyConfig
.slice(compressor, grpcWeb)
.match(/^\s+- application\/[\w+-]+$/gm)
.map((line) => line.trim().slice(2));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

💬 Nitpick: Avoid a TypeError when the Envoy compressor block has no content types

If the rendered compressor block contains no matching content-type lines, match() returns null and the test throws a TypeError before reaching an assertion. This produces a misleading failure and obscures the actual template regression. Normalize the match result to an empty array before mapping it.

Suggested change
const contentTypes = envoyConfig
.slice(compressor, grpcWeb)
.match(/^\s+- application\/[\w+-]+$/gm)
.map((line) => line.trim().slice(2));
const contentTypes = (envoyConfig
.slice(compressor, grpcWeb)
.match(/^\s+- application\/[\w+-]+$/gm) ?? [])
.map((line) => line.trim().slice(2));

source: muse-spark-1.3-contributor (phase1-reviewer: general, rust-quality)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done in b7d36f1 (?? []).


🤖 Posted autonomously by Claude on behalf of pasta.

@github-actions

Copy link
Copy Markdown
Contributor

Bots are done — your move: post /self-reviewed.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Oct 25, 2026
…st match

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai ✓ · thepastaclaw not yet. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed labels Oct 25, 2026
@PastaPastaPasta

Copy link
Copy Markdown
Member Author

@coderabbitai review


🤖 Posted autonomously by Claude on behalf of pasta.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@PastaPastaPasta

Copy link
Copy Markdown
Member Author

@coderabbitai review


🤖 Posted autonomously by Claude on behalf of pasta.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

waiting-bots Waiting for the review bots to report on this head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants