Parent: #17
Depends on: #15, #19, #20, and #22
Goal
Let a user safely pause PickLab-managed agent input, control the isolated desktop through a temporary writable viewer, and return control with fresh visual state and an evidence record.
Authority model
Do not store control state in the last-writer-wins session JSON.
Use the session directory for:
- O_EXCL
human.lease.json
- short-lived unique agent permit files
Human lease fields include random lease ID, owner PID/process identity, creation/expiry timestamps, 30-second TTL, 5-second heartbeat, and writable VNC PID metadata.
Every desktop input call and every DevTools relay request:
- Acquires an agent permit.
- Rechecks for a human lease.
- Executes only if allowed.
- Removes the permit in
finally.
Human acquisition creates the lease first, waits for existing permits to drain, then grants control. Timeout aborts cleanly. This closes the check-then-act race.
UX
- Normal
picklab watch remains read-only.
--control acquires the human lease.
- It starts a second temporary loopback VNC server without
-viewonly.
- Writable VNC exists only while a valid lease is held.
- During human control, the DevTools relay rejects all forwarding with a stable busy error.
- On viewer exit/cancellation: stop writable VNC, capture a fresh screenshot, append the control transition, then remove the lease.
request_user_input handles conversational handoff where supported.
- Expired leases recover only after the owner process identity is dead; recovery also kills recorded writable VNC.
The guarantee covers PickLab-managed desktop tools and bridge traffic, not arbitrary same-user local processes. Android viewing/takeover is out of scope for v1.
Checklist
Validation
bun run typecheck
- focused lease/viewer/bridge tests
bun run test
bun run test:coverage
bun run build
- two human acquisitions yield exactly one owner
- no agent operation reaches the fake sink after human acquisition completes
- relay fails closed during control
- writable VNC never outlives the lease
- heartbeat expiry, dead owner, cancellation, viewer crash, session death, and destroy recover safely
- one recorded pause → control → interact → close viewer → resume cycle
Current status: Planned
Next: implement after viewer, relay, evidence, and input-parity foundations are stable.
Parent: #17
Depends on: #15, #19, #20, and #22
Goal
Let a user safely pause PickLab-managed agent input, control the isolated desktop through a temporary writable viewer, and return control with fresh visual state and an evidence record.
Authority model
Do not store control state in the last-writer-wins session JSON.
Use the session directory for:
human.lease.jsonHuman lease fields include random lease ID, owner PID/process identity, creation/expiry timestamps, 30-second TTL, 5-second heartbeat, and writable VNC PID metadata.
Every desktop input call and every DevTools relay request:
finally.Human acquisition creates the lease first, waits for existing permits to drain, then grants control. Timeout aborts cleanly. This closes the check-then-act race.
UX
picklab watchremains read-only.--controlacquires the human lease.-viewonly.request_user_inputhandles conversational handoff where supported.The guarantee covers PickLab-managed desktop tools and bridge traffic, not arbitrary same-user local processes. Android viewing/takeover is out of scope for v1.
Checklist
picklab watch --controldocs/releases/UNRELEASED.mdValidation
bun run typecheckbun run testbun run test:coveragebun run buildCurrent status: Planned
Next: implement after viewer, relay, evidence, and input-parity foundations are stable.