Skip to content

fix(tlsnotary): bake wstcp into the image + publish the proxy port range#949

Open
Shitikyan wants to merge 9 commits into
stabilisationfrom
fix/tlsn-wstcp-proxy-reachability
Open

fix(tlsnotary): bake wstcp into the image + publish the proxy port range#949
Shitikyan wants to merge 9 commits into
stabilisationfrom
fix/tlsn-wstcp-proxy-reachability

Conversation

@Shitikyan

@Shitikyan Shitikyan commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Problem

TLSNotary verifications (e.g. Discord) fail with nginx 502 / CloseEvent {code: 1006} on the prover. The notary itself is healthy (/tlsnotary/health → 200, port 7047) — "connected to verifier" succeeds — but the next hop, wss://<node>/tlsn/<port>/, 502s.

Root cause is two layers, both confirmed live on node3:

  1. wstcp can't spawn. The TLSNotary flow spawns a wstcp websocket→TCP proxy on demand (proxyManager.ts). The slim runtime image has no Rust toolchain, so ensureWstcp()'s cargo install wstcp fallback fails silently — nothing ever binds the proxy port. Confirmed: docker exec demos-node → no wstcp, no cargo.

  2. The proxy port isn't reachable from the host. Even with wstcp, the proxy binds a dynamic port in 55000-57000 inside the container, but docker-compose.yml publishes none of that range. nginx forwards /tlsn/<port>/127.0.0.1:<port> → dead upstream → 502. Manually binding a single port (55688) is a band-aid that breaks on the next session's different port — which is why this kept recurring.

Fix

  1. Dockerfile — bake wstcp into the image via a dedicated FROM rust:1-slim AS wstcp stage and copy the binary to the exact path proxyManager.ts probes ($HOME/.cargo/bin/wstcp, HOME=/app). No toolchain in the runtime image; the proxy spawns instantly. (Validated: the stage builds, wstcp 0.2.1 runs.)
  2. constants.tsPORT_MIN/PORT_MAX are now overridable via TLSNOTARY_PROXY_PORT_MIN/MAX (defaults unchanged) so the allocation range can be narrowed to a host-publishable window.
  3. docker-compose.yml — publish a narrow, localhost-bound proxy window (127.0.0.1:55000-55063, env-driven). The allocation range and the published range read the same vars so they can't drift, and binding to 127.0.0.1 keeps the ports reachable by the host reverse proxy only, not the public internet.

Deploy on node3

  • Rebuild the node image (now contains wstcp) and recreate the demos-node container so the new ports: mapping applies. (Immediate unblock without a rebuild: docker cp a prebuilt wstcp into /app/.cargo/bin/wstcp and add the port-range mapping.)
  • If node3 uses a custom compose, mirror the TLSNOTARY_PROXY_PORT_MIN/MAX env + the 127.0.0.1:<min>-<max> port mapping there.

Refs: docs/runbooks/wstcp-reachability-check.md (this makes the containerized default actually reachable instead of "internal only").

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added environment-driven TLSNotary wstcp proxy port range configuration (with defaults) to support dynamic verification traffic.
    • Updated container/compose setup to publish the configured port range on loopback only, matching the local reverse proxy.
    • Enhanced Caddy routing for subpath deployments to forward /tlsn/<port>/... to the corresponding per-port proxy.
  • Refactor
    • Centralized the proxy port window configuration so allocation and proxy management share the same settings.
  • Documentation
    • Added a runbook for TLSNotary reverse-proxy routing, including WebSocket upgrade requirements and verification steps.
  • Chores / Infrastructure
    • Updated the runtime image to include the required wstcp helper via a multistage build.

TLSNotary verifications failed with nginx 502 / CloseEvent 1006 because
the wstcp websocket→TCP proxy could never be reached, on two layers:

1. The runtime image ships no Rust toolchain, so ensureWstcp()'s
   on-demand `cargo install wstcp` fallback silently failed and the proxy
   never spawned. Bake the binary in via a dedicated `rust` build stage
   and copy it to the exact path proxyManager.ts probes
   ($HOME/.cargo/bin/wstcp).

2. The proxy binds a dynamic port in 55000-57000 inside the container,
   but docker-compose published none of them — so nginx forwarding
   /tlsn/<port>/ to 127.0.0.1:<port> hit a dead upstream. Publish a
   narrow, localhost-bound, env-configurable window; the allocation range
   (PORT_MIN/MAX, now env-overridable) and the published range read the
   same vars so they cannot drift.

Manually binding one host port was a band-aid that broke on the next
session's different port. This fixes both layers durably.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Shitikyan, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 14 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8ac074ef-cf84-447a-8a85-f55721677faa

📥 Commits

Reviewing files that changed from the base of the PR and between c6611b7 and fcc246f.

📒 Files selected for processing (4)
  • docker-compose.devnet.yml
  • docker-compose.yml
  • docs/runbooks/tlsn-reverse-proxy.md
  • monitoring/caddy/tlsnotary-modes/subpath.caddy

Walkthrough

The Docker image now includes wstcp, TLSNotary proxy ports are configurable through environment variables, devnet publishes the matching range, and Caddy routes /tlsn/... traffic to either tlsnotary or the node proxy ports.

Changes

TLSNotary wstcp runtime and port wiring

Layer / File(s) Summary
Proxy port contract
src/features/tlsnotary/constants.ts, src/features/tlsnotary/portAllocator.ts, src/features/tlsnotary/proxyManager.ts, docker-compose.yml
PORT_CONFIG reads TLSNotary proxy bounds from environment variables, the TLSNotary modules import that shared config, and the node service sets matching defaults while publishing that port range on localhost.
Bake wstcp into the runtime image
Dockerfile
A Rust build stage installs wstcp, and the runtime stage copies the binary into /app/.cargo/bin/wstcp.
Expose devnet proxy ports
docker-compose.devnet.yml
The devnet compose override sets the TLSNotary proxy port window and publishes that range on 127.0.0.1.
Route TLSNotary subpaths
monitoring/caddy/tlsnotary-modes/subpath.caddy, docs/runbooks/tlsn-reverse-proxy.md
Caddy now routes /tlsnotary/* and /tlsn/<port>/* to tlsnotary, and forwards /tlsn/<digits>/... to the matching node port after stripping the prefix. The runbook documents the /tlsn/<port>/ WebSocket routing setup, header requirement, and verification command.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • kynesyslabs/node#554: Updates the TLSNotary port allocation wiring by moving PORT_CONFIG to constants.ts and making the port range env-driven, which overlaps the shared port configuration changes here.

Suggested labels

Review effort 4/5

Poem

🐇 I hopped through ports both wide and small,
with wstcp snugly in the wall.
From tlsn paths to localhost light,
the proxy purrs and runs just right.
🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main TLSNotary fix: baking wstcp into the image and publishing the proxy port range.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tlsn-wstcp-proxy-reachability

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.

@greptile-apps

greptile-apps Bot commented Jun 26, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes two root-cause issues that caused TLSNotary verifications to 502: the wstcp binary is now baked into the image via a dedicated Rust build stage (instead of relying on a cargo install fallback that can't run in the slim runtime), and the dynamic proxy port range is published on loopback and made env-overridable so the allocation window and the host-published range always match.

  • Dockerfile: adds a FROM rust:1-slim AS wstcp stage that builds wstcp 0.2.1 and copies the binary to /app/.cargo/bin/wstcp, the exact path ensureWstcp() probes at startup.
  • constants.ts / portAllocator.ts: PORT_MIN/PORT_MAX are now read from TLSNOTARY_PROXY_PORT_MIN/MAX env vars (falling back to the historical 55000-57000 defaults), and portAllocator.ts now imports from constants.ts instead of keeping a local hardcoded copy.
  • docker-compose.yml / devnet: publishes a narrow loopback port range (55000-55063 mainnet, 55100-55163 devnet) using the same env vars as the allocator, and passes TLSNOTARY_PORT to the Caddy service so the /tlsn/<notary-port>/ Caddyfile route resolves correctly on remapped stacks.

Confidence Score: 5/5

Safe to merge — the three-layer fix (binary baked in, env-driven port window, loopback port publishing) directly addresses the confirmed 502 root cause with no changes to existing behavior when defaults are unchanged.

All changed paths are infrastructure/config: the Dockerfile multistage addition is contained and the binary lands at the exact path already probed by proxyManager.ts. The env-driven port range change is backward-compatible (defaults preserve historical behavior). The Caddy routing additions are additive and guarded by a port-range regexp that prevents proxying arbitrary node ports.

No files require special attention. The two stale range references in portAllocator.ts and proxyManager.ts are cosmetic only.

Important Files Changed

Filename Overview
Dockerfile Adds a dedicated FROM rust:1-slim AS wstcp build stage and copies the resulting binary to /app/.cargo/bin/wstcp; cleanly fixes the missing-binary root cause with no toolchain in the runtime image.
docker-compose.yml Adds env-driven TLSNOTARY_PROXY_PORT_MIN/MAX to the node service and publishes the matching loopback port range; also passes TLSNOTARY_PORT to the Caddy service so the notary-port Caddyfile route resolves correctly.
docker-compose.devnet.yml Adds devnet-specific proxy port window (55100-55163) offset from mainnet, loopback-bound port mapping, and TLSNOTARY_PORT=7147 to the Caddy service to match the remapped notary port.
src/features/tlsnotary/constants.ts Makes PORT_MIN/MAX env-overridable via TLSNOTARY_PROXY_PORT_MIN/MAX; uses `Number(env)
src/features/tlsnotary/portAllocator.ts Removes local hardcoded PORT_CONFIG duplicate and imports from constants.ts — correct. However, the module docblock and PortPoolState interface comments still reference the old fixed range (55000-57000).
src/features/tlsnotary/proxyManager.ts Import of PORT_CONFIG moved to constants.ts correctly. One stale hardcoded range string ("55000-57000") remains in the PORT_EXHAUSTED error message at line 529.
monitoring/caddy/tlsnotary-modes/subpath.caddy Adds handle_path /tlsn/{$TLSNOTARY_PORT}/* for the notary leg and a path_regexp block routing /tlsn/<port>/ to the dynamic wstcp proxies; regex bounds (55000-57999) cover the default allocation window.
docs/runbooks/tlsn-reverse-proxy.md New runbook documenting WebSocket routing requirements, nginx config for hand-maintained nodes, and the Connection: Upgrade case-sensitivity gotcha with wstcp 0.2.1.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant Caddy
    participant Node
    participant wstcp
    participant TLSTarget

    Browser->>Caddy: GET wss://node/tlsn/7047/ (notary)
    Caddy-->>Browser: WebSocket upgrade → tlsnotary:7047

    Browser->>Node: "POST /api/tlsnotary/proxy {targetUrl}"
    Node->>wstcp: spawn /app/.cargo/bin/wstcp --bind-addr 0.0.0.0:55123 target:443
    wstcp-->>Node: INFO Starts a WebSocket proxy (port 55123)
    Node-->>Browser: "{websocketProxyUrl: wss://node/tlsn/55123/}"

    Browser->>Caddy: GET wss://node/tlsn/55123/ (proxy)
    Caddy->>wstcp: reverse_proxy node:55123 (WebSocket upgrade)
    wstcp->>TLSTarget: TCP relay :443
    TLSTarget-->>wstcp: TLS data
    wstcp-->>Browser: WebSocket frames
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser
    participant Caddy
    participant Node
    participant wstcp
    participant TLSTarget

    Browser->>Caddy: GET wss://node/tlsn/7047/ (notary)
    Caddy-->>Browser: WebSocket upgrade → tlsnotary:7047

    Browser->>Node: "POST /api/tlsnotary/proxy {targetUrl}"
    Node->>wstcp: spawn /app/.cargo/bin/wstcp --bind-addr 0.0.0.0:55123 target:443
    wstcp-->>Node: INFO Starts a WebSocket proxy (port 55123)
    Node-->>Browser: "{websocketProxyUrl: wss://node/tlsn/55123/}"

    Browser->>Caddy: GET wss://node/tlsn/55123/ (proxy)
    Caddy->>wstcp: reverse_proxy node:55123 (WebSocket upgrade)
    wstcp->>TLSTarget: TCP relay :443
    TLSTarget-->>wstcp: TLS data
    wstcp-->>Browser: WebSocket frames
Loading

Reviews (8): Last reviewed commit: "fix(tlsnotary): pass TLSNOTARY_PORT to t..." | Re-trigger Greptile

Comment thread src/features/tlsnotary/constants.ts

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
Dockerfile (1)

150-151: 📐 Maintainability & Code Quality | 🔵 Trivial

Pin the wstcp version for reproducible builds.

cargo install wstcp fetches the latest release (currently 0.2.1) at build time, making builds non-reproducible. The wstcp crate is available on crates.io with versions ranging from 0.1.0 to 0.2.1. To prevent unexpected behavior changes or build failures from upstream updates, pin the specific version and use --locked.

♻️ Suggested update
 FROM rust:1-slim AS wstcp
-RUN cargo install wstcp --root /wstcp
+RUN cargo install wstcp --version 0.2.1 --locked --root /wstcp
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Dockerfile` around lines 150 - 151, The wstcp install step is unpinned and
can pull a changing latest release, so update the Dockerfile’s wstcp build stage
to install a specific crates.io version of wstcp and use --locked for
reproducible builds. Keep the change focused on the FROM rust:1-slim AS wstcp
stage and the cargo install wstcp command so the image always builds against the
same crate release.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/features/tlsnotary/constants.ts`:
- Around line 60-61: `PORT_CONFIG` is duplicated and the allocator is still
using the hardcoded range instead of the env-driven values. Update
`portAllocator.ts` to remove its local `PORT_CONFIG` and import the shared one
from `./constants`, then make `proxyManager.ts` also use `PORT_CONFIG` from
`./constants` so there is a single source of truth for the TLSNotary port range.

---

Nitpick comments:
In `@Dockerfile`:
- Around line 150-151: The wstcp install step is unpinned and can pull a
changing latest release, so update the Dockerfile’s wstcp build stage to install
a specific crates.io version of wstcp and use --locked for reproducible builds.
Keep the change focused on the FROM rust:1-slim AS wstcp stage and the cargo
install wstcp command so the image always builds against the same crate release.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 93605c23-fd3e-4cf7-ac95-581870d043e0

📥 Commits

Reviewing files that changed from the base of the PR and between 01ef0a0 and f6c3acc.

📒 Files selected for processing (3)
  • Dockerfile
  • docker-compose.yml
  • src/features/tlsnotary/constants.ts

Comment thread src/features/tlsnotary/constants.ts
Shitikyan and others added 5 commits June 26, 2026 15:09
…ocation

portAllocator.ts kept its own hardcoded PORT_CONFIG (55000-57000) and
proxyManager imported PORT_CONFIG from it, so the env-overridable values in
constants.ts were never used for allocation: the allocator would walk past
the published window (e.g. 55064) and hand nginx an unreachable port,
re-creating the 502 after the first 64 allocations. Point both consumers at
constants.ts (the env-driven copy) and drop the duplicate.

Addresses CodeRabbit/Greptile review on #949.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`cargo install wstcp` pulled the latest release at build time. Pin 0.2.1
and pass --locked so the image always builds the same wstcp and an
upstream release can't change behaviour or break the build.

Addresses CodeRabbit review on #949.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`--locked` forces wstcp 0.2.1's bundled Cargo.lock, whose pinned deps no
longer compile on the current rust:1-slim toolchain (cargo exit 101).
Keep the version pin for reproducibility but let cargo resolve compatible
dependency versions. Validated: the stage builds and yields wstcp 0.2.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The devnet override replaces the node `ports:` list (`!override`), which
dropped the proxy-range publish from the base compose — so devnet
verifications would still 502. Add a devnet-specific window (55100-55163,
+100 offset from mainnet so the two stacks don't collide on host ports),
with the allocation env and the published range driven by the same values.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The node advertises every TLSN endpoint under /tlsn/<port>/ (buildWsUrl's
default path) — the notary at /tlsn/<TLSNOTARY_PORT>/ and each per-target
wstcp proxy at /tlsn/<dynamic-port>/. The subpath Caddy config only routed
/tlsnotary/* to the notary, so every proxy (and the notary on remapped
hosts) fell through to the RPC catch-all and 502'd — the browser's attest()
websocket then closed with CloseEvent 1006. This is why TLSN verification
failed on every node, not just dev; node3 only worked because of a manual
nginx rule that was never in the repo and is lost on redeploy.

- honour $TLSNOTARY_PORT (dev remaps it to 7147; the hard-coded 7047 made
  the notary leg 502 on remapped hosts)
- add /tlsn/<notary-port>/ -> tlsnotary container
- add a regex route /tlsn/<digits>/ -> node:<port> for the wstcp proxies
  (wstcp binds 0.0.0.0, reachable by service name on the compose network)

Validated with `caddy validate`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker-compose.devnet.yml`:
- Around line 57-63: The wstcp proxies are still binding to all interfaces
because proxyManager defaults WSTCP_BIND_HOST to 0.0.0.0, so update the node
service environment to set WSTCP_BIND_HOST to 127.0.0.1 as well. Keep the
existing TLSNOTARY_PROXY_PORT_MIN and TLSNOTARY_PROXY_PORT_MAX settings, and
make sure the change aligns with the spawn logic in proxyManager so only the
reverse proxy can reach the worker ports.

In `@monitoring/caddy/tlsnotary-modes/subpath.caddy`:
- Around line 27-30: The `@tlsnproxy` route in subpath.caddy currently forwards
any numeric /tlsn/<port>/ request directly to reverse_proxy
node:{re.tlsnport.1}, which can expose arbitrary listeners. Tighten the matching
logic in the tlsnport path_regexp/handle block so only ports within the
allocated TLSNOTARY_PROXY_PORT_MIN..MAX range are accepted, and reject or bypass
all other ports before reverse_proxy is reached. Use the existing `@tlsnproxy`,
tlsnport capture, and reverse_proxy directives as the place to enforce this
validation.
- Around line 18-21: The Caddy service is missing the TLSNOTARY_PORT environment
variable, so the placeholder in subpath.caddy never resolves to the devnet port.
Update the caddy service definition in both compose files to pass TLSNOTARY_PORT
through to Caddy, and make sure it matches the tlsnotary upstream port used by
the handle_path /tlsn/{$TLSNOTARY_PORT:7047} matcher so the remap works as
intended.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6f788a92-d8c8-45c0-acd4-5b205db4202b

📥 Commits

Reviewing files that changed from the base of the PR and between b56b20c and 7471b5b.

📒 Files selected for processing (3)
  • Dockerfile
  • docker-compose.devnet.yml
  • monitoring/caddy/tlsnotary-modes/subpath.caddy
🚧 Files skipped from review as they are similar to previous changes (1)
  • Dockerfile

Comment thread docker-compose.devnet.yml
Comment thread monitoring/caddy/tlsnotary-modes/subpath.caddy
Comment thread monitoring/caddy/tlsnotary-modes/subpath.caddy Outdated
…pital Connection: Upgrade gotcha

wstcp 0.2.1 checks the Connection header case-sensitively (requires
'Upgrade', capital U). The common nginx 'Connection "upgrade"' (lowercase)
makes wstcp reject every handshake -> /tlsn/ 502s -> browser CloseEvent 1006.
Document the exact Caddy (repo, automatic) and nginx (hand-maintained) routing
so any node can be brought up correctly, plus the wstcp/port prerequisites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/runbooks/tlsn-reverse-proxy.md (1)

25-25: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add text language specifier to the error output block.

-```
+```text
 Invalid WebSocket handshake request: assertion failed: `values.any(|v| v.trim() == "Upgrade")`; value="upgrade"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/runbooks/tlsn-reverse-proxy.md` at line 25, Add the text language
specifier to the fenced error output block in the TLSN reverse proxy runbook so
the literal handshake error is rendered correctly; update the markdown snippet
containing the “Invalid WebSocket handshake request” message to use the
appropriate fenced block syntax.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/runbooks/tlsn-reverse-proxy.md`:
- Around line 74-78: Remove the stray closing Markdown fence in the tlsn reverse
proxy runbook so the section renders correctly. Update the runbook content
around the HTTPS RPC note and the `101`/`502` explanation to ensure there is no
unmatched code fence; keep the surrounding prose intact and verify the markdown
block boundaries are balanced in this document.

---

Nitpick comments:
In `@docs/runbooks/tlsn-reverse-proxy.md`:
- Line 25: Add the text language specifier to the fenced error output block in
the TLSN reverse proxy runbook so the literal handshake error is rendered
correctly; update the markdown snippet containing the “Invalid WebSocket
handshake request” message to use the appropriate fenced block syntax.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7f687a3-a279-4eda-9b15-3d2626c669a7

📥 Commits

Reviewing files that changed from the base of the PR and between 7471b5b and c6611b7.

📒 Files selected for processing (1)
  • docs/runbooks/tlsn-reverse-proxy.md

Comment thread docs/runbooks/tlsn-reverse-proxy.md
Address review: the /tlsn/(\d+)/ regex forwarded any digits to node:<port>,
which could expose internal listeners (RPC 53550, MCP 3001, metrics 9090)
under a public /tlsn/ path. Narrow to 5[567]\d{3} — the wstcp allocation
window — in both the Caddy route and the runbook's nginx snippet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown

T-Rex pricing update — T-Rex was free through June 2026. Effective July 1, 2026, T-Rex adds 2 credits on top of the standard 1-credit review (3 total). T-Rex settings

Comment thread monitoring/caddy/tlsnotary-modes/subpath.caddy
…fence

The subpath snippet routes the notary leg via {$TLSNOTARY_PORT}, but Caddy reads
that from its own container env, which was never set — so on port-remapped stacks
(devnet notary = 7147) Caddy fell back to /tlsn/7047/ → tlsnotary:7047 where
nothing listens → 502. Set TLSNOTARY_PORT on the caddy service in the base
(${TLSNOTARY_PORT:-7047}) and devnet (7147) compose files. Verified via
`docker compose config`: mainnet caddy=7047, devnet caddy=7147.

Also drop a stray closing ``` fence in the reverse-proxy runbook.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant