~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
110 lines · 5.4 KB Raw History

Acceptance 0003: CLI requester, ssh over WebRTC, per bidder host (ACC34)

Proves the CLI requester (socialweb-computer run request) rents a VM on each prod bidder and opens ssh to the guest over a WebRTC datachannel, both from a fresh invocation kcp and after that kcp restarts from its state dir.

  • Plan 0034 ACC34-CLI-SSH; the long form with the scope note is 0001 section 9
  • One run per host: only $HOST bids, the other two bidders suspended
  • Last pass: rc142, 2026-10-31 18:13-18:24Z, all 3 hosts
sequenceDiagram
  participant C as CLI requester (alice, oauthQr)
  participant Q as qr.fedfork.com
  participant B as bidder $HOST
  participant G as guest VM
  C->>C: pendingAction scanQr url (stderr)
  Q-->>C: session transfer (signed in as alice)
  C->>B: RFP -> bid -> accept
  B->>G: boot, hostKeys, publicKey, onNetwork
  C->>G: WebRTC offer/answer (signalWebRTC events), STUN only
  C->>G: ssh (StrictHostKeyChecking=yes) uname -a; id
  C->>B: release -> vm.terminated

Preconditions

ItemNeed
Hostsssh to hat-7, hat-9; local bidder on this host; kubeconfigs as in 0001 Variables
Biddersall three bidder-tangled-vouch, Ready, same rc as the CLI
Requesteralice signed in by QR (-- --atproto-oauth-qr); default localRepo makes an unassociated DID and gets no bids
Vouchesbob + john vouch alice; alice vouches bob + john
Signera second shell (or the drives-oauth agent) opens the newest pendingAction url and signs alice in; creds file never printed
hat-7oauthQr bidder: after a role-scope change re-sign bob first (0001 section 9)
ICEguest reaches stun:stun.cloudflare.com:3478, nothing else

Steps

Announce first: linux-kcp -> all: ACC34 on <host> now; hold VM tests.

SWC=socialweb-computer
R=~/.tmp/acc34; mkdir -p "$R"; chmod 700 "$R"
HOST=<local|hat-9|hat-7>
# 1. suspend the other two MarketBidders (spec.suspend=true), wait both Suspended
<kubectl for other host> patch marketbidders.socialweb.computer app --type merge -p '{"spec":{"suspend":true}}'
# 2. fresh invocation: request + hold + first ssh
NAME=acc34-$HOST-$(date +%s)
$SWC run request --state-dir "$R" --name "$NAME" --hold \
  --tunnel ssh:22:webrtc --transport webrtc --exec "uname -a; id" \
  -- --atproto-oauth-qr > "$R/$NAME-request.log" 2>&1 &
# 3. sign alice in with the newest url from the log (second shell / drives-oauth)
command grep -oE 'pendingAction (scanQr|signInAgain) url [^ ]*' "$R/$NAME-request.log" | tail -1
# 4. wait for uid= in the request log and the --hold process to exit
# 5. restarted invocation kcp: second ssh from the same state dir
$SWC run request ssh "$NAME" --state-dir "$R" --transport webrtc --exec "uname -a; id" > "$R/$NAME-ssh.log" 2>&1
# 6. winner check (host lists a Running ComputeVM for alice), plaintext check
command grep -c -E 'a=candidate|AGE-SECRET-KEY' "$R/$NAME-request.log" "$R/$NAME-ssh.log"
# 7. release, then resume the two paused bidders
$SWC run request release "$NAME" --state-dir "$R"

The scripted form (pause, sign-in watch, both ssh runs, winner, release, resume) lives on the lead host as acc34.sh <host>; it is a wrapper of the commands above.

Expected observations

Request log phases ("phase": lines), rc142 runs:

Steplocalhat-9hat-7
start -> AwaitingScan20 s21 s20 s
scan -> identity Ready17 s19 s18 s
Requesting -> Held31 s40 s29 s
ssh returned, fresh kcp (seconds)2.5 s5.2 s8.9 s
ssh returned, restarted kcp6.1 s4.9 s3.6 s
  • signed in as aliceoa.bsky.social, then Held
  • {"msg":"ssh returned","transport":"webrtc","exit":0,"seconds":N} in both logs
  • output contains Linux and uid=
  • whole host run (pause -> resume) ~3 min; all three ~10 min
  • earlier baselines: 2026-10-24 local 2.16 s fresh / ~7 s restarted; rc118 CLI run RFP -> Held 29 s, ssh 4.4 s

Pass criteria

  • Each host: Held, uid= from both invocations, exit 0
  • ssh ran with StrictHostKeyChecking=yes against guest-reported host keys
  • Winner = $HOST (Running ComputeVM for alice DID there while held)
  • Plaintext check counts 0 / 0 (no ICE candidates, no age keys in logs)
  • run request release ends Released; $HOST has no ComputeVM / firecracker left
  • All 3 hosts pass, paused bidders resumed (Ready)

Cleanup

  • Resume both paused bidders (spec.suspend=false), check all three Ready
  • Leftover VM: 0007
  • chmod 700 state dir stays; delete old $R/acc34-* state dirs when done

Known pitfalls

SymptomCause / fix
second ssh exit 255 after 120 s (seen once on local, 18:15Z)first invocation still held the shared state-dir kcp; wait for the --hold process to exit, rerun
invocation kcp did not come up on releasesame: release before the hold process exited
timeout waiting for guest publicKey on hat-7bob's oauthQr session predates a scope change; re-sign bob (0001 section 9)
no bidsalice not signed in by QR (localRepo DID waits in AwaitingApproval), or a vouch missing
every canary lands on the old rcother bidders not paused; suspend them as above
guest publicKey / answer timeoutread the winning bidder journal for the requester refused the market event / submitting the market event to the requester failed