Repository navigation
fix(agent): route agent start through the daemon with round-trip verification - #403
Closed
codeaholicguy wants to merge 1 commit into
Closed
codeaholicguy wants to merge 1 commit into
codeaholicguy wants to merge 1 commit into
Conversation
codeaholicguy
force-pushed
the
fix/opencode-spawned-session-names
branch
2 times, most recently
from
October 17, 2026 06:15
ba933d9 to
84972f2
Compare
Closes #402. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
codeaholicguy
force-pushed
the
fix/opencode-spawned-session-names
branch
from
October 17, 2026 06:59
84972f2 to
5be480d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #402.
Confirmed root cause
Split-brain identity stores:
agent startwritesagents.dbunder the starting process's$HOMEwhile devkitd (socket + data dir) resolves under its own HOME. Under a nested/sandboxed start (HOME=/tmp/fakehome, overlay envs), the write lands where no client looks — the sweep synthesizes<cwd>-<pid>(slug-lib-75800),send --idcan't resolve the name, andstartreports a false success. Harness-agnostic; plausibly shares a root with #400.Fix (scoped per review)
agent.startRPC in devkitd (crates/devkitd/src/agent_start.rs): the daemon validates (name regex, name-in-use againstagents.db+kill(pid,0)liveness, cwd exists), creates the tmux session, polls the pane tree for the deepest harness pid (portedfindAgentPid/pollForPidsemantics), writes the registry row under its own store (schema-v1 columns so TS migrations take a fresh db forward), and returns the entry. Because the write happens inside the daemon's sane view, both HOME-divergence and write-overlay flavors are covered.agent startis a thin client on the tmux provider path: callsagent.startwhen the socket answers; falls back to localstartAgentwhen the daemon is absent or predates the method. Daemon-side errors surface as command failures.AgentHomeDivergenceErrorbefore creating any session when$HOMEdiverges and the account.ai-devkitstore exists, warns when divergent-but-self-consistent, and re-reads the registry write before reporting success — a failed round-trip is an error, not a false OK. The daemon path's registry write is authoritative by construction; its errors propagate.ensureDaemonnever auto-spawns a second daemon from a divergent HOME ($HOMEvs passwd home) — it refuses with a loud diagnostic instead of spawning an invisible twin.unregistered:<folder>-<pid>: synthesized identities in thelistAgentsmerge are marked self-explaining instead of masquerading as assigned names.type:sessionId→type:cwdre-home on pid drift (generic, all harnesses);dropDescendantProcessesfolds spawned child procs into the parent session (TS + devkitd); opencodesession.titleread tolerantly, surfaced assummary/firstUserMessagemetadata only.Deferred to phase 2 per review: HOME-independent socket path chain ($XDG_RUNTIME_DIR → /tmp → $HOME). Socket stays
$HOME/.ai-devkit/daemon.sockas today.Evidence
agent_start.rs: name-validation parity withAGENT_NAME_REGEX.ManagedAgentRuntime.test.ts: refuses under divergent HOME when the account store exists (no session created), warns+proceeds when self-consistent, fails when the registry write doesn't round-trip — the fake-HOME repro shape, at unit level: via-daemon succeeds with the name or fails loudly, never folder-PID fallback.AgentManager.test.ts: registry name survives detected-pid drift, sessionId re-home, ambiguity/no-steal guards,unregistered:expectations,resolveAgentresolves the adopted name.fixtures/harness/opencode/spawned.jsonparity bundle (TS + rust): spawned child folds into parent;slug-lib-75800title stays metadata.Test plan
cargo test -p devkitd7 — greennpm run lint,npm test(8 projects),npm run test:e2e(42) — green on hook runs (unrelatedClaudePrintAgentServicecold-import flake noted)Generated with Devin