Skip to content

fix(flows): auto-pick free ports in flow-11, auto-load .env in lib.sh#371

Merged
bussyjd merged 1 commit intomainfrom
fix/flow11-auto-ports
Apr 23, 2026
Merged

fix(flows): auto-pick free ports in flow-11, auto-load .env in lib.sh#371
bussyjd merged 1 commit intomainfrom
fix/flow11-auto-ports

Conversation

@bussyjd
Copy link
Copy Markdown
Collaborator

@bussyjd bussyjd commented Apr 23, 2026

Summary

Two related quality-of-life fixes for the flow-test suite:

  • `flows/lib.sh` now sources `$OBOL_ROOT/.env` with `set -a` so a single repo-local file can carry `REMOTE_SIGNER_PRIVATE_KEY` and any `FLOW*_PORT` / `FLOW*_URL` overrides. Already-exported shell vars still win.
  • `flows/flow-11-dual-stack.sh` now defaults all 8 Alice/Bob ingress ports to OS-picked ephemeral ports (`pick_free_port`) instead of hardcoded `80/8080/443/8443` + `9080/9180/9443/9543`. Explicit `FLOW11_*_PORT` env vars still win. The duplicate helper bodies in the script are dropped — `is_port_listening`, `require_ports_free`, `pick_free_port` are now shared in `lib.sh`.

Why

Running flow-11 alongside another cluster on the same machine used to require manually picking and exporting 4–8 non-colliding ports, and Claude Code ended up guessing them every time. With auto-pick, dual-stack runs just work without planning. The `.env` auto-load is a natural complement: pin a specific port once for reproducibility without re-exporting it every session.

Behavior

  • Default: no env overrides → 8 ephemeral ports assigned by the kernel, preflight re-checks they are free (small TOCTOU window that k3d's fast bind closes in practice).
  • Override any subset: set `FLOW11_ALICE_HTTP_PORT=10080` (etc.) in shell or `.env` — that value is honored verbatim, the rest still auto-pick.
  • No change to other flows — lib.sh additions are additive.

Test plan

  • `bash -n flows/lib.sh && bash -n flows/flow-11-dual-stack.sh` — syntax clean
  • `pick_free_port` called 8× returns 8 distinct ports in the ephemeral range
  • `.env` auto-load: `REMOTE_SIGNER_PRIVATE_KEY` is exported after sourcing lib.sh (verified via Python `os.environ`; value not printed)
  • Full flow-11 run end-to-end against two stacks on the same host (kicked off separately)

- `flows/lib.sh`: source `.env` (if present at `OBOL_ROOT`) with
  `set -a`, so `REMOTE_SIGNER_PRIVATE_KEY` and any `FLOW*_PORT` /
  `FLOW*_URL` overrides can be persisted per-checkout instead of
  re-exported every invocation. Existing shell exports win.
- `flows/lib.sh`: promote `is_port_listening`, `require_ports_free`,
  `pick_free_port` to shared helpers.
- `flows/flow-11-dual-stack.sh`: default all 8 Alice/Bob ingress ports
  to `pick_free_port` instead of `80/8080/443/8443` and
  `9080/9180/9443/9543`. Explicit `FLOW11_*_PORT` env vars still win.
  Drop the duplicate helper bodies (now in `lib.sh`).

This eliminates the "guess non-conflicting ports" step when running
dual-stack alongside another cluster on the same machine.
@bussyjd
Copy link
Copy Markdown
Collaborator Author

bussyjd commented Apr 23, 2026

Flow-11 dual-stack — full green on the first try with auto-picked ports

Ran ./flows/flow-11-dual-stack.sh from this branch alongside the existing local `obol-stack-fond-martin` k3d cluster (which holds 80/8080/443/8443).

Auto-picked ports (no env overrides, no FLOW11_*_PORT set):

  • Alice: `60718/60719/60720/60721`
  • Bob: `60722/60723/60724/60725`

Zero collision with the already-running cluster on the canonical ports. This is the first time I've run dual-stack without manually computing non-conflicting port numbers.

Result: 42/42 steps passed.

Notable real on-chain evidence from the run:

  • Alice (`0xC0De030F6C37f490594F93fB99e2756703c4297E`) registered as ERC-8004 Agent ID 5127 on Base Sepolia
  • Bob's agent discovered Alice via an ERC-8004 registry scan driven by a natural-language prompt to OpenClaw
  • Bob's agent, via a second natural-language prompt, ran `buy.py buy` and created a PurchaseRequest Ready with 5 pre-signed ERC-3009 auths
  • x402-buyer sidecar reported `alice-inference: remaining=5 spent=0 model=paid/qwen3.5:9b` post-reconcile
  • Paid inference through LiteLLM → buyer sidecar → Alice's tunnel returned a 200
  • On-chain USDC Transfer from Bob's remote-signer wallet to Alice recorded; balance deltas match on both sides
  • Cleanup left no stale resources

Caveat: Kicked off one false-start first run

On the very first invocation the docker.io mirror had never pulled `cloudflare/cloudflared` before. The hard-coded 30 s rollout timeout in `internal/tunnel/tunnel.go:203` fired, `obol sell http` silently skipped the ERC-8004 registration step (because it's nested inside the tunnel-success branch in `cmd/obol/sell.go:711-733`), and flow-11 hit `FAIL: [18] Alice: ServiceOffer Ready`. Killed that run, deleted the dead cluster, and rerun — the second run hit the now-cached `cloudflared` image and everything flowed. Filing this as a separate follow-up PR since it's orthogonal to auto-ports.

/cc

@bussyjd bussyjd merged commit a7ff7c0 into main Apr 23, 2026
6 checks passed
@OisinKyne OisinKyne deleted the fix/flow11-auto-ports branch April 23, 2026 19:25
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