Dashboard › opencode › Distillation
b2592dc1-0d70-4e0a-8d73-d315ae4fa30e["lore_tm_v1_JBg6UPZiENxUClnlFqAdP1VXP5yyvj8zC5-M9OBJMKo","lore_tm_v1_z9koL7fvs9eiXU0dQiv9EO4VpYSO0nbEiIAk7jR8H8A","lore_tm_v1_iMQrFXGGaMZavPtxooe3Pd5_jIGuGGvkAMF7vMSJzXE","lore_tm_v1_PMECvlSR-oqjLHoVnAHgFGuXFA94xP244gv148y9Fqg","lore_tm_v1_czmimqQWqCYRGu2xCRITUI2lODXXrmwxEwqe2iKG61I","lore_tm_v1_KRejNPKq-7YU074vM0wPlojcIa1v12VSwC08O6nSpvI","lore_tm_v1_htK_NDCsQf3NqWvc_bEunqdCGXKVwAtT4CXW-nCbZ1c","lore_tm_v1_LdVSzZeMLPOspGLNV0k5AkfOzkeYQekUMUaa_Js6Hwk"]
Date: Sep 8, 2026
/usr/bin/script and /usr/bin/grep are regular executable files with mode 755; versions are util-linux script 2.39.3 and GNU grep 3.11 using PCRE2 10.42 (2022-12-11).Error: write EPIPE (errno: -32, code: 'EPIPE', syscall: 'write') and terminated the process./home/byk/.local/share/opencode-v2-pilot/config/opencode/plugins/pty.ts plus the current Promise adapter, tool registry, permission service, built-in shell tool, synthetic-session path, and Node SEA build in /home/byk/Code/opencode-v2-pilot; final verdict was DO-NOT-MERGE./home/byk/.local/share/opencode-v2-pilot/config/opencode/plugins/pty.ts:135 and :394-405 authorize only the displayed command + args, while :146-150 overlays arbitrary caller variables onto the host environment. PATH can replace an allowed executable; SHELL controls util-linux scriptβs interpreter; LD_PRELOAD, LD_LIBRARY_PATH, ENV, and BASH_ENV can execute code before or around the approved command. Evidence: SHELL=/bin/false /usr/bin/script -qefc "'true'" /dev/null exited 1. Recommended fix: use a fixed trusted shell and executable-resolution policy, and do not accept loader or shell-startup variables without separate authorization.options.permission: "shell" at pty.ts:133, :249, and :308 controls only visibility; Core filters wholly denied definitions at /home/byk/Code/opencode-v2-pilot/packages/core/src/tool.ts:220-232 and directly executes the leaf at :249-267. The plugin reimplements matching from static agent rules at pty.ts:394-428, omitting saved project grants added by /home/byk/Code/opencode-v2-pilot/packages/core/src/permission.ts:143-183, permission evaluation hooks (including allow-to-deny changes) at :174-183, canonical tool source identity supplied by /home/byk/Code/opencode-v2-pilot/packages/core/src/tool/plugin/shell.ts:114-140, and approval requests because ask is always rejected at pty.ts:403-405. /home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/permission.ts:18-24 exposes only list, get, reply, and hooksβnot canonical Permission.assert; until that API exists, the plugin cannot truthfully claim V2 shell-permission enforcement.pty.ts:394-400 validates realpath(workdir) but discards the canonical path, while spawn uses the original caller string at pty.ts:142-145. A symlink can point inside the project during authorization and outside it when spawn resolves cwd; the built-in shell instead resolves access and uses the resolved absolute target at /home/byk/Code/opencode-v2-pilot/packages/core/src/tool/plugin/shell.ts:120-149.kill() sends a single SIGTERM at pty.ts:379-385 with no grace deadline, SIGKILL escalation, or wait for group death. An ignoring process can remain alive indefinitely; its state remains killing, but pty.ts:136-140 treats every non-running session as removable; remove() deletes tracking after one signal at :117-125; pty_kill(cleanup: true) reports βStopped and removedβ immediately at :310-320; shutdown forgets processes immediately at :336-339; and detached children/pipes are never unrefed, so an uncooperative group can keep Node alive. Recommended fix: retain ownership until group exit and escalate after a bounded grace period.pty_write performs stdin.write at pty.ts:250-255 without callback, backpressure handling, or an error listener, allowing a status-check/write race to cause unhandled EPIPE. The regex subprocess at pty.ts:431-448 listens to grep errors but not grep.stdin; an invalid expression can make GNU grep exit while the plugin writes the 1 MB buffer. The exact failure was reproduced with GNU grep 3.11 and pattern [, producing an unhandled write EPIPE. Spawn failure is also unsafe: if /usr/bin/script cannot start, pid is undefined and pty.ts:152-155 throws before the child error listener is installed at :179-181.MAX_READ_LIMIT limits only the final slice. Non-pattern reads split the entire buffer and allocate one object per line at pty.ts:269-273; lines() splits all buffered output at :353-357; a 1 MB newline-filled buffer can create roughly one million strings and objects to return only 500 lines. Pattern reads at :431-449 collect all grep output in unbounded arrays before limiting it, and line-number prefixes can make output several times larger than input. pty_write input is unbounded at :42-45, ignored backpressure permits unlimited queued stdin data, and the global 25-process limit neither prevents one session from exhausting the quota nor limits transient allocations from concurrent reads.exit before output streams necessarily close: pty.ts:182-207 computes line count and final line immediately, while stdout/stderr handlers at :173-178 can still receive trailing output. <pty_exited> may therefore contain an incomplete final line and count. Recommended fix: derive final output after close, while separately tracking process state and stream completion.pty.ts:375-377, but permission matching uses an unquoted space join at :397. Different argv arrays can map to the same permission resource, causing argument-sensitive rules to approve or deny the wrong invocation.-- option terminator, 250 ms timeout, and SIGKILL at pty.ts:55-57 and :431-447 are appropriate. However, GNU grep can treat NUL-containing input as binary and emit Binary file (standard input) matches; parsing at pty.ts:449-453 then throws because the line has no colon.pty.ts:136-140, and one Session can occupy all 25 running slots. Recommended alternatives: per-Session limits or owner-aware eviction./usr/bin/script at pty.ts:143 and /usr/bin/grep at :433. /home/byk/Code/opencode-v2-pilot/packages/cli/script/build-node.ts:118-131 shows the Node SEA build embeds the JavaScript bundle and declared assets, not those executables. The current deployment has util-linux script 2.39.3 and GNU grep 3.11, but packaging must explicitly provide them; ordinary non-FHS Nix environments will not work.pty.ts:375-377, preventing ordinary argument text from injecting shell operators.pty.ts:420-428 matches Coreβs /home/byk/Code/opencode-v2-pilot/packages/core/src/util/wildcard.ts:3-13; the defect is omission of canonical permission layers, not wildcard translation.requireSession, which checks parentSessionID at pty.ts:251, :266, :310, and :347-350; listing filters by owner at :296-299.pty.ts:325-334 removes processes owned by a deleted Session, subject to the unresolved process-termination flaw.delivery: "steer" at pty.ts:190-206. Core durably admits synthetic input, defaults to steer, and wakes execution when resume is not false at /home/byk/Code/opencode-v2-pilot/packages/core/src/session/session.ts:282-320; /home/byk/Code/opencode-v2-pilot/packages/core/src/session/runner/to-llm-message.ts:257-258 sends synthetic messages to the model as user-role rather than privileged system messages.pty.ts:10-16 and :35-58; Core validates plugin input before execution at /home/byk/Code/opencode-v2-pilot/packages/core/src/tool/runtime.ts:28-44 and :62-84.