Repository navigation
Description
[Windows 11] Follow-up for v0.7.2: OpenCode GOA composer regex mismatch, watchdog stall flood on reported tasks, and worker tool scoping
First off, thank you for the super fast turnaround on #49 and the credit in v0.7.2! The daemon ping-pong fix, old session check, and blank chat fallback are working great.
Following up from our live test session on Windows 11 with OpenCode as GOA (and worker sessions running under OpenCode with Gemini Flash / DeepSeek), here are three factual issues with code traces, live screen evidence, and telemetry from our running daemon:
1. OpenCode GOA auto-wake failure on Windows (core/agent/prompts.go)
Observed Behavior
When worker sessions finish their turn and invoke goa report --outcome done "...", the report is accepted by the daemon and appended to ~/.enowx-app/goa-tell.json. However, OpenCode GOA never wakes up to process it, leaving reports trapped in the file indefinitely.
Root Cause Trace
In daemon/goa_inject.go:130-133, goaCanType guards line injection into idle sessions:
func goaCanType(sess *session.Session, now time.Time) bool {
info := sess.Info()
return !info.Exited && info.State != proto.StateWorking && info.State != proto.StateWaiting &&
sess.TypedFor(now) >= goaTypedQuiet && agent.PromptEmpty(sess.Terminal().Text())
}OpenCode is an agent with no native background hooks, so it relies entirely on path 4 ("typed in, but only into a composer sure to be empty").
On Windows, reading OpenCode's idle terminal buffer (enowx read <goa-session-id>) reveals the exact screen lines:
Baris 15: ▣ Goa · wz/deepseek-v4.1-flash · 2m 10s
Baris 16:
Baris 17: ┃
Baris 18: ┃
Baris 19: ┃ ... ctrl+p commands • OpenCode 1.18.35
Notice lines 17–18: OpenCode renders an input box border with two leading spaces: " ┃".
When evaluated against core/agent/prompts.go:
emptyPlaceholderfails because it expects Claude/Codex placeholders (Ask Codex...,Type your message...,Try "...") and requires prompt glyphs[❯›>]. OpenCode usesAsk anything…without glyphs.- Fallback
promptAlonefails:var promptAlone = regexp.MustCompile(`^[│|┃]?\s*[❯›>$%#]\s*[│|┃]?$`)
promptAlonestrictly requires at least one of[❯›>$%#]. In OpenCode on Windows, the idle box contains only" ┃"with no prompt glyph and 2 leading spaces.
Because PromptEmpty returns false, goaCanType evaluates to false. In daemon/goa_inject.go:111, lines are continually pushed back into s.goa.tell, keeping GOA permanently silent.
Suggested Fix
Update regexes in core/agent/prompts.go to match OpenCode's empty input border and placeholder:
var promptAlone = regexp.MustCompile(`^\s*[│|┃]?\s*[❯›>$%#]?\s*[│|┃]?$`)
var emptyPlaceholder = regexp.MustCompile(`^\s*[│|┃]?\s*([❯›>]\s*)?(Ask anything.*|Ask Codex to do anything|Type your message or @path/to/file|Try "[^"]*")\s*[│|┃]?$`)2. Cascading Watchdog stall flood on tasks that already reported done (daemon/goa_stall.go)
Observed Behavior
~/.enowx-app/goa-tell.json maxed out at its 200-line capacity (goaTellMax), with 156+ duplicate stall warnings generated for the exact same task (t64ea68d8). The daemon log flooded with:
level=WARN msg="goa: too much waits for GOA, the oldest goes" lines=1
This warning loop evicted genuine worker completion reports from the buffer.
Root Cause
In daemon/goa_stall.go:
case l.Info.State == "" || l.Info.State == proto.StateDone:
if l.Still >= idle {
return "idle: its agent isn't working on it", idle
}The watchdog assumes "a turn ending moves the board on". However, because GOA never received the completion report due to Issue 1, the task remained on goa-board.json with "status": "working", even though the worker had already finished and set "outcome": "done".
stallCase does not inspect task.Outcome. It repeatedly flags the completed worker session as stalled every few minutes.
Suggested Fix
In daemon/goa_stall.go, skip or deduplicate stall notifications if task.Outcome != "" or if an unsettled turn report for that task is already pending.
3. Field Data & Feedback: OpenCode optimization & Worker MCP tool scoping
From extended multi-agent testing on Windows 11:
-
OpenCode SQLite database bloat:
After intensive multi-turn runs,~/.local/share/opencode/opencode.dbgrew to 4.85 GB on disk. Performing reads or transcript operations on a database this size creates noticeable disk I/O lag on Windows. Consider adding a vacuum/compaction check or recommending DB maintenance in docs. -
Restricting MCP tool schema for Worker sessions (Mitigating Role Confusion):
In worker sessions, enowX currently exposes the full suite of orchestrator MCP tools (enowx_session_send,enowx_session_read,enowx_session_spawn, etc.).
When running smaller, cost-effective models (e.g. Gemini 2.5/3.8 Flash, DeepSeek V3) in worker sessions, exposing supervisor tools causes acute Role Confusion. Workers mistakenly assume they are the supervisor:Sesi 9e2fe58d5ce1 sedang membaca cameras.json... Saya pantau manual sampai selesai dan saya laporkan hasilnya...The worker then ends its turn prematurely without executing any file edits. Restricting worker sessions to file/execution tools (
read,edit,write,bash,browser) prevents this hallucination and makes lightweight models significantly more reliable in worker sessions.
4. Sleep/Resume 7-hour RPC context deadline hang
In app.log and enowxd.log after the machine resumed from overnight sleep:
2026-11-07T08:18:39+07:00 rpc.slow method=cloud.request took=6h55m40.338s sentBytes=72 gotBytes=0 err="cloud.request: cloud: Post \"https://cloud.enowx.ai/v1/teams/.../presence\": context deadline exceeded"
The presence RPC had no active TCP keepalive or sleep-aware cancellation, hanging for ~6h 55m and triggering a 1.18s GDI thread lag upon wake (app-lag-20261107-081841.txt). A transport-level timeout on HTTP clients would resolve this cleanly.
Activity
sicknewbie commentedon Nov 7, 2026
Update & Empirical Field Trace: OpenCode GOA Session Collision & Revert to
buildAgent (Agent not found: "goa")Following up with another reproducible finding observed during sustained testing when running OpenCode for both GOD of Agents and worker sessions on Windows 11 (OpenCode 1.18.35):
1. Symptom
While in the GOD of Agents tab:
GoatoBuild · <model>(e.g.Build · ag/gemini-3.8-flash 9router), despite the working directory remaining~/.enowx-app/goaand the enowX tab header displayingGOD of Agents.2. Root Cause Evidence (From
opencode.logandopencode.db)A. Session ID Collision in Runtime Log
Inspecting
~/.local/share/opencode/log/opencode.logreveals two concurrent runner processes colliding on the exact same session ID (ses_e517d0fb0ffe4fHiDZvKRZ0v8x):run=1ca5157d(worker process running standardagent=build) andrun=7eedb956(GOA process runningagent=goa) both latched ontoses_e517d0fb0ffe4fHiDZvKRZ0v8x. Because SQLite operations are shared across OpenCode processes, the GOA process aborted and the session record was overwritten.B. Persistent State Overwrite in SQLite
Querying
~/.local/share/opencode/opencode.dbfor the affected session:Output:
directory:C:/Users/.../.enowx-app/goaagent:'build'(overwritten from'goa')model:{"id":"ag/gemini-3.8-flash","providerID":"9router"}When OpenCode resumes via
opencode --continue, it restores the agent from the SQLitesessiontable (build), ignoring"default_agent": "goa"fromOPENCODE_CONFIG_CONTENT. Underbuildmode, only built-in agents (build,explore,general,plan) exist in OpenCode's registry, so any prompt routed togoatriggersAgent not found: "goa".3. Code Trace in enowX
Premise regarding OpenCode 1.x server/isolation:
In
core/agent/opencode_service.go:3-12:OpenCode 1.18.x does have an internal background server (
SessionHttpApi) and shares a singleopencode.dbfile across all running instances on the user account. Without explicit session or port isolation, concurrent OpenCode sessions can step on each other's session IDs.Missing
--agentflag on resume:In
core/agent/presets.go:43, OpenCode continue is defined purely as:Because it relies entirely on
"default_agent": "goa"inOPENCODE_CONFIG_CONTENTwithout an explicit--agent goaCLI argument, OpenCode defers to the agent persisted in SQLite whenever--continueis used.4. Suggested Fix
Pass
--agent goaexplicitly on CLI for GOA sessions:When spawning or resuming OpenCode GOA (
daemon/create.go&daemon/persist.go), append--agent goato the command line:OpenCode 1.18.35 supports
--agent <name>on the CLI. Passing it explicitly forces the active session to bind togoaregardless of prior SQLite state.Pass explicit
--session <id>on session launch:Providing
--session <unique-session-id>when starting each OpenCode session ensures GOA and worker sessions never bind to or overwrite each other's records inopencode.db.sicknewbie commentedon Nov 7, 2026
Field Report & Deep-Dive (Part 3): Session Crossover via
opencode --continueTemplate, Ghost Process PTY Resize Glitch, and Memory ExhaustionFollowing up on our earlier trace on session collisions and SQLite contention, we conducted an empirical audit on enowX v0.7.2 after experiencing a complete
MemoryExhaustioncrash, session cross-contamination, and rapid viewport flickering on Windows 11.Here are the concrete findings, binary traces, and log data:
1. Session Crossover on Startup:
opencode --continueTemplate Overrides--session <id>Observed Behavior
After restarting or closing and reopening enowX with multiple sessions active, tab contents, chat transcripts, and canvases get cross-linked and scrambled across tabs (e.g. the GOA tab renders the Canvas Style 2 terminal, or worker tabs hijack each other's prompts).
Root Cause & Evidence
Inspecting compiled strings inside
enowX.exeandenowx-daemon.exe(daemon/36a940ad363f/enowx-daemon.exe) reveals the--continueflag hardcoded into the default resume template for OpenCode:~/.enowx-app/sessions.json:When an OpenCode session is first created,
commandproperly binds to the session ID:restartarray with the generic template:On application startup, enowX iterates over all active sessions in
sessions.jsonand executesrestart. Every active OpenCode tab executesopencode --continueat the exact same moment. In OpenCode CLI,--continueresolves to the most recent session in that directory. As a result, multiple tabs race to attach to the same latest session row in SQLite, corrupting the UI state and scrambling tab transcripts.Suggested Fix
In
daemon/persist.go(and wherever therestartcommand is generated), preserve the explicit session ID fromcommand:Never default OpenCode sessions to a bare
--continuewhen an explicit session ID is already assigned.2. Viewport & Terminal "Resize Ping-Pong" Glitch: Missing Single-Instance Mutex on Windows
Observed Behavior
The application window, sidebar, and terminal viewport rapidly expand and shrink in a continuous jitter/flicker loop.
Root Cause & Evidence
Checking running processes revealed two independent
enowX.exeinstances running concurrently under the same user session:PID 52468(launched earlier in the background)PID 56304(launched when the user reopened the app from the taskbar)Both GUI instances held open WebSocket/RPC connections to the same local daemon socket (
~/.enowx-app/enowxd.sock):Both windows render the same Ghostty/xterm terminal instance. Window A calculates its viewport (e.g.
cols=120, rows=40) and sends a PTY resize RPC to the daemon. Window B receives the broadcasted resize, recalculates its bounding box (e.g.cols=118, rows=40due to subtle DPI/padding differences), and sends a counter-resize RPC back.The daemon continuously bounces resize events between both windows, creating an infinite resize loop. Terminating
PID 52468immediately stopped the glitch.Suggested Fix
Add a single-instance mutex check (
CreateMutexW/ named pipe check) on Windows startup. If an instance ofenowX.exeis already running, activate and bring the existing window to the foreground instead of spawning a new GUI process.3. Unbounded Concurrency in GOA Triggers Windows
MemoryExhaustionObserved Behavior
Windows ran out of virtual memory / swap (
MemoryExhaustion), forcefully terminating sockets and background daemons (wsarecv: An existing connection was forcibly closed by the remote host).Root Cause & Evidence
GOA spawned 5 worker sessions concurrently (Matrix, Routes, Login/Register, Corridor, Popup rail).
Upon relaunch, enowX started 11 parallel
opencode.exeprocesses (~700 MB to 1.3 GB RAM each), 10enowx-daemon.exeinstances, and 9 separate git worktrees under~/.enowx-app/worktrees/CCTVKU-0fc9d9c5/.Total RAM usage exceeded 14.5 GB of 16 GB physical RAM, completely exhausting the pagefile and crashing
enowxd.sock.All 11 instances concurrently read and wrote to a single 4.98 GB
opencode.db(568 sessions, 23,793 messages, 97,045 parts).The daemon log shows RPC latencies spiking due to lock contention:
Suggested Fix
sicknewbie commentedon Nov 8, 2026
Field Report & Deep-Dive (Part 4): GOA Lifecycle on Windows — Agent-Switching UI Mismatch & Worker Notification Stalls
Following up on sustained testing with two interrelated findings observed during GOD of Agents (GOA) runtime operations on Windows 11 (enowX v0.7.2):
Issue A: Agent-Switching UI/RPC Mismatch & False-Positive Rollback ("Claude Code didn't take")
1. Symptom
In the GUI modal "Settings of GOD of Agents":
This creates a false impression that the target agent binary (
claude.exe) crashed or failed to start, when in fact the CLI is fully authenticated and healthy.2. Empirical Evidence & Diagnostic Trace
~/.enowx-app/enowxd.log):agent=claudeexited cleanly withcode=0(NOT a crash). The exit occurred within the 5-secondgoaSwitchSettlewindow, triggering automatic rollback.~/.enowx-app/app.log):Running the exact transition via CLI succeeds instantly in 1 turn:
enowX.exe goa switch --check: sessionb60df4832327immediately attached toclaude-opus-5-5 · mediumin stateidle.3. Root Cause Analysis
goaSwitchRun/goaSettingsDialog) fails to passnewConversation: trueto the daemon RPC. The daemon attempts to resume the previous conversation ID across incompatible agent runtimes (opencode->claude), which cleanly aborts withcode=0.--forceHandling When GOA Has Active Tasks: Perdocs/goa, when GOA has worker sessions running or queued, the daemon requires--forceto interrupt. The GUI dialog lacks a confirmation prompt (e.g. "GOA has active tasks. Force restart?") and does not pass the force flag, triggering an automatic rollback.Issue B: Worker Report Delivery Stall on Windows (
goa-tell.jsonBuffer Accumulation)1. Symptom
After worker sessions finish their delegation and execute
enowx goa report --outcome done "...", GOD of Agents does not proactively notify the user or settle tasks. GOA remains completely silent until the user manually submits an arbitrary message into GOA's chat terminal, at which point GOA immediately wakes up, acknowledges the backlog, and reports the results.2. Empirical Evidence
~/.enowx-app/goa-tell.jsonBacklog:Inspecting
goa-tell.jsonrevealed dozens of unconsumed event lines accumulating over hours, reaching 92+ KB in file size:[ {"text":"[enowX GOA] Task t6d06a8c8 \"...\" reports done: ...", "task":"t6d06a8c8"} ]This stall occurs on both Claude Code and OpenCode. When queried about the delay upon manual wake-up, the agent confirms:
3. Root Cause Analysis
goa_told_watch.go/goaTellLine) to type lines fromgoa-tell.jsoninto the GOA terminal once the session is deemed idle.Suggestions for the Development Team
--new-conversationin the GUI:In the "Settings of GOD of Agents" modal handler, whenever
targetAgent !== currentAgent, automatically ensurenewConversation: trueis included in the RPC payload sent togoa.switch.If GOA has active tasks/workers, display a confirmation prompt ("GOA has active tasks. Force restart?") and pass
force: trueupon user confirmation.goa-tell.json:Rather than relying purely on simulated keystroke injection into a quiet PTY, consider triggering an explicit PTY wake-up / carriage return, or providing a dedicated local event-stream/hook pipe to deliver worker lifecycle updates to GOA reliably on Windows.
We strongly suggest adding automated end-to-end integration tests for modal action buttons (specifically agent and config switching:
opencode<->claude<->codex<->claude-platform) to verify that GUI actions achieve parity with CLI executions without requiring manual terminal intervention.enowdev commentedon Nov 9, 2026
Thanks for the detailed traces. Where each point stands on main:
PromptEmptydoesn't know OpenCode's empty composer, so lines wait. Wait for GOA's agent to start before a switch fails #53 fixes the Claude Code side (the rule joined to the composer), not OpenCode. We'll add OpenCode's composer from real screens, and look at an OpenCode plugin that wakes GOA when it goes idle.goa report. We won't touch OpenCode's database ourselves; see [Feature Request] UX & Storage enhancements: Canvas Pick Element inspector and Clean Cache storage breakdown with DB compaction #52.From your comments: OpenCode resuming with
--continueinstead of its session ID is real, and we'll resume by ID and pass--agent goafor GOA. The Settings switch does sendnewConversationafter asking. The "didn't take" error was PowerShell starting the agent late, fixed in #53. If it still happens once that is released, the daemon log lines around the switch would help.The fixes above are being worked on now.