From e87d876f26697492b5b403290733a5572f1bfa7e Mon Sep 17 00:00:00 2001 From: "K. Isom" Date: Wed, 23 Sep 2026 00:46:23 -0700 Subject: [PATCH] M3b plan: task 08 says not to join handler threads and to skip argv[0] The first attempt at task 08 did both and stopped without a commit. Also asks the implementer to debug inside the repository, since OpenCode refuses /tmp. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/plans/M3b/08-toolkit-egress-proxy.md | 24 +++++++++++++++++++---- docs/plans/M3b/README.md | 5 +++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/plans/M3b/08-toolkit-egress-proxy.md b/docs/plans/M3b/08-toolkit-egress-proxy.md index 676fd7c..505c0c7 100644 --- a/docs/plans/M3b/08-toolkit-egress-proxy.md +++ b/docs/plans/M3b/08-toolkit-egress-proxy.md @@ -109,13 +109,22 @@ Use `try_clone` for the second handle of each stream. If a `try_clone` fails, re For each accepted stream: if the number of connections being handled is already `MAX_CONNECTIONS`, drop the stream at once (the client reads the end). Otherwise count it, handle it on its own thread (`std::thread::Builder`, not `spawn`, which panics; if the thread cannot be -started, uncount it), and uncount it when `handle` returns. An `accept` error ends `serve` with -that error. Use an `AtomicUsize` for the count. +started, uncount it), and uncount it **inside that thread** when `handle` returns. An `accept` +error ends `serve` with that error. Use an `AtomicUsize` for the count. + +**Never wait for (`join`) a handler thread in `serve`.** Start it, drop its `JoinHandle`, and go +straight back to `accept`. Joining makes the proxy serve one connection at a time: the second +client never gets its greeting, and `more_than_the_limit_of_connections_are_closed_at_once` fails +with a read timeout (`WouldBlock`). (A first attempt at this task did exactly that.) ## `main.rs` -Add one form before the tool form: the arguments (after the program name) are exactly -`egress-proxy --socket --allow `, in that order, all UTF-8. Then: +Add one form before the tool form: the arguments **after the program name** are exactly +`egress-proxy --socket --allow `, in that order, all UTF-8. Take them with +`std::env::args_os().skip(1)`: without `skip(1)`, the first element is the program's own path, the +form never matches, and the proxy never listens (the given test then fails with "the proxy never +listened", and standard error shows `toolkit: unknown tool ""`; a first attempt did exactly that). +Then: 1. `Allow::parse(list)`; an error `e` → print `toolkit: egress-proxy: --allow: {e}` to standard error, exit 2. @@ -136,6 +145,13 @@ with some of the client's bytes unread makes the client's next read fail with "c rather than read the end; the tests treat both as closed. That is normal and needs nothing from you. +## Debugging + +Work only inside the repository. Do not use `/tmp` or other directories outside it: OpenCode +refuses them, and a refused command ends nothing but wastes the turn. To try the program by hand, +put the socket under `target/`, for example +`target/debug/toolkit egress-proxy --socket target/egress-try.sock --allow example.com`. + ## Steps - [ ] **1. Copy.** `git switch m3b`, then diff --git a/docs/plans/M3b/README.md b/docs/plans/M3b/README.md index 5329d3d..0a0ebcd 100644 --- a/docs/plans/M3b/README.md +++ b/docs/plans/M3b/README.md @@ -60,6 +60,11 @@ At the end: `make gate` prints `gate: ok` with about 638 tests. its `git add` line left the lock out, so the driver stopped on an unclean tree. The design model folded the lock into task 04's commit and added `Cargo.lock` to every task's `git add` (a no-op when it has not changed). The owner resumes from task 05. +- 2026-09-23, task 08: the first attempt passed 13 of 15 tests and ended without a commit, after + OpenCode refused a command in `/tmp`. Its two defects: `main` did not skip the program name, so + `egress-proxy` never matched; and `serve` joined each handler thread, serving one connection at a + time. The attempt is saved in `.state/runs/M3b/08-first-attempt.diff`; the tree was reset, and the + task now says both things explicitly and to debug inside the repository. Resume from task 08. ## Running it