Repository navigation
fix(browser): keep generated sessions reachable after scratch cleanup - #6083
Conversation
fef9877 to
3fa1d31
Compare
Design Review (Fable 5, fork) — 🟡 CONCERNSDesign-level review of Design-Verdict: CONCERNS Sound partial fix, but it trades unbounded orphan daemons for unbounded per-spawn lifecycle directories in the persistent data home, with pruning deferred to the same open issue. Watch
Suggestions
[DESIGN-REVIEWED] 09dd326 |
GPT 5.6 Review (fork) — ✅ no blocking findingsReviewed Review detailsFINDING -- src/kiro_crew/acp/client.py:2805, src/kiro_crew/acp/runtime.py:1061 -- when lifecycle preparation returns [GPT-REVIEWED] 09dd326 |
First Principles Review (Fable 5, fork) — 🟡 CONCERNSPremise-level review of All the reused mechanisms check out in the base tree ( First-Principles-Verdict: CONCERNS The reachability fix earns its place; the operator-root rewriting and the upstream source-scan are extra surface whose zero options cost nearly nothing. What this change shipsIntent: keep an agent's browser daemon closeable after its scratch directory is reclaimed — a FIX.
Watch
Subtractions
[FIRST-PRINCIPLES-REVIEWED] 09dd326 |
Opus 4.8 Review (fork) — ✅ no blocking findingsReviewed |
3fa1d31 to
029d2c7
Compare
|
Both findings on
|
029d2c7 to
8c7de92
Compare
|
All findings on GPT — BLOCKING
Correct: the mixed-generation snapshot was the gap. Fixed along the suggested shape — the kill phase in First Principles — Watch: description claims a lazy import the diff does not have — FIXED. The import was hoisted to module scope in the previous round at GPT's own advisory; the PR body's "What changed" is updated in place to describe the module-level import. First Principles — Subtraction 1 (drop the First Principles — Subtraction 2 (drop the double predicate evaluation) — FIXED. The kill phase routes on the read-nothing |
79563d9 to
f03ae2d
Compare
|
👋 Hi! This PR is currently in draft status. Workflow runs won't be auto-approved until it's marked as ready for review. When you're ready, click "Ready for review" and the workflows will be approved on the next cycle automatically. |
|
All concerns on GPT BLOCKING — shared roots expose browsers across chat families — REBUTTED as pre-existing, with a narrowing change retained.
That authority exists on The implementation nonetheless narrows ambient visibility: generated sessions now receive separate Design Watch — upstream test hooks may disappear silently — FIXED. The active Design Watch — permanent small-file growth — ACCEPTED-AND-DEFERRED to #5986. Per-session namespace directories can remain after a crash. Safe connect-test-then-prune requires the same cross-process ownership decision this PR deliberately avoids; adding unattended deletion here would reintroduce the withdrawn authority problem. The limitation and follow-up are now explicit in Additional correctness finding from focused review — relative configured PWTEST roots — FIXED. Relative roots are rejected before directory creation because gateway and agent CWDs can differ. Absolute configured roots are treated as bases and namespaced per generated session. |
f03ae2d to
4639708
Compare
Move Playwright daemon sockets and session metadata for generated per-process browser sessions out of agent scratch and into fixed owner-restricted data-home directories. This preserves ordinary playwright-cli reachability after the agent or scratch directory is gone, while operator-provided session locations remain untouched. The change deliberately adds no automatic close, external CLI execution, registry read, or process signal. Crash-orphan reclamation remains open under kirodotdev#5986 until cross-process ownership can be proven safely across supported platforms. Related: kirodotdev#5986
4639708 to
09dd326
Compare
|
The blocking caller-controlled-root finding is fixed in
Correct. The prior code passed the fully merged child environment — including caller/app/cron Both ACP spawn paths now construct lifecycle input as exactly A behavioral test constructs Focused independent re-review: blocker CLOSED, no new blocker found. |
Problem / Motivation
A
playwright-clidaemon deliberately outlives the individual command that opened it. Kiro Crew points each agent process'sTMPDIRat a per-process scratch directory, and Playwright derives its Unix control socket from that temporary root. When scratch is reclaimed, the socket disappears while the daemon and Chromium tree remain alive. The CLI then answers "browser is not open" and the surviving daemon is no longer reachable through ordinary lifecycle commands.Why it matters
On one long-running host this produced 19 detached
cliDaemonprocesses, with roughly 10.7 GB belonging to daemons no live session claimed. Preserving the control socket does not automatically kill crash orphans, but it removes the permanent-unreachability root cause: generated sessions remain visible toplaywright-cli listand can be closed through the CLI's own protocol after their originating scratch directory is gone.What changed (motivation → approach → change)
The earlier revisions of this PR attempted automatic process-table reaping. Review correctly established that unattended SIGKILL could not prove cross-process ownership safely on every supported platform: scratch metadata is agent-writable, PID/group identities can be reused, and macOS has no pidfd equivalent. That design is fully removed.
This revision implements the smaller safe direction from #5986: keep generated browser sessions reachable, without adding automatic close authority.
PLAYWRIGHT_CLI_SESSION(kc-<8hex>). For a newly generated name only, both ACP spawn paths now inject short, per-session lifecycle roots:PWTEST_SOCKETS_DIR=<base>/<8hex>/sPWTEST_DAEMON_SESSION_DIR=<base>/<8hex>/dThe default base is
<data-home>/pw; absolute operator-configured roots are treated as bases and namespaced identically. A session's ordinaryplaywright-cli listtherefore does not enumerate peer chat families.<workspace-hash>/<session>.sessionmetadata survive scratch reclamation. This does not create a new same-UID security boundary: latestmainalready documents that Playwright's user-global default registry letslistshow every browser on the machine. The diff reduces ambient visibility and adds no close/read/signal authority.kc-session names preserve their complete existing Playwright location environment. They are never redirected. For generated sessions, lifecycle bases are selected only from the trusted gatewayos.environplus the generated session name; caller/app/cronextra_envis excluded, and returned trusted paths override caller PWTEST values in the final child env. Relative configured lifecycle roots are rejected because gateway and agent working directories can differ.@playwright/clipackage through the existing package anchor and verifies exactplaywright-coreexecution snippets for both variables. Missing/renamed hooks fail back with a warning; a stale standalone package can never satisfy a different active installation. The source verdict is bounded and cached by path/mtime/size.This PR deliberately performs no registry read, socket connection, external CLI execution, automatic close, or numeric PID/process-group signal. Crash-orphan reclamation remains an open design problem under #5986; this change enables operator-controlled cleanup and future graceful lifecycle work without creating cross-session kill authority.
Tests
test_browser_cli_launch.pykc-values;PWTEST_*location variables;test_browser_cli_install.pytest_acp_client.pyPLAYWRIGHT_CLI_SESSION=chromeremains unchanged and does not enter Kiro Crew lifecycle locations.--platform linux), docs-lint, subprocess-encoding gate, spawn audit, and portability regex all passed. One unrelated liveness timing test failed only in a parallel aggregate run and passed standalone on both this branch and clean latestmain.browser_socket_envthroughAcpClient._to_thread_guarding_sandbox. Later focused review confirmed the same-UID peer-control concern is pre-existing onmain, while the diff reduces default visibility; the real relative-root and stale-package probe issues were fixed. No new blocker remained.Manual verification
N/A — this revision changes only inherited environment placement. Unit tests pin the exact env passed by both spawn paths, and the upstream Playwright source contract for
PWTEST_SOCKETS_DIR/PWTEST_DAEMON_SESSION_DIRis exercised through those paths. No user-visible UI changes.Related Issues
Related: #5986 — partial fix only; this PR intentionally does not close the crash-orphan issue.
Checklist
feat|fix|docs|refactor|perf|test|chore|ci|build|revert: ...)Why no screenshot: backend-only environment and lifecycle-path change; no rendered surface is touched.