Skip to content

fix(desktop): keep harnesses available when login-shell capture is slow #458

Closed

Description

@lukemaj

What: Keep installed harnesses available when desktop login-shell capture is slow or fails.
Why: Cavallo lost its full PATH on both d275565 and restored118f, despite working installed CLIs.
So what: One isolated source repair gets focused proof and independent review; the coordinator reassesses fleet delivery without restarting Cavallo.

Outcome and Objective

Reliable GUI startup and provider discovery support the Objective that Promachos works in Chromeria. User requested this separate repair via Gavin at21:00 Warsaw on2026-10-18. Related delivery: #411 / merged PR #419. This is an existing-component repair, not a new system.

Baseline and corrected attribution

Live fork main: d2755650622796e3b13a58655dd58e88fc85e1f9. Its desktop trace records login-shell zsh timeoutMs5000 and a6042.42ms probe span, followed by minimal server PATH. Restoring prior build118f89e94a05 did not fix capture: its backend also lacked NVM/Homebrew paths; Codex and Claude were unavailable while Grok was ready. The coordinator's earlier claim that d275 caused the timeout is superseded. The timeout predates absorption. Current d275 additionally caches unconditional POSIX prepared=true, suppressing server recovery after failure; assess that boundary without blaming chronology.

User relayed idle interactive startup around2.7–3.5seconds. Measure the actual multi-variable capture and launch context, including subprocess/stream overhead, rather than assuming timing one shell proves the production probe. Gavin applied temporary launchd PATH mitigation, private runbook commit00144d3, and asked the user to quit/reopen. Do not change that mitigation or restart/roll back Cavallo.

Upstream first

Read complete upstream Issue10534, which documents the exact timeout/provider symptom, and PR11275, whose job-control change is a candidate only if faithful reproduction supports it. Native03bd839554/eef0e4e1f9 added/revised prepared-environment reuse. Fresh upstream d218d5b still has the five-second bound and unconditional POSIX true. Recheck current merged fixes before editing.

Acceptance and required proof

  • Reproduce slow/failed capture independently of a missing CLI. Distinguish shell startup, capture overhead, process/stream handling, timeout and fallback.
  • Use the smallest owner-level repair: an adequate bounded capture window and a usable launchd fallback or enabled server recovery when capture fails. Never claim successful preparation merely because a platform branch ran.
  • Preserve profile semantics, PATH order/deduplication, related captured values, successful caching and Windows/WSL behavior. No recursive retry or unbounded wait.
  • Meaningful red/green owner/consumer tests, focused desktop/server/shared checks, affected types/lint and exact Fork Stack Model. CI owns the full suite.
  • Independent exact-head review. Real packaged provider discovery is separate coordinator-owned live proof, not implied by HTTP health.

Non-goals and blockers

No package bump, provider reinstall, credential/account changes, global shell edits, new service/cron, arbitrary per-provider pins, live-data test server, browser/device launch or Cavallo restart. Preserve main checkouts and other writers. Keep private evidence outside tracked/public source. No product decision blocks isolated source repair; fleet rollout remains stopped pending reassessment. User owns Cavallo quit/reopen.

Elon record

Requirements and who asked: User requested a separate robust probe repair and fleet reassessment while forbidding another Cavallo restart.
Deleted: Blaming d275 solely from chronology, per-provider pins, reinstalling tools, new host automation and broad shell redesign.
Bottleneck: Actual capture/fallback behavior and faithful proof, followed by provider readiness rather than HTTP health alone.
Checked myself: Both build identities and provider failures, native timeout trace, old/new source, upstream10534 discussion/11275 full diff/current source, and the user-owned launchd mitigation.

Activity

  1. lukemaj commented on Oct 18, 2026

    @lukemaj
    ContributorAuthor

    What: One exclusive implementation task is active for this repair.
    Why: The inherited shell-capture failure needs its own source proof, separate from stopped fleet delivery in #411.
    So what: The worker produces one scoped PR and durable exact-head handoff; the coordinator then dispatches independent review and retains all live-delivery ownership.

    Task node:delegated-task:command%3Amcp%3Ad347275a-deea-49c2-9f31-bb7c1dffda2a%3Adelegate-task%3Achromeria-458-login-shell-capture-20261018-v1; backing thread has the same identifier with thread: in place of node:. Prism selected Grok4.7 on the configured worker kit; no model override or deadline was imposed.

    Exclusive branch fix/458-login-shell-capture, workspace /home/luke/.t3/worktrees/chromeria/fix-458-login-shell-capture, initially exact d2755650622796e3b13a58655dd58e88fc85e1f9. No main checkout mutation. Subsequent #457 main and the user-approved #449 → #454 → #453 → #455 landing window are recorded in the same job's queued context; it must refresh eventual source/base proof after that bounded window, not overwrite those topics or start a competing writer.

    No worker authority to merge, stage, restart, roll back, modify host/provider/credential configuration, open browsers/devices, or run servers against live data. Cavallo's user-owned quit/reopen and launchd PATH mitigation remain untouched. Full source brief, upstream evidence, acceptance and independent-review requirements are in this Issue and its task. Original #411 implementation is terminal/released; this new source job is dedicated to #458.

  2. lukemaj commented on Oct 18, 2026

    @lukemaj
    ContributorAuthor

    What: Login-shell capture now waits 12 seconds and reports prepared only when a login shell returns PATH. Draft PR: #459

    Why: The 5 second cap killed a warm interactive zsh of about 3.5 seconds, and POSIX startup still reported prepared, so the server skipped its own PATH capture.

    So what: This worker keeps the same branch until the parent confirms the bounded final main. Independent review waits until this branch is rebased onto that main and the focused shell proof is refreshed. The earlier release of e9fcf546876a6683f3c283495a045c271617f479 for immediate review is withdrawn. This worker does not merge, push main, restart Cavallo, or post review/independent. CI on the current head was still pending at 21:25 Warsaw.

    Carry, 21:03 Warsaw landing window

    Recorded from Gavin, not a rebase. Landing request: #411 (comment)

    Already on this PR's base c1d3960a1d1c0da46e714553ec32bf08b3136844:

    Approved and still open, in landing order, with no deployment authority: #454 (388648949738ea8320bc4a780d96b39b55db94cb), then #453 (7fb5d1f1ab9b6200b63baf27d23711ce8cf7c165), then #455 (1860d4850bb02a865c10b1669d0e0e6ee1db05db). origin/main has not moved past c1d3960 as of this note. #453 and #455 touch docs/fork-features.md and scripts/fork-upstream-edits.txt. None of the three touch the shell owner. The later rebase is a registry append, then a re-run of the focused shell proof. It waits until the parent confirms the bounded final main. This branch is not being rebased or pushed to main now. Fleet stays stopped. No Cavallo restart.

    Handoff

    • Task: node:delegated-task:command%3Amcp%3Ad347275a-deea-49c2-9f31-bb7c1dffda2a%3Adelegate-task%3Achromeria-458-login-shell-capture-20261018-v1
    • Thread: thread:delegated-task:command%3Amcp%3Ad347275a-deea-49c2-9f31-bb7c1dffda2a%3Adelegate-task%3Achromeria-458-login-shell-capture-20261018-v1
    • Model: grok-4.7, T3 Code Grok harness. Prism selected Grok 4.7 on the worker kit. No effort value was exposed.
    • Workspace: /home/luke/.t3/worktrees/chromeria/fix-458-login-shell-capture (clean, retained for a same-job repair)
    • Branch: fix/458-login-shell-capture
    • Base: c1d3960a1d1c0da46e714553ec32bf08b3136844 (origin/main). Frozen d2755650622796e3b13a58655dd58e88fc85e1f9 was two commits behind. Those commits do not touch the shell owner. The topical base is current main.
    • Head: e9fcf546876a6683f3c283495a045c271617f479
    • Behavior commit: 8e129c71a666fdc29e40c2dd6a530f06b1d13fac. The follow-up only points the fork feature at PR 459.
    • PR: fix(desktop): keep harnesses available when login-shell capture is slow #459 (draft). Linked on this worker thread.
    • Version: not bumped. No VERSION file. Chromeria builds use t3codeCommitHash.

    Diagnosis: installPosixEnvironment used a 5 second timeout and installShellEnvironment returned prepared true on darwin and linux even when the capture timed out or returned no PATH. That skipped server fixPath. Windows was already truthful. launchctl getenv PATH still applies when the shell PATH is missing and does not count as prepared. Upstream d218d5b397d5c23098b697a44ae282b094d68ac9 still has the 5 second cap and unconditional POSIX prepared true. Open PR 11275 is a job-control change for a different issue and was not ported. A read-only Cavallo run of the real multi-variable zsh -ilc capture exited 0 in 2.547 seconds with empty stderr. zsh -lc true was 0.031 seconds and skips interactive startup. The timeout predates d275565.

    Change: shared LOGIN_SHELL_CAPTURE_TIMEOUT_MS is 12000 for the desktop POSIX probe and readEnvironmentFromLoginShell. Prepared is true only when a login shell returned PATH. Windows stays at 5 seconds. Cache, PATH order, launchctl merge, and WSL are unchanged.

    Proof on the behavior sources, 21:21 Warsaw, 2026-10-18:

    ./node_modules/.bin/vp test run apps/desktop/src/shell/DesktopShellEnvironment.test.ts packages/shared/src/shell.test.ts apps/server/src/os-jank.test.ts
    

    3 files, 80 tests passed, 1.30s. Before the production edit, the shared probe still used 5000ms, launchctl-only and empty captures reported prepared true, and a PATH delayed 6 seconds fell through to launchctl.

    vp run --filter @t3tools/shared --filter @t3tools/desktop --filter t3 typecheck exited 0 on these shell sources before the fast-forward. That fast-forward did not edit the shell owner. vp lint on the five source and test files reported 0 warnings and 0 errors. scripts/fork-check.sh and node scripts/fork-features.mjs check printed OK on the final head.

    CI at 21:25 Warsaw: Changes, Collect PR targets, and Prepare PR size config passed. Build and Typecheck, Lint, Test, Test Server 1-8, Test Web, Fork Stack Model, Release Smoke, and Native fingerprint diff were still pending. Mobile native static analysis, Rust, EAS Preview, and Deploy web preview were skipping. Full CI is not complete. Repo-wide local checks were not run.

    Not done: live packaged provider discovery, any Cavallo/Rocky/bestia restart, and independent review. No review/independent status was posted.

    Blockers: landing window still open for #454, then #453, then #455; rebase and focused proof refresh wait for the parent's bounded final main; CI on e9fcf546876a6683f3c283495a045c271617f479 was still pending at 21:25 Warsaw; PR stays draft. No review dispatch against this head.

    Elon record

    Requirements and who asked: Gavin asked, in Issue 458, for a robust login-shell probe so installed harnesses stay available when capture is slow or fails, without another Cavallo restart.

    Deleted: The job-control port from open PR 11275, ignoring stderr, per-provider path pins, recursive retries, counting launchctl alone as full preparation, and the claim that d275565 alone caused the timeout.

    Bottleneck: The 5 second cap against a warm interactive zsh of about 3.5 seconds, plus a prepared flag that skips the server's second capture.

    Checked myself: Desktop, shared, and server source; upstream issue 10534 and the full open PR 11275 diff; the read-only Cavallo timings above; focused tests, typecheck, lint, and both fork checks on this head. Live provider discovery was not run.

  3. lukemaj commented on Oct 18, 2026

    @lukemaj
    ContributorAuthor

    User approval 2026-10-18: merge PR #459 after a passing independent exact-head review, then build current main (d275565 plus #459) and deploy it to cavallo only, with live provider readiness (Codex, Claude, Grok visible after a real GUI launch) as the acceptance gate. Rocky, bestia and TestFlight stay out of scope. Review in progress (Opus 5.5 high).

  4. lukemaj commented on Oct 18, 2026

    @lukemaj
    ContributorAuthor

    What: This task now owns the cavallo Chromeria deployment of main c95b5318036aee547c0d0782442df861c5f0ab30 (#419 plus #459) and is its only writer.
    Why: User approval on #458 (2026-10-18): build current main and deploy it to cavallo only; Rocky, bestia and TestFlight are out of scope.
    So what: This task builds once from the exact SHA, signs, smokes, backs up, stages and activates through the installed restart helper, then runs Live Verification; it rolls back to 118f89e94a05 on any failed check.

    Pre-ownership check, 22:18 Warsaw on cavallo: running build 118f89e94a05 (healthy), no Chromeria.app.new, no .app.prev, no swap or restart job loaded, no pending resume, probation or restart lock, no #411 build/stage/sign process running. #411 markers ROLLOUT_STOPPED and rollout-user-stop.json under ~/.cache/chromeria-411-delivery/ are left in place; this task does not reuse that d275 stage or artifacts.

  5. lukemaj commented on Oct 18, 2026

    @lukemaj
    ContributorAuthor

    What: Cavallo now runs Chromeria main c95b5318036a (#419 plus #459), and Live Verification passed on the GUI-launched app.
    Why: The login-shell probe now finishes and Codex, Claude and Grok are all available and answer real turns.
    So what: Done for cavallo; Rocky, bestia and TestFlight stay out of scope. 118f89e94a05 is kept as /Applications/Chromeria.app.prev for rollback.

    Times Warsaw, 2026-10-18. Full record: runbook cavallo/CHROMERIA-2026-10-18-c95b531.md (commit 845aaf9).

    Artifact. Built once on cavallo in a dedicated worktree at the exact SHA (tree 517d12390cc4). Unsigned ZIP 36efc5da8520fd08beabfe022d8a092daede8c30728724990008c56eb60abbdf. Developer ID signed on cavallo through ~/.local/bin/bao (OpenBao via SSH to rocky) and a throwaway keychain; search list restored, temp keychain deleted. Signed ZIP 995c6c090a16206177da1eec3bab78e8fca28f618352b90483643efd04eed520, ASAR 707f52834bc36072988c7f3a5ce85aeec51b270b9e93ac90350f4325b4e7a88d, executable ddb10d94163fd36efad59c2f19f60d168963193ba3f88d58754b18dab22819a1. Package smoke: strict signature, embedded c95b5318036a, isolated packaged server answered discovery with empty PATH.

    Activation. Backups by read-only VACUUM INTO, all integrity ok. The first safe window (22:43) found Chromeria quit at the Mac at 22:42; the watchdog relaunched 118f at 22:44:41. Fresh safe pre-check at 22:45:13 (only claudeAgent runs running), then chromeria-restart-and-resume: quit 22:45:43, swapped 22:45:48, healthy 22:46:05, probation cleared 22:46:42.

    Acceptance.

    1. Pass. Running app (PID 60817, launched by open, parent launchd) embeds c95b5318036a; ASAR and executable digests equal the signed build; strict signature verifies.
    2. Pass. codex 0.163.0, claudeAgent 2.1.302, grok 1.0.62 all ready, authenticated. One scratch thread per provider ran a real turn on that provider (run rows codex, claudeAgent, grok completed, each replied ok). Threads deleted afterwards.
    3. Pass. desktop.trace.ndjson after activation: login-shell desktop.shellEnvironment.runCommandOutput Success in 2592 ms under installPosixEnvironment/installIntoProcess, no DesktopShellEnvironmentCommandTimeoutError. Caveat: 2.6 s is also under the old 5 s cap (118f's 21:57 launch also finished under 5 s), so this launch shows the probe completing, not the 12 s cap being exercised. The launchctl PATH mitigation is unchanged.
    4. Pass. Recent threads and the 340-message 329aeb81 thread load over HTTP; Rocky and bestia reachable; no uncontinued cut turn. Ten-minute gate: 21 samples 22:47:41 to 22:57:51, all HTTP 200, same PID, same ASAR, no watchdog unhealthy/rollback line.

    Held queues (agents here cannot resume them): "Show Remote Children in Agent Lineage" (2) and "Build venue browser app" (1) predate activation; "Build outreach pipeline #1 (Opus)" (1, delegated child of "Plan an Affordable Italy Wedding") is new since the 22:42 quit or this restart.

    Cleanup. Probe threads deleted, task session revoked, build worktree removed, unsigned ZIP and extracted package deleted. Kept under cavallo ~/.cache/chromeria-458-delivery/: signed ZIP, DB backups (about 4.4 GiB), evidence, rollback.py. Cavallo has 14 GiB free.

    Elon record

    Requirements and who asked: The user (2026-10-18, this Issue) asked for current main built once, deployed to cavallo only, accepted on live provider readiness, the trace and a ten-minute gate.
    Deleted: Rebuilding through chromeria-stage (builds moving main, arms the swap job), the swap-on-quit job, reuse of the #411 stage, any change to the launchctl PATH mitigation.
    Bottleneck: A safe restart window; busy Codex children delayed it by about 17 minutes.
    Checked myself: Exact SHA and tree, signed digests against the running app, trace spans, provider run rows, thread loads, peers and every stability sample.

    Claude Opus 5.5, Claude Code harness in T3 Code (bestia).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions