From 0a99550c6dc594c9df52eff08d20a0f30e95d9b1 Mon Sep 17 00:00:00 2001 From: mkorwel Date: Sun, 15 Mar 2026 12:06:33 -0700 Subject: [PATCH] feat(offload): re-center on persistent workstation model and archive container logic --- .gemini/skills/offload/NEXT_MISSION.md | 21 ++++++++++-- .../skills/offload/scripts/orchestrator.ts | 32 +++++++------------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/.gemini/skills/offload/NEXT_MISSION.md b/.gemini/skills/offload/NEXT_MISSION.md index a53b863d28..2521a3026b 100644 --- a/.gemini/skills/offload/NEXT_MISSION.md +++ b/.gemini/skills/offload/NEXT_MISSION.md @@ -38,6 +38,23 @@ Shift from a "Manual VM" to an "Invisible VM" (Container-Optimized OS) that runs 4. **Configuration**: Point to `.gcp/maintainer-worker.yml`. 5. **Purpose**: Allows developers to test infrastructure changes before merging. +## Phase 2: Refactoring setup.ts for Container-OS +This phase is currently **ARCHIVED** in favor of the Persistent Workstation model. + +### Implementation Logic (Snapshot) +The orchestrator should launch isolated containers using this pattern: +```bash +docker run --rm -it \ + --name offload-job-id \ + -v ~/dev/worktrees/job-id:/home/node/dev/worktree:rw \ + -v ~/dev/main:/home/node/dev/main:ro \ + -v ~/.gemini:/home/node/.gemini:ro \ + -w /home/node/dev/worktree \ + maintainer-image:latest \ + sh -c "tsx ~/.offload/scripts/entrypoint.ts ..." +``` + ## How to Resume -1. Load the checkpoint: `/checkpoint save offload-container-refactor` (if available). -2. Tell Gemini: *"Read .gemini/skills/offload/NEXT_MISSION.md and start Phase 3: Refactoring setup.ts for Container-OS."* +1. Review the archived container-launch logic above. +2. Update `setup.ts` to use `gcloud compute instances create-with-container`. +3. Update `orchestrator.ts` to use `docker run` instead of standard `ssh`. diff --git a/.gemini/skills/offload/scripts/orchestrator.ts b/.gemini/skills/offload/scripts/orchestrator.ts index aea405a0b2..119acee386 100644 --- a/.gemini/skills/offload/scripts/orchestrator.ts +++ b/.gemini/skills/offload/scripts/orchestrator.ts @@ -1,7 +1,7 @@ /** * Universal Offload Orchestrator (Local) * - * Automatically connects to your dedicated worker and launches an isolated job container. + * Automatically connects to your dedicated worker and launches a persistent tmux task. */ import { spawnSync } from 'child_process'; import path from 'path'; @@ -31,7 +31,7 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p return 1; } - const { projectId, zone, remoteHost, remoteWorkDir, useContainer } = config; + const { projectId, zone, remoteHost, remoteWorkDir } = config; const targetVM = `gcli-offload-${env.USER || 'mattkorwel'}`; // 2. Wake Worker @@ -48,8 +48,8 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p const sessionName = `offload-${prNumber}-${action}`; const remoteWorktreeDir = `~/dev/worktrees/offload-${prNumber}-${action}`; - // 3. Remote Context Setup (Executed on Host for efficiency) - console.log(`🚀 Provisioning clean worktree for ${action} on PR #${prNumber}...`); + // 3. Remote Context Setup (Parallel Worktree) + console.log(`🚀 Provisioning persistent worktree for ${action} on PR #${prNumber}...`); const setupCmd = ` mkdir -p ~/dev/worktrees && \ cd ${remoteWorkDir} && \ @@ -58,22 +58,12 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p `; spawnSync(`ssh ${remoteHost} ${q(setupCmd)}`, { shell: true, stdio: 'inherit' }); - // 4. Launch Isolated Container for Playbook - // We mount the specific worktree as RW, and the rest as RO for maximum safety. - const containerImage = 'us-docker.pkg.dev/gemini-code-dev/gemini-cli/maintainer:latest'; - const dockerRun = ` - docker run --rm -it \ - --name ${sessionName} \ - -v ${remoteWorktreeDir}:/home/node/dev/worktree:rw \ - -v ${remoteWorkDir}:/home/node/dev/main:ro \ - -v ~/.gemini:/home/node/.gemini:ro \ - -v ~/.offload:/home/node/.offload:ro \ - -w /home/node/dev/worktree \ - ${containerImage} \ - sh -c "tsx ${persistentScripts}/entrypoint.ts ${prNumber} remote-branch /home/node/.gemini/policies/offload-policy.toml ${action}; exec $SHELL" - `; - - const finalSSH = `ssh -t ${remoteHost} ${q(dockerRun)}`; + // 4. Execution Logic (Persistent OS Mode) + const remoteWorker = `tsx ${persistentScripts}/entrypoint.ts ${prNumber} remote-branch ${remotePolicyPath} ${action}`; + const tmuxCmd = `cd ${remoteWorktreeDir} && ${remoteWorker}; exec $SHELL`; + + const sshInternal = `tmux attach-session -t ${sessionName} 2>/dev/null || tmux new-session -s ${sessionName} -n 'offload' ${q(tmuxCmd)}`; + const finalSSH = `ssh -t ${remoteHost} ${q(sshInternal)}`; // 5. Open in iTerm2 const isWithinGemini = !!env.GEMINI_CLI || !!env.GEMINI_SESSION_ID || !!env.GCLI_SESSION_ID; @@ -93,7 +83,7 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p end run `; spawnSync('osascript', ['-', tempCmdPath], { input: appleScript }); - console.log(`✅ iTerm2 window opened on ${remoteHost} (Isolated Container).`); + console.log(`✅ iTerm2 window opened on ${remoteHost} (Persistent Session).`); return 0; }