refactor(runtime): move headless permission setup into the agent adapter - #55
Open
FreshlyBrewedCode wants to merge 4 commits into
Open
FreshlyBrewedCode wants to merge 4 commits into
FreshlyBrewedCode wants to merge 4 commits into
Conversation
FreshlyBrewedCode
added this pull request to stack #58
September 20, 2026 13:00
FreshlyBrewedCode
force-pushed
the
37-move-headless-permissions
branch
from
September 20, 2026 13:15
5afc474 to
b64a9be
Compare
This was referenced Sep 22, 2026
FreshlyBrewedCode
added a commit
that referenced
this pull request
Sep 23, 2026
A 0-byte .tanstack-projected-* file under a stray data/src/factory/... path leaked into 2f97451 from a sandboxed run writing through an absolute path that mirrored the checkout. .gitignore already covers .tanstack-projected-* and data/ (added in PR #55), which is why nothing flagged it since; git rm drops it and its now-empty parent dirs. No other stray data/ or .factory/workspaces/ paths are tracked on this branch. Part of #32
ADR 0012 §3: the adapter prepares its own workspace. The opencode adapter writes opencode.json with the never-ask permission policy (#24). Test adapters (corpus replay, slow fake) no-op. Co-Authored-By: opencode-go/qwen3.7-plus <noreply@opencode.ai>
ADR 0012 §3: workspace preparation is the agent runtime's responsibility. Called for clone workspaces only — scratch has no git tree to prepare. Covers both the per-run allocateWorkspace path and the legacy resetClone path, since both reach startRun. Co-Authored-By: opencode-go/qwen3.7-plus <noreply@opencode.ai>
…e allocator (#37) lib/workspace.ts and lib/clone.ts no longer import or call writeHeadlessPermissions. The existsSync guard in allocateWorkspace (needed only for the injected-fake-exec test) is gone along with the responsibility. The opencode adapter now owns workspace preparation via prepareWorkspace (ADR 0012 §3), called by startRun when the caller signals a clone workspace was provisioned. The daemon sets the flag when allocateWorkspace ran; the CLI/HTTP legacy paths set it when resetClone ran. sandbox-config.test.ts now tests opencodeAdapter.prepareWorkspace directly instead of going through resetClone. Co-Authored-By: opencode-go/qwen3.7-plus <noreply@opencode.ai>
…k artifacts (#37) The signalAdapter helper in agent-step.test.ts was missing the new prepareWorkspace method required by the AgentAdapter interface. Also gitignore .tanstack-projected-* and data/ created by sandbox tooling. Co-Authored-By: opencode-go/qwen3.7-plus <noreply@opencode.ai>
FreshlyBrewedCode
force-pushed
the
37-move-headless-permissions
branch
from
September 23, 2026 07:08
b64a9be to
cdf760e
Compare
FreshlyBrewedCode
added a commit
that referenced
this pull request
Sep 23, 2026
A 0-byte .tanstack-projected-* file under a stray data/src/factory/... path leaked into 2f97451 from a sandboxed run writing through an absolute path that mirrored the checkout. .gitignore already covers .tanstack-projected-* and data/ (added in PR #55), which is why nothing flagged it since; git rm drops it and its now-empty parent dirs. No other stray data/ or .factory/workspaces/ paths are tracked on this branch. Part of #32
This branch has not been deployed
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.
Part of #32 · Closes #37
allocateWorkspaceandresetClonewriteopencode.json(permission: {"*": "allow"}) into every run tree — the fix for #24, a real production deadlock where a headless opencode serve parks a turn on a permission ask nobody can answer. That policy is entirely opencode's business; a git-shaped workspace allocator has no way to know it exists and no business knowing it. ADR 0012 §3 draws the line: the agent runtime prepares its own workspace, andlib/workspace.tsgoes back to being about git.What changed
AgentAdaptergainsprepareWorkspace(dir): Promise<void>;opencodeAdapterimplements it by callingwriteHeadlessPermissions(unchanged: still writesopencode.jsonand registers it in.git/info/excludesowriteBacknever stages it). The replay/slow-fake test adapters no-op.startRuncallsadapter.prepareWorkspace(dir)once, beforeworkflow.run, gated by a newprepareWorkspace?: booleanoption — so it runs before the first agent step regardless of which adapter is wired in.lib/workspace.tsandlib/clone.tsno longer importsandbox-config;allocateWorkspace'sexistsSyncguard (only needed becauseworkspace.test.ts's injected fake exec spawns nothing and leavesdirabsent) is gone with the responsibility it was guarding.startTrackedRunitself ranallocateWorkspace(workspaceAllocated && kind === "clone"); the CLI and the legacy HTTPbody.dir+body.clonepath set it explicitly after callingresetClone. Scratch workspaces never set it, matching current behaviour (the pre-refactor code only ever wrote the config past the scratch early-return).sandbox-config.test.tsnow drivesopencodeAdapter.prepareWorkspacedirectly instead of going throughresetClone;workspace.test.ts's now-obsoleteopencode.jsonassertion is removed since that's no longerallocateWorkspace's job;run.test.tsadds coverage for both the true and absentprepareWorkspacecases.Notes for reviewers
prepareWorkspacecontract.fix: add prepareWorkspace to inline test adapters + gitignore tanstack artifacts) has a slightly misleading message — theagent-step.test.tssignalAdapterfix it describes actually landed in the prior commit (a4ccf3b). Its actual diff is just a.gitignoreaddition for.tanstack-projected-*/data/plus deleting one empty file (data/src/factory/.factory/workspaces/run-.../.tanstack-projected-...) that a sandbox run had accidentally committed in the commit before it. Confirmed nothing else rode along — no functional change in that commit.startRunwith a clone workspace (daemon allocation, CLI--clone, legacy HTTPresetClone, and the schedule-trigger path which always goes through daemon allocation since it never setsdir),prepareWorkspacenow runs synchronously beforeworkflow.run, i.e. before any agent step can start. No path was found where a clone workspace reaches the first agent step without it.Verification
sandbox-config.test.ts(adapter-level),run.test.ts(prepareWorkspacetrue/absent), inline adapter fixtures acrossagent-step.test.ts/agent-step.usage.test.ts/replay/adapter.tsupdated for the new interface member.gh pr checks 55):check(format + lint + typecheck +bun test) passes,lint-titlepasses. I did not re-runbun run checklocally; relying on CI's green result.Stack
Stack created with GitHub Stacks CLI • Give Feedback 💬