Skip to content

feat(tunnel): simlock tunnel reverses a leased device's port to the caller (#1114) - #1126

Merged
V3RON merged 116 commits into
callstackincubator:mainfrom
leonardoxr:task/1114
Nov 1, 2026
Merged

V3RON merged 116 commits into
callstackincubator:mainfrom
leonardoxr:task/1114

Conversation

@leonardoxr

@leonardoxr leonardoxr commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1114

Status

Implement: done Review: cap reached; R4 fix accepted by the maintainer Hardware: pass (slow-android-tunnel, 137b7dd) Gate: running

Done when

  • The Tests lines pass. — src/cli/tunnel.test.ts, src/ports/websocket-client.test.ts and the tunnel CLI e2e files run in the fix runs; CI on the head
  • e2e/slow-android-tunnel.test.ts passes in the slow lane on a machine with the Android SDK: an emulator lease on a lone worker with tunnels on; simlock tunnel reverse <p> with a loopback HTTP server on the caller; on the device, (printf 'GET / HTTP/1.0\r\n\r\n'; sleep 2) | nc 127.0.0.1 <p> prints the server's body (the nc form the Facts' check used). — slow lane on 137b7dd, 2026-11-01 18:12, 1 passed
  • lazy-loading.test.ts shows ws loaded by simlock tunnel and by no other command or the MCP entry. — lazy-loading.test.ts, checked by the spec review
  • The CLI reference describes simlock tunnel, lists SIMLOCK_URL and SIMLOCK_TOKEN, and words the global --token as the credential a command sends. — cli.mdx, checked by the claims review

Assumptions

  • Assumption: an upgrade or lookup refusal whose body code is not in the contract's table (HTTP UNAUTHENTICATED) — printed with that code and exit 1 by the command itself, since the table has no row for it.
  • Assumption: no Lease <id>: prefix on an upgrade refusal's body message — the body's own message is printed unchanged; only a REFUSED frame gets the prefix, as the issue words it.

Review

Spec review: 0 blocking, 0 fixed, 1 notes. Code review: 3 blocking, 3 fixed, 0 notes. Claims review: 0 blocking, 0 fixed, 0 notes.
Rounds: 2. Tokens: 36.5M.
Runs: 12. Cost USD: 4.3995. Agent seconds: 2017.

Rejected:

  • spec: src/cli/commands/tunnel.ts:293 --url refuses a path, query or fragment — origin-only is documented at cli.mdx:218 and the API is served at the root [nonblocking]

Assessment: complete — R4's fix (50c1f69, two test assertions, both probed) came after the final fix-check; the maintainer accepted it on 2026-11-01

Written by an agent.

leonardoxr and others added 30 commits October 31, 2026 00:50
…els and gets READY, and a device connection arrives as OPEN with its bytes as DATA (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ctions as OPEN and DATA (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ED and close 4003 (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…de and close 4003 (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…tation, and is refused (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r and gets ROTATION_UNSUPPORTED naming it (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…blet simulator (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s and gets INPUT_UNAVAILABLE with the reason (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… when the helper or the write fails (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…esh helper; a socket open during a rotate keeps its helper (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…credit pausing only its connection (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…credit (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… a closed connection is ignored (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s sockets and device.rotate (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…when the socket closes, the lease ends or the daemon stops (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…gets the op's output (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…a tunnel's rules and close its connections (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rotate (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ugh a gateway (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… may (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… worker (callstackincubator#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…eway (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…wn message (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he unknown message (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ller's lease id (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
leonardoxr and others added 10 commits October 31, 2026 02:10
…rove rotate's cases (callstackincubator#1107)

The coordinator rewrote the worker's lease id only for two codes and with a
substring replace; it now maps every coded error's details.leaseId and replaces
the id only as a whole token. The rotate e2e test sends all four orientation
names, covers a rejected open and a failed shared input, and no longer waits on
the daemon's real host-load probe on Linux; the registry's lease-end close and
failure drop get a unit test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ls, and reword the orientation claims (callstackincubator#1107)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ut bound (callstackincubator#1108)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… rules at start, name the call in refusals (callstackincubator#1112)

A removal that fails keeps the loopback listener reserved and the device's
reclaim frees it; the start sweep only reads a leased device's rules and
reserves their ports; refusal texts follow the spec's shared values; a
cancelled TcpStream no longer closes its readable twice.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r#1112)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…lementation with input (callstackincubator#1113)

Merge origin/task/1112. One src/modules/relay-channel.ts now holds the channel
framing, channelSocket, the close mapping and the refusal bodies that input and
tunnel each copied; the tunnel's coded relay failure answers 503 like input's.
Tests: the gateway aborts the relay when the holder closes, when a worker frame
is over the limit and when an upgrade is abandoned. The tunnel config row says
a gateway serves it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ay channel names it (callstackincubator#1113)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…-json timing bound (callstackincubator#1114)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@leonardoxr
leonardoxr marked this pull request as ready for review October 31, 2026 05:26
@leonardoxr

leonardoxr commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor Author

Review ledger

Round 1: 35d8bbf
Round 2: 137b7dd
Round fix-check: 137b7dd

Runs: 12. Cost USD: 4.551. Agent seconds: 3658.
Tokens input 324, output 94085, cache read 6897232, cache write 725711.
- fix implementer: claude-sonnet-5-5 147 s $0.256
- review 1 reviewer: claude-sonnet-5-5 492 s $0.4096
- review 1 spec: claude-sonnet-5-5 50 s $0.4039
- review 1 code both: claude-opus-5-5 378 s $1.8275
- review 1 claims: claude-sonnet-5-5 33 s $0.1507
- fix 1 implementer: claude-sonnet-5-5 112 s $0.1945
- review 2 reviewer: claude-sonnet-5-5 126 s $0.1944
- hardware hardware-verifier: claude-sonnet-5-5 135 s $0.0896
- review fix-check reviewer: claude-sonnet-5-5 1975 s $0.4317
- review fix-check code both: claude-opus-5-5 100 s $0.3834
- review fix-check claims: claude-sonnet-5-5 28 s $0.0837
- fix fix-check implementer: claude-sonnet-5-5 82 s $0.126
Finding outcomes: {"fixed":3,"nonblocking":1}. Classes: {"behaviour not asked for":1,"exit not within 2 s of Ctrl-C":1,"spec line delivered differently":1,"testing 3":1}.
{"findings":[{"id":"R1","role":"code","class":"exit not within 2 s of Ctrl-C","outcome":"fixed","path":"src/ports/websocket-client.ts","round":"1","fix":"137b7dd88c9ae6f702b222ce46de041740470424"},{"id":"R2","role":"code","class":"spec line delivered differently","outcome":"fixed","path":"src/cli/commands/tunnel.ts","round":"1","fix":"137b7dd88c9ae6f702b222ce46de041740470424"},{"id":"R3","role":"spec","class":"behaviour not asked for","outcome":"nonblocking","path":"src/cli/commands/tunnel.ts","round":"1"},{"id":"R4","role":"code","class":"testing 3","outcome":"fixed","path":"src/cli/tunnel.test.ts","round":"fix-check","fix":"50c1f696c"}]}

Written by an agent.

leonardoxr and others added 5 commits October 31, 2026 02:36
…t a connection whose write failed, refuse a --url with a path, query or fragment (callstackincubator#1114)

Also corrects the comments on which ports files import ws.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…into helpers under the CRAP threshold (callstackincubator#1114)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
V3RON added 6 commits November 1, 2026 10:52
# Conflicts:
#	src/contract/AGENTS.md
#	src/contract/protocol.ts
#	src/daemon-protocol/index.test.ts
#	src/daemon/AGENTS.md
#	src/daemon/main.ts
#	src/drivers/android/index.test.ts
#	src/drivers/android/index.ts
#	src/modules/AGENTS.md
#	src/modules/testing.ts
#	website/src/content/docs/docs/reference/errors.mdx
# Conflicts:
#	src/input/AGENTS.md
#	src/modules/AGENTS.md
# Conflicts:
#	src/cli/AGENTS.md
#	src/cli/index.test.ts
#	src/cli/index.ts
#	src/cli/remote-lease.ts
#	src/cli/tree.ts
#	src/daemon/lease-inputs.test.ts
#	src/gateway/fleet-coordinator.ts
#	website/src/content/docs/docs/reference/cli.mdx
@V3RON
V3RON marked this pull request as draft November 1, 2026 17:20
@V3RON
V3RON marked this pull request as ready for review November 1, 2026 17:52
@V3RON
V3RON merged commit 0857ffe into callstackincubator:main Nov 1, 2026
116 of 119 checks passed
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.

simlock tunnel: reverse a leased device's port to the caller's machine

2 participants